Merge "Store the existence of home and previous process"
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 754c4e9..8090bec 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -152,8 +152,8 @@
     args: metalava_framework_docs_args,
     check_api: {
         current: {
-            api_file: "non-updatable-api/current.txt",
-            removed_api_file: "non-updatable-api/removed.txt",
+            api_file: "core/api/current.txt",
+            removed_api_file: "core/api/removed.txt",
         },
         last_released: {
             api_file: ":android-non-updatable.api.public.latest",
@@ -212,8 +212,8 @@
     args: metalava_framework_docs_args + priv_apps,
     check_api: {
         current: {
-            api_file: "non-updatable-api/system-current.txt",
-            removed_api_file: "non-updatable-api/system-removed.txt",
+            api_file: "core/api/system-current.txt",
+            removed_api_file: "core/api/system-removed.txt",
         },
         last_released: {
             api_file: ":android-non-updatable.api.system.latest",
@@ -223,7 +223,7 @@
         api_lint: {
             enabled: true,
             new_since: ":android-non-updatable.api.system.latest",
-            baseline_file: "non-updatable-api/system-lint-baseline.txt",
+            baseline_file: "core/api/system-lint-baseline.txt",
         },
     },
 }
@@ -257,46 +257,19 @@
 }
 
 /////////////////////////////////////////////////////////////////////
-// Following droidstubs modules are for extra APIs for modules,
+// Following droidstub module for extra APIs for modules,
 // namely @SystemApi(client=MODULE_LIBRARIES) APIs.
 /////////////////////////////////////////////////////////////////////
 
 droidstubs {
-    name: "module-lib-api",
-    defaults: ["metalava-full-api-stubs-default"],
-    arg_files: ["core/res/AndroidManifest.xml"],
-    args: metalava_framework_docs_args + module_libs,
-
-    // Do not generate stubs as they are not needed
-    generate_stubs: false,
-
-    check_api: {
-        current: {
-            api_file: "api/module-lib-current.txt",
-            removed_api_file: "api/module-lib-removed.txt",
-        },
-        last_released: {
-            api_file: ":android.api.module-lib.latest",
-            removed_api_file: ":removed.api.module-lib.latest",
-            baseline_file: ":module-lib-api-incompatibilities-with-last-released"
-        },
-        api_lint: {
-            enabled: true,
-            new_since: ":android.api.module-lib.latest",
-            baseline_file: "api/module-lib-lint-baseline.txt",
-        },
-    },
-}
-
-droidstubs {
     name: "module-lib-api-stubs-docs-non-updatable",
     defaults: ["metalava-non-updatable-api-stubs-default"],
     arg_files: ["core/res/AndroidManifest.xml"],
     args: metalava_framework_docs_args + priv_apps + module_libs,
     check_api: {
         current: {
-            api_file: "non-updatable-api/module-lib-current.txt",
-            removed_api_file: "non-updatable-api/module-lib-removed.txt",
+            api_file: "core/api/module-lib-current.txt",
+            removed_api_file: "core/api/module-lib-removed.txt",
         },
         last_released: {
             api_file: ":android-non-updatable.api.module-lib.latest",
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/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java
index 5f2fabe..beb9ad3 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java
@@ -27,8 +27,6 @@
  *
  * <p>This class is a higher level implement of {@link GenericDocument}.
  *
- * <p>This class will eventually migrate to Jetpack, where it will become public API.
- *
  * @hide
  */
 
@@ -99,10 +97,9 @@
     }
 
     /**
-     * Get the from address of {@link AppSearchEmail}.
+     * Gets the from address of {@link AppSearchEmail}.
      *
-     * @return Returns the subject of {@link AppSearchEmail} or {@code null} if it's not been set
-     *         yet.
+     * @return The subject of {@link AppSearchEmail} or {@code null} if it's not been set yet.
      */
     @Nullable
     public String getFrom() {
@@ -110,10 +107,10 @@
     }
 
     /**
-     * Get the destination addresses of {@link AppSearchEmail}.
+     * Gets the destination addresses of {@link AppSearchEmail}.
      *
-     * @return Returns the destination addresses of {@link AppSearchEmail} or {@code null} if it's
-     *         not been set yet.
+     * @return The destination addresses of {@link AppSearchEmail} or {@code null} if it's not
+     *         been set yet.
      */
     @Nullable
     public String[] getTo() {
@@ -121,10 +118,9 @@
     }
 
     /**
-     * Get the CC list of {@link AppSearchEmail}.
+     * Gets the CC list of {@link AppSearchEmail}.
      *
-     * @return Returns the CC list of {@link AppSearchEmail} or {@code null} if it's not been set
-     *         yet.
+     * @return The CC list of {@link AppSearchEmail} or {@code null} if it's not been set yet.
      */
     @Nullable
     public String[] getCc() {
@@ -132,10 +128,9 @@
     }
 
     /**
-     * Get the BCC list of {@link AppSearchEmail}.
+     * Gets the BCC list of {@link AppSearchEmail}.
      *
-     * @return Returns the BCC list of {@link AppSearchEmail} or {@code null} if it's not been set
-     *         yet.
+     * @return The BCC list of {@link AppSearchEmail} or {@code null} if it's not been set yet.
      */
     @Nullable
     public String[] getBcc() {
@@ -143,10 +138,9 @@
     }
 
     /**
-     * Get the subject of {@link AppSearchEmail}.
+     * Gets the subject of {@link AppSearchEmail}.
      *
-     * @return Returns the value subject of {@link AppSearchEmail} or {@code null} if it's not been
-     *         set yet.
+     * @return The value subject of {@link AppSearchEmail} or {@code null} if it's not been set yet.
      */
     @Nullable
     public String getSubject() {
@@ -154,9 +148,9 @@
     }
 
     /**
-     * Get the body of {@link AppSearchEmail}.
+     * Gets the body of {@link AppSearchEmail}.
      *
-     * @return Returns the body of {@link AppSearchEmail} or {@code null} if it's not been set yet.
+     * @return The body of {@link AppSearchEmail} or {@code null} if it's not been set yet.
      */
     @Nullable
     public String getBody() {
@@ -169,7 +163,8 @@
     public static class Builder extends GenericDocument.Builder<AppSearchEmail.Builder> {
 
         /**
-         * Create a new {@link AppSearchEmail.Builder}
+         * Creates a new {@link AppSearchEmail.Builder}
+         *
          * @param uri The Uri of the Email.
          */
         public Builder(@NonNull String uri) {
@@ -177,56 +172,56 @@
         }
 
         /**
-         * Set the from address of {@link AppSearchEmail}
+         * Sets the from address of {@link AppSearchEmail}
          */
         @NonNull
         public AppSearchEmail.Builder setFrom(@NonNull String from) {
-            setProperty(KEY_FROM, from);
+            setPropertyString(KEY_FROM, from);
             return this;
         }
 
         /**
-         * Set the destination address of {@link AppSearchEmail}
+         * Sets the destination address of {@link AppSearchEmail}
          */
         @NonNull
         public AppSearchEmail.Builder setTo(@NonNull String... to) {
-            setProperty(KEY_TO, to);
+            setPropertyString(KEY_TO, to);
             return this;
         }
 
         /**
-         * Set the CC list of {@link AppSearchEmail}
+         * Sets the CC list of {@link AppSearchEmail}
          */
         @NonNull
         public AppSearchEmail.Builder setCc(@NonNull String... cc) {
-            setProperty(KEY_CC, cc);
+            setPropertyString(KEY_CC, cc);
             return this;
         }
 
         /**
-         * Set the BCC list of {@link AppSearchEmail}
+         * Sets the BCC list of {@link AppSearchEmail}
          */
         @NonNull
         public AppSearchEmail.Builder setBcc(@NonNull String... bcc) {
-            setProperty(KEY_BCC, bcc);
+            setPropertyString(KEY_BCC, bcc);
             return this;
         }
 
         /**
-         * Set the subject of {@link AppSearchEmail}
+         * Sets the subject of {@link AppSearchEmail}
          */
         @NonNull
         public AppSearchEmail.Builder setSubject(@NonNull String subject) {
-            setProperty(KEY_SUBJECT, subject);
+            setPropertyString(KEY_SUBJECT, subject);
             return this;
         }
 
         /**
-         * Set the body of {@link AppSearchEmail}
+         * Sets the body of {@link AppSearchEmail}
          */
         @NonNull
         public AppSearchEmail.Builder setBody(@NonNull String body) {
-            setProperty(KEY_BODY, body);
+            setPropertyString(KEY_BODY, body);
             return this;
         }
 
diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java
index 90e4df6..3933726 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java
@@ -16,10 +16,12 @@
 
 package android.app.appsearch;
 
+import android.annotation.SuppressLint;
 import android.os.Bundle;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 
 import android.app.appsearch.exceptions.IllegalSchemaException;
 import android.util.ArraySet;
@@ -28,6 +30,8 @@
 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.Set;
 
 /**
@@ -39,13 +43,8 @@
  * @hide
  */
 public final class AppSearchSchema {
-    /** @hide */
-    
-    public static final String SCHEMA_TYPE_FIELD = "schemaType";
-
-    /** @hide */
-    
-    public static final String PROPERTIES_FIELD = "properties";
+    private static final String SCHEMA_TYPE_FIELD = "schemaType";
+    private static final String PROPERTIES_FIELD = "properties";
 
     private final Bundle mBundle;
 
@@ -71,10 +70,35 @@
         return mBundle.toString();
     }
 
+    /** Returns the name of this schema type, e.g. Email. */
+    @NonNull
+    public String getSchemaTypeName() {
+        return mBundle.getString(SCHEMA_TYPE_FIELD, "");
+    }
+
+    /**
+     * Returns the list of {@link PropertyConfig}s that are part of this schema.
+     *
+     * <p>This method creates a new list when called.
+     */
+    @NonNull
+    public List<PropertyConfig> getProperties() {
+        ArrayList<Bundle> propertyBundles =
+                mBundle.getParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD);
+        if (propertyBundles.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<PropertyConfig> ret = new ArrayList<>(propertyBundles.size());
+        for (int i = 0; i < propertyBundles.size(); i++) {
+            ret.add(new PropertyConfig(propertyBundles.get(i)));
+        }
+        return ret;
+    }
+
     /** Builder for {@link AppSearchSchema objects}. */
     public static final class Builder {
         private final String mTypeName;
-        private final ArrayList<Bundle> mProperties = new ArrayList<>();
+        private final ArrayList<Bundle> mPropertyBundles = new ArrayList<>();
         private final Set<String> mPropertyNames = new ArraySet<>();
         private boolean mBuilt = false;
 
@@ -85,15 +109,19 @@
         }
 
         /** Adds a property to the given type. */
+        // TODO(b/171360120): MissingGetterMatchingBuilder expects a method called getPropertys, but
+        //  we provide the (correct) method getProperties. Once the bug referenced in this TODO is
+        //  fixed, remove this SuppressLint.
+        @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkNotNull(propertyConfig);
-            if (!mPropertyNames.add(propertyConfig.mName)) {
-                throw new IllegalSchemaException(
-                        "Property defined more than once: " + propertyConfig.mName);
+            String name = propertyConfig.getName();
+            if (!mPropertyNames.add(name)) {
+                throw new IllegalSchemaException("Property defined more than once: " + name);
             }
-            mProperties.add(propertyConfig.mBundle);
+            mPropertyBundles.add(propertyConfig.mBundle);
             return this;
         }
 
@@ -107,7 +135,7 @@
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Bundle bundle = new Bundle();
             bundle.putString(AppSearchSchema.SCHEMA_TYPE_FIELD, mTypeName);
-            bundle.putParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD, mProperties);
+            bundle.putParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD, mPropertyBundles);
             mBuilt = true;
             return new AppSearchSchema(bundle);
         }
@@ -120,29 +148,12 @@
      * a property.
      */
     public static final class PropertyConfig {
-        /** @hide */
-        
-        public static final String NAME_FIELD = "name";
-
-        /** @hide */
-        
-        public static final String DATA_TYPE_FIELD = "dataType";
-
-        /** @hide */
-        
-        public static final String SCHEMA_TYPE_FIELD = "schemaType";
-
-        /** @hide */
-        
-        public static final String CARDINALITY_FIELD = "cardinality";
-
-        /** @hide */
-        
-        public static final String INDEXING_TYPE_FIELD = "indexingType";
-
-        /** @hide */
-        
-        public static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
+        private static final String NAME_FIELD = "name";
+        private static final String DATA_TYPE_FIELD = "dataType";
+        private static final String SCHEMA_TYPE_FIELD = "schemaType";
+        private static final String CARDINALITY_FIELD = "cardinality";
+        private static final String INDEXING_TYPE_FIELD = "indexingType";
+        private static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
 
         /**
          * Physical data-types of the contents of the property.
@@ -259,11 +270,9 @@
         /** Tokenization for plain text. */
         public static final int TOKENIZER_TYPE_PLAIN = 1;
 
-        final String mName;
         final Bundle mBundle;
 
-        PropertyConfig(@NonNull String name, @NonNull Bundle bundle) {
-            mName = Preconditions.checkNotNull(name);
+        PropertyConfig(@NonNull Bundle bundle) {
             mBundle = Preconditions.checkNotNull(bundle);
         }
 
@@ -272,6 +281,45 @@
             return mBundle.toString();
         }
 
+        /** Returns the name of this property. */
+        @NonNull
+        public String getName() {
+            return mBundle.getString(NAME_FIELD, "");
+        }
+
+        /** Returns the type of data the property contains (e.g. string, int, bytes, etc). */
+        public @DataType int getDataType() {
+            return mBundle.getInt(DATA_TYPE_FIELD, -1);
+        }
+
+        /**
+         * Returns the logical schema-type of the contents of this property.
+         *
+         * <p>Only set when {@link #getDataType} is set to {@link #DATA_TYPE_DOCUMENT}.
+         * Otherwise, it is {@code null}.
+         */
+        @Nullable
+        public String getSchemaType() {
+            return mBundle.getString(SCHEMA_TYPE_FIELD);
+        }
+
+        /**
+         * Returns the cardinality of the property (whether it is optional, required or repeated).
+         */
+        public @Cardinality int getCardinality() {
+            return mBundle.getInt(CARDINALITY_FIELD, -1);
+        }
+
+        /** Returns how the property is indexed. */
+        public @IndexingType int getIndexingType() {
+            return mBundle.getInt(INDEXING_TYPE_FIELD);
+        }
+
+        /** Returns how this property is tokenized (split into words). */
+        public @TokenizerType int getTokenizerType() {
+            return mBundle.getInt(TOKENIZER_TYPE_FIELD);
+        }
+
         /**
          * Builder for {@link PropertyConfig}.
          *
@@ -286,13 +334,11 @@
          * is also required.
          */
         public static final class Builder {
-            private final String mName;
             private final Bundle mBundle = new Bundle();
             private boolean mBuilt = false;
 
             /** Creates a new {@link PropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
-                mName = Preconditions.checkNotNull(propertyName);
                 mBundle.putString(NAME_FIELD, propertyName);
             }
 
@@ -386,7 +432,7 @@
                     throw new IllegalSchemaException("Missing field: cardinality");
                 }
                 mBuilt = true;
-                return new PropertyConfig(mName, mBundle);
+                return new PropertyConfig(mBundle);
             }
         }
     }
diff --git a/apex/appsearch/framework/java/android/app/appsearch/GenericDocument.java b/apex/appsearch/framework/java/android/app/appsearch/GenericDocument.java
index 9fe2c67..48d3ac0 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/GenericDocument.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/GenericDocument.java
@@ -30,6 +30,7 @@
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Set;
 
 /**
@@ -65,20 +66,14 @@
     /** The default time-to-live in millisecond of a document, which is infinity. */
     private static final long DEFAULT_TTL_MILLIS = 0L;
 
-    /** @hide */
-    
-    public static final String PROPERTIES_FIELD = "properties";
-
-    /** @hide */
-    
-    public static final String BYTE_ARRAY_FIELD = "byteArray";
-
-    static final String SCHEMA_TYPE_FIELD = "schemaType";
-    static final String URI_FIELD = "uri";
-    static final String SCORE_FIELD = "score";
-    static final String TTL_MILLIS_FIELD = "ttlMillis";
-    static final String CREATION_TIMESTAMP_MILLIS_FIELD = "creationTimestampMillis";
-    static final String NAMESPACE_FIELD = "namespace";
+    private static final String PROPERTIES_FIELD = "properties";
+    private static final String BYTE_ARRAY_FIELD = "byteArray";
+    private static final String SCHEMA_TYPE_FIELD = "schemaType";
+    private static final String URI_FIELD = "uri";
+    private static final String SCORE_FIELD = "score";
+    private static final String TTL_MILLIS_FIELD = "ttlMillis";
+    private static final String CREATION_TIMESTAMP_MILLIS_FIELD = "creationTimestampMillis";
+    private static final String NAMESPACE_FIELD = "namespace";
 
     /**
      * The maximum number of indexed properties a document can have.
@@ -190,6 +185,12 @@
         return mBundle.getInt(SCORE_FIELD, DEFAULT_SCORE);
     }
 
+    /** Returns the names of all properties defined in this document. */
+    @NonNull
+    public Set<String> getPropertyNames() {
+        return Collections.unmodifiableSet(mProperties.keySet());
+    }
+
     /**
      * Retrieves a {@link String} value by key.
      *
@@ -437,8 +438,6 @@
 
     @Override
     public boolean equals(@Nullable Object other) {
-        // Check only proto's equality is sufficient here since all properties in
-        // mProperties are ordered by keys and stored in proto.
         if (this == other) {
             return true;
         }
@@ -450,8 +449,8 @@
     }
 
     /**
-     * Deeply checks two bundle is equally or not.
-     * <p> Two bundle will be considered equally if they contains same content.
+     * Deeply checks two bundles are equally or not.
+     * <p> Two bundles will be considered equally if they contain same content.
      */
     @SuppressWarnings("unchecked")
     private static boolean bundleEquals(Bundle one, Bundle two) {
@@ -472,7 +471,7 @@
                 return false;
             } else if (valueOne == null && (valueTwo != null || !two.containsKey(key))) {
                 // If we call bundle.get(key) when the 'key' doesn't actually exist in the
-                // bundle, we'll get  back a null. So make sure that both values are null and
+                // bundle, we'll get back a null. So make sure that both values are null and
                 // both keys exist in the bundle.
                 return false;
             } else if (valueOne instanceof boolean[]) {
@@ -538,8 +537,8 @@
 
     /**
      * Calculates the hash code for a bundle.
-     * <p> The hash code is only effected by the content in the bundle. Bundles will get
-     * consistent hash code if they have same content.
+     * <p> The hash code is only effected by the contents in the bundle. Bundles will get
+     * consistent hash code if they have same contents.
      */
     @SuppressWarnings("unchecked")
     private static int bundleHashCode(Bundle bundle) {
@@ -648,8 +647,11 @@
     /**
      * The builder class for {@link GenericDocument}.
      *
-     * @param <BuilderType> Type of subclass who extend this.
+     * @param <BuilderType> Type of subclass who extends this.
      */
+    // This builder is specifically designed to be extended by classes deriving from
+    // GenericDocument.
+    @SuppressLint("StaticFinalBuilder")
     public static class Builder<BuilderType extends Builder> {
 
         private final Bundle mProperties = new Bundle();
@@ -662,12 +664,11 @@
          *
          * @param uri The uri of {@link GenericDocument}.
          * @param schemaType The schema type of the {@link GenericDocument}. The passed-in
-         *        {@code schemaType} must be defined using {@code AppSearchManager#setSchema} prior
+         *        {@code schemaType} must be defined using {@link AppSearchSession#setSchema} prior
          *        to inserting a document of this {@code schemaType} into the AppSearch index using
-         *        {@code AppSearchManager#putDocuments}. Otherwise, the document will be
-         *        rejected by {@code AppSearchManager#putDocuments}.
+         *        {@link AppSearchSession#putDocuments}. Otherwise, the document will be
+         *        rejected by {@link AppSearchSession#putDocuments}.
          */
-        //TODO(b/157082794) Linkify AppSearchManager once that API is public.
         @SuppressWarnings("unchecked")
         public Builder(@NonNull String uri, @NonNull String schemaType) {
             Preconditions.checkNotNull(uri);
@@ -685,9 +686,12 @@
         }
 
         /**
-         * Set the app-defined namespace this Document resides in. No special values  are
-         * reserved or understood by the infrastructure. URIs are unique within a namespace. The
-         * number of namespaces per app should be kept small for efficiency reasons.
+         * Sets the app-defined namespace this Document resides in. No special values are
+         * reserved or understood by the infrastructure.
+         *
+         * <p>URIs are unique within a namespace.
+         *
+         * <p>The number of namespaces per app should be kept small for efficiency reasons.
          */
         @NonNull
         public BuilderType setNamespace(@NonNull String namespace) {
@@ -714,7 +718,7 @@
         }
 
         /**
-         * Set the creation timestamp in milliseconds of the {@link GenericDocument}. Should be
+         * Sets the creation timestamp of the {@link GenericDocument}, in milliseconds. Should be
          * set using a value obtained from the {@link System#currentTimeMillis()} time base.
          */
         @NonNull
@@ -726,7 +730,7 @@
         }
 
         /**
-         * Set the TTL (Time To Live) of the {@link GenericDocument}, in milliseconds.
+         * Sets the TTL (Time To Live) of the {@link GenericDocument}, in milliseconds.
          *
          * <p>After this many milliseconds since the {@link #setCreationTimestampMillis creation
          * timestamp}, the document is deleted.
@@ -752,7 +756,7 @@
          * @param values The {@code String} values of the property.
          */
         @NonNull
-        public BuilderType setProperty(@NonNull String key, @NonNull String... values) {
+        public BuilderType setPropertyString(@NonNull String key, @NonNull String... values) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkNotNull(key);
             Preconditions.checkNotNull(values);
@@ -768,7 +772,7 @@
          * @param values The {@code boolean} values of the property.
          */
         @NonNull
-        public BuilderType setProperty(@NonNull String key, @NonNull boolean... values) {
+        public BuilderType setPropertyBoolean(@NonNull String key, @NonNull boolean... values) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkNotNull(key);
             Preconditions.checkNotNull(values);
@@ -784,7 +788,7 @@
          * @param values The {@code long} values of the property.
          */
         @NonNull
-        public BuilderType setProperty(@NonNull String key, @NonNull long... values) {
+        public BuilderType setPropertyLong(@NonNull String key, @NonNull long... values) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkNotNull(key);
             Preconditions.checkNotNull(values);
@@ -800,7 +804,7 @@
          * @param values The {@code double} values of the property.
          */
         @NonNull
-        public BuilderType setProperty(@NonNull String key, @NonNull double... values) {
+        public BuilderType setPropertyDouble(@NonNull String key, @NonNull double... values) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkNotNull(key);
             Preconditions.checkNotNull(values);
@@ -815,7 +819,7 @@
          * @param values The {@code byte[]} of the property.
          */
         @NonNull
-        public BuilderType setProperty(@NonNull String key, @NonNull byte[]... values) {
+        public BuilderType setPropertyBytes(@NonNull String key, @NonNull byte[]... values) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkNotNull(key);
             Preconditions.checkNotNull(values);
@@ -831,7 +835,8 @@
          * @param values The {@link GenericDocument} values of the property.
          */
         @NonNull
-        public BuilderType setProperty(@NonNull String key, @NonNull GenericDocument... values) {
+        public BuilderType setPropertyDocument(
+                @NonNull String key, @NonNull GenericDocument... values) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkNotNull(key);
             Preconditions.checkNotNull(values);
diff --git a/apex/appsearch/framework/java/android/app/appsearch/GetByUriRequest.java b/apex/appsearch/framework/java/android/app/appsearch/GetByUriRequest.java
index 3c0e746..e1e0eda 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/GetByUriRequest.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/GetByUriRequest.java
@@ -17,12 +17,12 @@
 package android.app.appsearch;
 
 import android.annotation.NonNull;
-
 import android.util.ArraySet;
 import com.android.internal.util.Preconditions;
 
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Set;
 
 /**
@@ -40,18 +40,16 @@
         mUris = uris;
     }
 
-    /** @hide */
-    
+    /** Returns the namespace to get documents from. */
     @NonNull
     public String getNamespace() {
         return mNamespace;
     }
 
-    /** @hide */
-    
+    /** Returns the URIs to get from the namespace. */
     @NonNull
     public Set<String> getUris() {
-        return mUris;
+        return Collections.unmodifiableSet(mUris);
     }
 
     /** Builder for {@link GetByUriRequest} objects. */
@@ -75,14 +73,14 @@
 
         /** Adds one or more URIs to the request. */
         @NonNull
-        public Builder addUris(@NonNull String... uris) {
+        public Builder addUri(@NonNull String... uris) {
             Preconditions.checkNotNull(uris);
-            return addUris(Arrays.asList(uris));
+            return addUri(Arrays.asList(uris));
         }
 
         /** Adds one or more URIs to the request. */
         @NonNull
-        public Builder addUris(@NonNull Collection<String> uris) {
+        public Builder addUri(@NonNull Collection<String> uris) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkNotNull(uris);
             mUris.addAll(uris);
diff --git a/apex/appsearch/framework/java/android/app/appsearch/PutDocumentsRequest.java b/apex/appsearch/framework/java/android/app/appsearch/PutDocumentsRequest.java
index 7e97542..1f90bc1 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/PutDocumentsRequest.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/PutDocumentsRequest.java
@@ -16,13 +16,16 @@
 
 package android.app.appsearch;
 
-import android.annotation.NonNull;
+import android.annotation.SuppressLint;
 
+import android.annotation.NonNull;
+import android.app.appsearch.exceptions.AppSearchException;
 import com.android.internal.util.Preconditions;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -38,11 +41,10 @@
         mDocuments = documents;
     }
 
-    /** @hide */
-    
+    /** Returns the documents that are part of this request. */
     @NonNull
     public List<GenericDocument> getDocuments() {
-        return mDocuments;
+        return Collections.unmodifiableList(mDocuments);
     }
 
     /** Builder for {@link PutDocumentsRequest} objects. */
@@ -51,6 +53,7 @@
         private boolean mBuilt = false;
 
         /** Adds one or more documents to the request. */
+        @SuppressLint("MissingGetterMatchingBuilder")  // Merged list available from getDocuments()
         @NonNull
         public Builder addGenericDocument(@NonNull GenericDocument... documents) {
             Preconditions.checkNotNull(documents);
@@ -58,6 +61,7 @@
         }
 
         /** Adds one or more documents to the request. */
+        @SuppressLint("MissingGetterMatchingBuilder")  // Merged list available from getDocuments()
         @NonNull
         public Builder addGenericDocument(@NonNull Collection<GenericDocument> documents) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
diff --git a/apex/appsearch/framework/java/android/app/appsearch/RemoveByUriRequest.java b/apex/appsearch/framework/java/android/app/appsearch/RemoveByUriRequest.java
index a047041..486857f 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/RemoveByUriRequest.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/RemoveByUriRequest.java
@@ -17,12 +17,12 @@
 package android.app.appsearch;
 
 import android.annotation.NonNull;
-
 import android.util.ArraySet;
 import com.android.internal.util.Preconditions;
 
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Set;
 
 /**
@@ -40,18 +40,16 @@
         mUris = uris;
     }
 
-    /** @hide */
-    
+    /** Returns the namespace to remove documents from. */
     @NonNull
     public String getNamespace() {
         return mNamespace;
     }
 
-    /** @hide */
-    
+    /** Returns the URIs to remove from the namespace. */
     @NonNull
     public Set<String> getUris() {
-        return mUris;
+        return Collections.unmodifiableSet(mUris);
     }
 
     /** Builder for {@link RemoveByUriRequest} objects. */
@@ -75,14 +73,14 @@
 
         /** Adds one or more URIs to the request. */
         @NonNull
-        public Builder addUris(@NonNull String... uris) {
+        public Builder addUri(@NonNull String... uris) {
             Preconditions.checkNotNull(uris);
-            return addUris(Arrays.asList(uris));
+            return addUri(Arrays.asList(uris));
         }
 
         /** Adds one or more URIs to the request. */
         @NonNull
-        public Builder addUris(@NonNull Collection<String> uris) {
+        public Builder addUri(@NonNull Collection<String> uris) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkNotNull(uris);
             mUris.addAll(uris);
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResult.java b/apex/appsearch/framework/java/android/app/appsearch/SearchResult.java
index 758280b..99cb2f1 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/SearchResult.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/SearchResult.java
@@ -49,19 +49,22 @@
     @NonNull
     private final Bundle mDocumentBundle;
 
+    /** Cache of the inflated document. Comes from inflating mDocumentBundle at first use. */
     @Nullable
     private GenericDocument mDocument;
 
-    @Nullable
-    private final List<Bundle> mMatchBundles;
-
     /**
-     * Contains a list of Snippets that matched the request. Only populated when requested in
-     * both {@link SearchSpec.Builder#setSnippetCount(int)}
-     * and {@link SearchSpec.Builder#setSnippetCountPerProperty(int)}.
+     * Contains a list of MatchInfo bundles that matched the request.
+     *
+     * Only populated when requested in both {@link SearchSpec.Builder#setSnippetCount} and
+     * {@link SearchSpec.Builder#setSnippetCountPerProperty}.
      *
      * @see #getMatches()
      */
+    @NonNull
+    private final List<Bundle> mMatchBundles;
+
+    /** Cache of the inflated matches. Comes from inflating mMatchBundles at first use. */
     @Nullable
     private List<MatchInfo> mMatches;
 
@@ -70,7 +73,7 @@
     public SearchResult(@NonNull Bundle bundle) {
         mBundle = Preconditions.checkNotNull(bundle);
         mDocumentBundle = Preconditions.checkNotNull(bundle.getBundle(DOCUMENT_FIELD));
-        mMatchBundles = bundle.getParcelableArrayList(MATCHES_FIELD);
+        mMatchBundles = Preconditions.checkNotNull(bundle.getParcelableArrayList(MATCHES_FIELD));
     }
 
     /** @hide */
@@ -93,19 +96,16 @@
     }
 
     /**
-     * Contains a list of Snippets that matched the request. Only populated when requested in
-     * both {@link SearchSpec.Builder#setSnippetCount(int)}
-     * and {@link SearchSpec.Builder#setSnippetCountPerProperty(int)}.
+     * Contains a list of Snippets that matched the request.
      *
-     * @return  List of matches based on {@link SearchSpec}, if snippeting is disabled and this
-     * method is called it will return {@code null}. Users can also restrict snippet population
-     * using {@link SearchSpec.Builder#setSnippetCount} and
-     * {@link SearchSpec.Builder#setSnippetCountPerProperty(int)}, for all results after that
-     * value this method will return {@code null}.
+     * @return List of matches based on {@link SearchSpec}. If snippeting is disabled using
+     * {@link SearchSpec.Builder#setSnippetCount} or
+     * {@link SearchSpec.Builder#setSnippetCountPerProperty}, for all results after that
+     * value, this method returns an empty list.
      */
-    @Nullable
+    @NonNull
     public List<MatchInfo> getMatches() {
-        if (mMatchBundles != null && mMatches == null) {
+        if (mMatches == null) {
             mMatches = new ArrayList<>(mMatchBundles.size());
             for (int i = 0; i < mMatchBundles.size(); i++) {
                 MatchInfo matchInfo = new MatchInfo(getDocument(), mMatchBundles.get(i));
@@ -119,8 +119,8 @@
      * Snippet: It refers to a substring of text from the content of document that is returned as a
      * part of search result.
      * This class represents a match objects for any Snippets that might be present in
-     * {@link SearchResults} from query. Using this class user can get the full text, exact matches
-     * and Snippets of document content for a given match.
+     * {@link SearchResults} from query. Using this class
+     * user can get the full text, exact matches and Snippets of document content for a given match.
      *
      * <p>Class Example 1:
      * A document contains following text in property subject:
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java b/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java
index c871905..15acf10 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java
@@ -16,16 +16,23 @@
 
 package android.app.appsearch;
 
+import android.annotation.SuppressLint;
 import android.os.Bundle;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 
+import android.app.appsearch.exceptions.AppSearchException;
 import android.app.appsearch.exceptions.IllegalSearchSpecException;
 import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * This class represents the specification logic for AppSearch. It can be used to set the type of
@@ -34,69 +41,26 @@
  */
 // TODO(sidchhabra) : AddResultSpec fields for Snippets etc.
 public final class SearchSpec {
-    /** @hide */
-    
-    public static final String TERM_MATCH_TYPE_FIELD = "termMatchType";
-
-    /** @hide */
-    
-    public static final String SCHEMA_TYPES_FIELD = "schemaType";
-
-    /** @hide */
-    
-    public static final String NAMESPACE_FIELD = "namespace";
-
-    /** @hide */
-    
-    public static final String NUM_PER_PAGE_FIELD = "numPerPage";
-
-    /** @hide */
-    
-    public static final String RANKING_STRATEGY_FIELD = "rankingStrategy";
-
-    /** @hide */
-    
-    public static final String ORDER_FIELD = "order";
-
-    /** @hide */
-    
-    public static final String SNIPPET_COUNT_FIELD = "snippetCount";
-
-    /** @hide */
-    
-    public static final String SNIPPET_COUNT_PER_PROPERTY_FIELD = "snippetCountPerProperty";
-
-    /** @hide */
-    
-    public static final String MAX_SNIPPET_FIELD = "maxSnippet";
+    static final String TERM_MATCH_TYPE_FIELD = "termMatchType";
+    static final String SCHEMA_TYPE_FIELD = "schemaType";
+    static final String NAMESPACE_FIELD = "namespace";
+    static final String NUM_PER_PAGE_FIELD = "numPerPage";
+    static final String RANKING_STRATEGY_FIELD = "rankingStrategy";
+    static final String ORDER_FIELD = "order";
+    static final String SNIPPET_COUNT_FIELD = "snippetCount";
+    static final String SNIPPET_COUNT_PER_PROPERTY_FIELD = "snippetCountPerProperty";
+    static final String MAX_SNIPPET_FIELD = "maxSnippet";
 
     /** @hide */
     
     public static final int DEFAULT_NUM_PER_PAGE = 10;
 
+    // TODO(b/170371356): In framework, we may want these limits might be flag controlled.
     private static final int MAX_NUM_PER_PAGE = 10_000;
     private static final int MAX_SNIPPET_COUNT = 10_000;
     private static final int MAX_SNIPPET_PER_PROPERTY_COUNT = 10_000;
     private static final int MAX_SNIPPET_SIZE_LIMIT = 10_000;
 
-    private final Bundle mBundle;
-
-    /** @hide */
-    
-    public SearchSpec(@NonNull Bundle bundle) {
-        Preconditions.checkNotNull(bundle);
-        mBundle = bundle;
-    }
-
-    /**
-     * Returns the {@link Bundle} populated by this builder.
-     * @hide
-     */
-    @NonNull
-    public Bundle getBundle() {
-        return mBundle;
-    }
-
     /**
      * Term Match Type for the query.
      * @hide
@@ -108,7 +72,7 @@
             TERM_MATCH_PREFIX
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface TermMatchCode {}
+    public @interface TermMatch {}
 
     /**
      * Query terms will only match exact tokens in the index.
@@ -126,14 +90,14 @@
      * @hide
      */
     // NOTE: The integer values of these constants must match the proto enum constants in
-    // {@link ScoringSpecProto.RankingStrategy.Code }
+    // {@link ScoringSpecProto.RankingStrategy.Code}
     @IntDef(value = {
             RANKING_STRATEGY_NONE,
             RANKING_STRATEGY_DOCUMENT_SCORE,
             RANKING_STRATEGY_CREATION_TIMESTAMP
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface RankingStrategyCode {}
+    public @interface RankingStrategy {}
 
     /** No Ranking, results are returned in arbitrary order.*/
     public static final int RANKING_STRATEGY_NONE = 0;
@@ -147,23 +111,109 @@
      * @hide
      */
     // NOTE: The integer values of these constants must match the proto enum constants in
-    // {@link ScoringSpecProto.Order.Code }
+    // {@link ScoringSpecProto.Order.Code}
     @IntDef(value = {
             ORDER_DESCENDING,
             ORDER_ASCENDING
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface OrderCode {}
+    public @interface Order {}
 
     /** Search results will be returned in a descending order. */
     public static final int ORDER_DESCENDING = 0;
     /** Search results will be returned in an ascending order. */
     public static final int ORDER_ASCENDING = 1;
 
+    private final Bundle mBundle;
+
+    /** @hide */
+    
+    public SearchSpec(@NonNull Bundle bundle) {
+        Preconditions.checkNotNull(bundle);
+        mBundle = bundle;
+    }
+
+    /**
+     * Returns the {@link Bundle} populated by this builder.
+     * @hide
+     */
+    
+    @NonNull
+    public Bundle getBundle() {
+        return mBundle;
+    }
+
+    /** Returns how the query terms should match terms in the index. */
+    public @TermMatch int getTermMatch() {
+        return mBundle.getInt(TERM_MATCH_TYPE_FIELD, -1);
+    }
+
+    /**
+     * Returns the list of schema types to search for.
+     *
+     * <p>If empty, the query will search over all schema types.
+     */
+    @NonNull
+    public List<String> getSchemas() {
+        List<String> schemas = mBundle.getStringArrayList(SCHEMA_TYPE_FIELD);
+        if (schemas == null) {
+            return Collections.emptyList();
+        }
+        return Collections.unmodifiableList(schemas);
+    }
+
+    /**
+     * Returns the list of namespaces to search for.
+     *
+     * <p>If empty, the query will search over all namespaces.
+     */
+    @NonNull
+    public List<String> getNamespaces() {
+        List<String> namespaces = mBundle.getStringArrayList(NAMESPACE_FIELD);
+        if (namespaces == null) {
+            return Collections.emptyList();
+        }
+        return Collections.unmodifiableList(namespaces);
+    }
+
+    /** Returns the number of results per page in the returned object. */
+    public int getNumPerPage() {
+        return mBundle.getInt(NUM_PER_PAGE_FIELD, DEFAULT_NUM_PER_PAGE);
+    }
+
+    /** Returns the ranking strategy. */
+    public @RankingStrategy int getRankingStrategy() {
+        return mBundle.getInt(RANKING_STRATEGY_FIELD);
+    }
+
+    /** Returns the order of returned search results (descending or ascending). */
+    public @Order int getOrder() {
+        return mBundle.getInt(ORDER_FIELD);
+    }
+
+    /** Returns how many documents to generate snippets for. */
+    public int getSnippetCount() {
+        return mBundle.getInt(SNIPPET_COUNT_FIELD);
+    }
+
+    /**
+     * Returns how many matches for each property of a matching document to generate snippets for.
+     */
+    public int getSnippetCountPerProperty() {
+        return mBundle.getInt(SNIPPET_COUNT_PER_PROPERTY_FIELD);
+    }
+
+    /** Returns the maximum size of a snippet in characters. */
+    public int getMaxSnippetSize() {
+        return mBundle.getInt(MAX_SNIPPET_FIELD);
+    }
+
     /** Builder for {@link SearchSpec objects}. */
     public static final class Builder {
 
         private final Bundle mBundle;
+        private final ArrayList<String> mSchemaTypes = new ArrayList<>();
+        private final ArrayList<String> mNamespaces = new ArrayList<>();
         private boolean mBuilt = false;
 
         /** Creates a new {@link SearchSpec.Builder}. */
@@ -176,7 +226,7 @@
          * Indicates how the query terms should match {@code TermMatchCode} in the index.
          */
         @NonNull
-        public Builder setTermMatch(@TermMatchCode int termMatchTypeCode) {
+        public Builder setTermMatch(@TermMatch int termMatchTypeCode) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkArgumentInRange(termMatchTypeCode, TERM_MATCH_EXACT_ONLY,
                     TERM_MATCH_PREFIX, "Term match type");
@@ -187,13 +237,27 @@
         /**
          * Adds a Schema type filter to {@link SearchSpec} Entry. Only search for documents that
          * have the specified schema types.
+         *
          * <p>If unset, the query will search over all schema types.
          */
         @NonNull
-        public Builder setSchemaTypes(@NonNull String... schemaTypes) {
+        public Builder addSchema(@NonNull String... schemaTypes) {
             Preconditions.checkNotNull(schemaTypes);
             Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putStringArray(SCHEMA_TYPES_FIELD, schemaTypes);
+            return addSchema(Arrays.asList(schemaTypes));
+        }
+
+        /**
+         * Adds a Schema type filter to {@link SearchSpec} Entry. Only search for documents that
+         * have the specified schema types.
+         *
+         * <p>If unset, the query will search over all schema types.
+         */
+        @NonNull
+        public Builder addSchema(@NonNull Collection<String> schemaTypes) {
+            Preconditions.checkNotNull(schemaTypes);
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mSchemaTypes.addAll(schemaTypes);
             return this;
         }
 
@@ -203,10 +267,22 @@
          * <p>If unset, the query will search over all namespaces.
          */
         @NonNull
-        public Builder setNamespaces(@NonNull String... namespaces) {
+        public Builder addNamespace(@NonNull String... namespaces) {
             Preconditions.checkNotNull(namespaces);
             Preconditions.checkState(!mBuilt, "Builder has already been used");
-            mBundle.putStringArray(NAMESPACE_FIELD, namespaces);
+            return addNamespace(Arrays.asList(namespaces));
+        }
+
+        /**
+         * Adds a namespace filter to {@link SearchSpec} Entry. Only search for documents that
+         * have the specified namespaces.
+         * <p>If unset, the query will search over all namespaces.
+         */
+        @NonNull
+        public Builder addNamespace(@NonNull Collection<String> namespaces) {
+            Preconditions.checkNotNull(namespaces);
+            Preconditions.checkState(!mBuilt, "Builder has already been used");
+            mNamespaces.addAll(namespaces);
             return this;
         }
 
@@ -224,7 +300,7 @@
 
         /** Sets ranking strategy for AppSearch results.*/
         @NonNull
-        public Builder setRankingStrategy(@RankingStrategyCode int rankingStrategy) {
+        public Builder setRankingStrategy(@RankingStrategy int rankingStrategy) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkArgumentInRange(rankingStrategy, RANKING_STRATEGY_NONE,
                     RANKING_STRATEGY_CREATION_TIMESTAMP, "Result ranking strategy");
@@ -238,7 +314,7 @@
          * <p>This order field will be ignored if RankingStrategy = {@code RANKING_STRATEGY_NONE}.
          */
         @NonNull
-        public Builder setOrder(@OrderCode int order) {
+        public Builder setOrder(@Order int order) {
             Preconditions.checkState(!mBuilt, "Builder has already been used");
             Preconditions.checkArgumentInRange(order, ORDER_DESCENDING, ORDER_ASCENDING,
                     "Result ranking order");
@@ -264,11 +340,12 @@
         }
 
         /**
-         * Only the first {@code matchesCountPerProperty} matches for a every property of
-         * {@link GenericDocument} will contain snippet information.
+         * Sets {@code snippetCountPerProperty}. Only the first {@code snippetCountPerProperty}
+         * snippets for a every property of {@link GenericDocument} will contain snippet
+         * information.
          *
-         * <p>If set to 0, snippeting is disabled and {@link SearchResult#getMatches} will return
-         * {@code null} for that result.
+         * <p>If set to 0, snippeting is disabled and {@link SearchResult#getMatches}
+         * will return {@code null} for that result.
          *
          * <p>The value should be set in range[0, 10k].
          */
@@ -286,10 +363,13 @@
          * {@code maxSnippetSize/2} bytes before the middle of the matching token and end at
          * {@code maxSnippetSize/2} bytes after the middle of the matching token. It respects
          * token boundaries, therefore the returned window may be smaller than requested.
+         *
          * <p> Setting {@code maxSnippetSize} to 0 will disable windowing and an empty string will
          * be returned. If matches enabled is also set to false, then snippeting is disabled.
+         *
          * <p>Ex. {@code maxSnippetSize} = 16. "foo bar baz bat rat" with a query of "baz" will
          * return a window of "bar baz bat" which is only 11 bytes long.
+         *
          * <p>The value should be in range[0, 10k].
          */
         @NonNull
@@ -312,6 +392,8 @@
             if (!mBundle.containsKey(TERM_MATCH_TYPE_FIELD)) {
                 throw new IllegalSearchSpecException("Missing termMatchType field.");
             }
+            mBundle.putStringArrayList(NAMESPACE_FIELD, mNamespaces);
+            mBundle.putStringArrayList(SCHEMA_TYPE_FIELD, mSchemaTypes);
             mBuilt = true;
             return new SearchSpec(mBundle);
         }
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SetSchemaRequest.java b/apex/appsearch/framework/java/android/app/appsearch/SetSchemaRequest.java
index b2e9d46..f2c8156 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/SetSchemaRequest.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/SetSchemaRequest.java
@@ -16,13 +16,17 @@
 
 package android.app.appsearch;
 
-import android.annotation.NonNull;
-import android.util.ArraySet;
+import android.annotation.SuppressLint;
 
+import android.annotation.NonNull;
+import android.app.appsearch.exceptions.AppSearchException;
+import android.util.ArraySet;
 import com.android.internal.util.Preconditions;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -40,15 +44,13 @@
         mForceOverride = forceOverride;
     }
 
-    /** @hide */
-    
+    /** Returns the schemas that are part of this request. */
     @NonNull
     public Set<AppSearchSchema> getSchemas() {
         return mSchemas;
     }
 
-    /** @hide */
-    
+    /** Returns whether this request will force the schema to be overridden. */
     public boolean isForceOverride() {
         return mForceOverride;
     }
diff --git a/apex/appsearch/framework/java/android/app/appsearch/exceptions/AppSearchException.java b/apex/appsearch/framework/java/android/app/appsearch/exceptions/AppSearchException.java
index d490469..15d0992 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/exceptions/AppSearchException.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/exceptions/AppSearchException.java
@@ -54,6 +54,7 @@
         mResultCode = resultCode;
     }
 
+    /** Returns the result code this exception was constructed with. */
     public @AppSearchResult.ResultCode int getResultCode() {
         return mResultCode;
     }
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
index 7cd6ee2..f2830e5 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java
@@ -33,11 +33,11 @@
 import com.android.internal.infra.AndroidFuture;
 import com.android.internal.util.Preconditions;
 import com.android.server.SystemService;
-import com.android.server.appsearch.external.localbackend.AppSearchImpl;
-import com.android.server.appsearch.external.localbackend.converter.GenericDocumentToProtoConverter;
-import com.android.server.appsearch.external.localbackend.converter.SchemaToProtoConverter;
-import com.android.server.appsearch.external.localbackend.converter.SearchResultToProtoConverter;
-import com.android.server.appsearch.external.localbackend.converter.SearchSpecToProtoConverter;
+import com.android.server.appsearch.external.localstorage.AppSearchImpl;
+import com.android.server.appsearch.external.localstorage.converter.GenericDocumentToProtoConverter;
+import com.android.server.appsearch.external.localstorage.converter.SchemaToProtoConverter;
+import com.android.server.appsearch.external.localstorage.converter.SearchResultToProtoConverter;
+import com.android.server.appsearch.external.localstorage.converter.SearchSpecToProtoConverter;
 
 import com.google.android.icing.proto.DocumentProto;
 import com.google.android.icing.proto.SchemaProto;
@@ -46,6 +46,7 @@
 import com.google.android.icing.proto.SearchSpecProto;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -193,7 +194,12 @@
                         SearchSpecToProtoConverter.toResultSpecProto(searchSpec),
                         SearchSpecToProtoConverter.toScoringSpecProto(searchSpec));
                 List<SearchResult> searchResultList =
-                        SearchResultToProtoConverter.convert(searchResultProto);
+                        new ArrayList<>(searchResultProto.getResultsCount());
+                for (int i = 0; i < searchResultProto.getResultsCount(); i++) {
+                    SearchResult result = SearchResultToProtoConverter.convertSearchResult(
+                            searchResultProto.getResults(i));
+                    searchResultList.add(result);
+                }
                 SearchResults searchResults =
                         new SearchResults(searchResultList, searchResultProto.getNextPageToken());
                 callback.complete(AppSearchResult.newSuccessfulResult(searchResults));
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
index 60f7005..2871eb6 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/ImplInstanceManager.java
@@ -24,7 +24,7 @@
 import android.os.storage.StorageManager;
 import android.util.SparseArray;
 
-import com.android.server.appsearch.external.localbackend.AppSearchImpl;
+import com.android.server.appsearch.external.localstorage.AppSearchImpl;
 
 import java.io.File;
 
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
similarity index 99%
rename from apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/AppSearchImpl.java
rename to apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
index 642378d..b1a79f8 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/AppSearchImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.appsearch.external.localbackend;
+package com.android.server.appsearch.external.localstorage;
 
 import android.util.Log;
 
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
similarity index 69%
rename from apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverter.java
rename to apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
index fdeb90d..60684f0 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverter.java
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.appsearch.external.localbackend.converter;
-
-import android.os.Bundle;
+package com.android.server.appsearch.external.localstorage.converter;
 
 import android.annotation.NonNull;
 
@@ -43,7 +41,6 @@
     @SuppressWarnings("unchecked")
     public static DocumentProto convert(@NonNull GenericDocument document) {
         Preconditions.checkNotNull(document);
-        Bundle properties = document.getBundle().getBundle(GenericDocument.PROPERTIES_FIELD);
         DocumentProto.Builder mProtoBuilder = DocumentProto.newBuilder();
         mProtoBuilder.setUri(document.getUri())
                 .setSchema(document.getSchemaType())
@@ -51,42 +48,45 @@
                 .setScore(document.getScore())
                 .setTtlMs(document.getTtlMillis())
                 .setCreationTimestampMs(document.getCreationTimestampMillis());
-        ArrayList<String> keys = new ArrayList<>(properties.keySet());
+        ArrayList<String> keys = new ArrayList<>(document.getPropertyNames());
         Collections.sort(keys);
         for (int i = 0; i < keys.size(); i++) {
             String name = keys.get(i);
-            Object values = properties.get(name);
             PropertyProto.Builder propertyProto = PropertyProto.newBuilder().setName(name);
-            if (values instanceof boolean[]) {
-                for (boolean value : (boolean[]) values) {
-                    propertyProto.addBooleanValues(value);
+            String[] stringValues = document.getPropertyStringArray(name);
+            long[] longValues = document.getPropertyLongArray(name);
+            double[] doubleValues = document.getPropertyDoubleArray(name);
+            boolean[] booleanValues = document.getPropertyBooleanArray(name);
+            byte[][] bytesValues = document.getPropertyBytesArray(name);
+            GenericDocument[] documentValues = document.getPropertyDocumentArray(name);
+            if (stringValues != null) {
+                for (int j = 0; j < stringValues.length; j++) {
+                    propertyProto.addStringValues(stringValues[j]);
                 }
-            } else if (values instanceof long[]) {
-                for (long value : (long[]) values) {
-                    propertyProto.addInt64Values(value);
+            } else if (longValues != null) {
+                for (int j = 0; j < longValues.length; j++) {
+                    propertyProto.addInt64Values(longValues[j]);
                 }
-            } else if (values instanceof double[]) {
-                for (double value : (double[]) values) {
-                    propertyProto.addDoubleValues(value);
+            } else if (doubleValues != null) {
+                for (int j = 0; j < doubleValues.length; j++) {
+                    propertyProto.addDoubleValues(doubleValues[j]);
                 }
-            } else if (values instanceof String[]) {
-                for (String value : (String[]) values) {
-                    propertyProto.addStringValues(value);
+            } else if (booleanValues != null) {
+                for (int j = 0; j < booleanValues.length; j++) {
+                    propertyProto.addBooleanValues(booleanValues[j]);
                 }
-            } else if (values instanceof ArrayList) {
-                for (Bundle bundle : (ArrayList<Bundle>) values) {
-                    byte[] value = bundle.getByteArray(GenericDocument.BYTE_ARRAY_FIELD);
-                    propertyProto.addBytesValues(ByteString.copyFrom(value));
+            } else if (bytesValues != null) {
+                for (int j = 0; j < bytesValues.length; j++) {
+                    propertyProto.addBytesValues(ByteString.copyFrom(bytesValues[j]));
                 }
-            } else if (values instanceof Bundle[]) {
-                for (Bundle bundle : (Bundle[]) values) {
-                    GenericDocument value = new GenericDocument(bundle);
-                    propertyProto.addDocumentValues(convert(value));
+            } else if (documentValues != null) {
+                for (int j = 0; j < documentValues.length; j++) {
+                    DocumentProto proto = convert(documentValues[j]);
+                    propertyProto.addDocumentValues(proto);
                 }
             } else {
                 throw new IllegalStateException(
-                        "Property \"" + name + "\" has unsupported value type \""
-                                + values.getClass().getSimpleName() + "\"");
+                        "Property \"" + name + "\" has unsupported value type");
             }
             mProtoBuilder.addProperties(propertyProto);
         }
@@ -107,42 +107,42 @@
         for (int i = 0; i < proto.getPropertiesCount(); i++) {
             PropertyProto property = proto.getProperties(i);
             String name = property.getName();
-            if (property.getBooleanValuesCount() > 0) {
-                boolean[] values = new boolean[property.getBooleanValuesCount()];
+            if (property.getStringValuesCount() > 0) {
+                String[] values = new String[property.getStringValuesCount()];
                 for (int j = 0; j < values.length; j++) {
-                    values[j] = property.getBooleanValues(j);
+                    values[j] = property.getStringValues(j);
                 }
-                documentBuilder.setProperty(name, values);
+                documentBuilder.setPropertyString(name, values);
             } else if (property.getInt64ValuesCount() > 0) {
                 long[] values = new long[property.getInt64ValuesCount()];
                 for (int j = 0; j < values.length; j++) {
                     values[j] = property.getInt64Values(j);
                 }
-                documentBuilder.setProperty(name, values);
+                documentBuilder.setPropertyLong(name, values);
             } else if (property.getDoubleValuesCount() > 0) {
                 double[] values = new double[property.getDoubleValuesCount()];
                 for (int j = 0; j < values.length; j++) {
                     values[j] = property.getDoubleValues(j);
                 }
-                documentBuilder.setProperty(name, values);
-            } else if (property.getStringValuesCount() > 0) {
-                String[] values = new String[property.getStringValuesCount()];
+                documentBuilder.setPropertyDouble(name, values);
+            } else if (property.getBooleanValuesCount() > 0) {
+                boolean[] values = new boolean[property.getBooleanValuesCount()];
                 for (int j = 0; j < values.length; j++) {
-                    values[j] = property.getStringValues(j);
+                    values[j] = property.getBooleanValues(j);
                 }
-                documentBuilder.setProperty(name, values);
+                documentBuilder.setPropertyBoolean(name, values);
             } else if (property.getBytesValuesCount() > 0) {
                 byte[][] values = new byte[property.getBytesValuesCount()][];
                 for (int j = 0; j < values.length; j++) {
                     values[j] = property.getBytesValues(j).toByteArray();
                 }
-                documentBuilder.setProperty(name, values);
+                documentBuilder.setPropertyBytes(name, values);
             } else if (property.getDocumentValuesCount() > 0) {
                 GenericDocument[] values = new GenericDocument[property.getDocumentValuesCount()];
                 for (int j = 0; j < values.length; j++) {
                     values[j] = convert(property.getDocumentValues(j));
                 }
-                documentBuilder.setProperty(name, values);
+                documentBuilder.setPropertyDocument(name, values);
             } else {
                 throw new IllegalStateException("Unknown type of value: " + name);
             }
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
similarity index 73%
rename from apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverter.java
rename to apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
index ca0d2ee..403711f 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverter.java
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.appsearch.external.localbackend.converter;
-
-import android.os.Bundle;
+package com.android.server.appsearch.external.localstorage.converter;
 
 import android.annotation.NonNull;
 
@@ -28,7 +26,7 @@
 import com.google.android.icing.proto.SchemaTypeConfigProto;
 import com.google.android.icing.proto.TermMatchType;
 
-import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Translates an {@link AppSearchSchema} into a {@link SchemaTypeConfigProto}.
@@ -45,31 +43,26 @@
     @NonNull
     public static SchemaTypeConfigProto convert(@NonNull AppSearchSchema schema) {
         Preconditions.checkNotNull(schema);
-        Bundle bundle = schema.getBundle();
         SchemaTypeConfigProto.Builder protoBuilder =
-                SchemaTypeConfigProto.newBuilder()
-                        .setSchemaType(bundle.getString(AppSearchSchema.SCHEMA_TYPE_FIELD, ""));
-        ArrayList<Bundle> properties =
-                bundle.getParcelableArrayList(AppSearchSchema.PROPERTIES_FIELD);
-        if (properties != null) {
-            for (int i = 0; i < properties.size(); i++) {
-                PropertyConfigProto propertyProto = convertProperty(properties.get(i));
-                protoBuilder.addProperties(propertyProto);
-            }
+                SchemaTypeConfigProto.newBuilder().setSchemaType(schema.getSchemaTypeName());
+        List<AppSearchSchema.PropertyConfig> properties = schema.getProperties();
+        for (int i = 0; i < properties.size(); i++) {
+            PropertyConfigProto propertyProto = convertProperty(properties.get(i));
+            protoBuilder.addProperties(propertyProto);
         }
         return protoBuilder.build();
     }
 
     @NonNull
-    private static PropertyConfigProto convertProperty(@NonNull Bundle bundle) {
-        Preconditions.checkNotNull(bundle);
+    private static PropertyConfigProto convertProperty(
+            @NonNull AppSearchSchema.PropertyConfig property) {
+        Preconditions.checkNotNull(property);
         PropertyConfigProto.Builder propertyConfigProto = PropertyConfigProto.newBuilder()
-                .setPropertyName(bundle.getString(AppSearchSchema.PropertyConfig.NAME_FIELD, ""));
+                .setPropertyName(property.getName());
         IndexingConfig.Builder indexingConfig = IndexingConfig.newBuilder();
 
         // Set dataType
-        @AppSearchSchema.PropertyConfig.DataType int dataType =
-                bundle.getInt(AppSearchSchema.PropertyConfig.DATA_TYPE_FIELD);
+        @AppSearchSchema.PropertyConfig.DataType int dataType = property.getDataType();
         PropertyConfigProto.DataType.Code dataTypeProto =
                 PropertyConfigProto.DataType.Code.forNumber(dataType);
         if (dataTypeProto == null) {
@@ -78,12 +71,13 @@
         propertyConfigProto.setDataType(dataTypeProto);
 
         // Set schemaType
-        propertyConfigProto.setSchemaType(
-                bundle.getString(AppSearchSchema.PropertyConfig.SCHEMA_TYPE_FIELD, ""));
+        String schemaType = property.getSchemaType();
+        if (schemaType != null) {
+            propertyConfigProto.setSchemaType(schemaType);
+        }
 
         // Set cardinality
-        @AppSearchSchema.PropertyConfig.Cardinality int cardinality =
-                bundle.getInt(AppSearchSchema.PropertyConfig.CARDINALITY_FIELD);
+        @AppSearchSchema.PropertyConfig.Cardinality int cardinality = property.getCardinality();
         PropertyConfigProto.Cardinality.Code cardinalityProto =
                 PropertyConfigProto.Cardinality.Code.forNumber(cardinality);
         if (cardinalityProto == null) {
@@ -92,8 +86,7 @@
         propertyConfigProto.setCardinality(cardinalityProto);
 
         // Set indexingType
-        @AppSearchSchema.PropertyConfig.IndexingType int indexingType =
-                bundle.getInt(AppSearchSchema.PropertyConfig.INDEXING_TYPE_FIELD);
+        @AppSearchSchema.PropertyConfig.IndexingType int indexingType = property.getIndexingType();
         TermMatchType.Code termMatchTypeProto;
         switch (indexingType) {
             case AppSearchSchema.PropertyConfig.INDEXING_TYPE_NONE:
@@ -112,7 +105,7 @@
 
         // Set tokenizerType
         @AppSearchSchema.PropertyConfig.TokenizerType int tokenizerType =
-                bundle.getInt(AppSearchSchema.PropertyConfig.TOKENIZER_TYPE_FIELD);
+                property.getTokenizerType();
         IndexingConfig.TokenizerType.Code tokenizerTypeProto =
                 IndexingConfig.TokenizerType.Code.forNumber(tokenizerType);
         if (tokenizerTypeProto == null) {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/SearchResultToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
similarity index 79%
rename from apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/SearchResultToProtoConverter.java
rename to apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
index 524c80d..9f7c696 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/SearchResultToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.appsearch.external.localbackend.converter;
+package com.android.server.appsearch.external.localstorage.converter;
 
 import android.os.Bundle;
 
@@ -22,43 +22,32 @@
 
 import android.app.appsearch.GenericDocument;
 import android.app.appsearch.SearchResult;
-import android.app.appsearch.SearchResults;
 
 import com.google.android.icing.proto.SearchResultProto;
 import com.google.android.icing.proto.SnippetMatchProto;
 import com.google.android.icing.proto.SnippetProto;
 
 import java.util.ArrayList;
-import java.util.List;
 
 /**
- * Translates a {@link SearchResultProto} into {@link SearchResults}.
+ * Translates a {@link SearchResultProto} into {@link SearchResult}s.
+ *
  * @hide
  */
 
 public class SearchResultToProtoConverter {
     private SearchResultToProtoConverter() {}
 
-    /** Translates a {@link SearchResultProto} into a list of {@link SearchResult}. */
-    @NonNull
-    public static List<SearchResult> convert(@NonNull SearchResultProto searchResultProto) {
-        List<SearchResult> results = new ArrayList<>(searchResultProto.getResultsCount());
-        for (int i = 0; i < searchResultProto.getResultsCount(); i++) {
-            results.add(convertSearchResult(searchResultProto.getResults(i)));
-        }
-        return results;
-    }
-
     /** Translate a {@link SearchResultProto.ResultProto} into {@link SearchResult}. */
     @NonNull
-    static SearchResult convertSearchResult(@NonNull SearchResultProto.ResultProto proto) {
+    public static SearchResult convertSearchResult(
+            @NonNull SearchResultProto.ResultProtoOrBuilder proto) {
         Bundle bundle = new Bundle();
         GenericDocument document = GenericDocumentToProtoConverter.convert(proto.getDocument());
         bundle.putBundle(SearchResult.DOCUMENT_FIELD, document.getBundle());
 
-        ArrayList<Bundle> matchList = null;
+        ArrayList<Bundle> matchList = new ArrayList<>();
         if (proto.hasSnippet()) {
-            matchList = new ArrayList<>();
             for (int i = 0; i < proto.getSnippet().getEntriesCount(); i++) {
                 SnippetProto.EntryProto entry = proto.getSnippet().getEntries(i);
                 for (int j = 0; j < entry.getSnippetMatchesCount(); j++) {
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/SearchSpecToProtoConverter.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
similarity index 67%
rename from apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/SearchSpecToProtoConverter.java
rename to apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
index a5d913a..14822dc 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localbackend/converter/SearchSpecToProtoConverter.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.appsearch.external.localbackend.converter;
-
-import android.os.Bundle;
+package com.android.server.appsearch.external.localstorage.converter;
 
 import android.annotation.NonNull;
 
@@ -28,8 +26,6 @@
 import com.google.android.icing.proto.SearchSpecProto;
 import com.google.android.icing.proto.TermMatchType;
 
-import java.util.Arrays;
-
 /**
  * Translates a {@link SearchSpec} into icing search protos.
  * @hide
@@ -42,25 +38,17 @@
     @NonNull
     public static SearchSpecProto toSearchSpecProto(@NonNull SearchSpec spec) {
         Preconditions.checkNotNull(spec);
-        Bundle bundle = spec.getBundle();
-        SearchSpecProto.Builder protoBuilder = SearchSpecProto.newBuilder();
+        SearchSpecProto.Builder protoBuilder = SearchSpecProto.newBuilder()
+                .addAllSchemaTypeFilters(spec.getSchemas())
+                .addAllNamespaceFilters(spec.getNamespaces());
 
-        @SearchSpec.TermMatchCode int termMatchCode =
-                bundle.getInt(SearchSpec.TERM_MATCH_TYPE_FIELD);
+        @SearchSpec.TermMatch int termMatchCode = spec.getTermMatch();
         TermMatchType.Code termMatchCodeProto = TermMatchType.Code.forNumber(termMatchCode);
         if (termMatchCodeProto == null || termMatchCodeProto.equals(TermMatchType.Code.UNKNOWN)) {
             throw new IllegalArgumentException("Invalid term match type: " + termMatchCode);
         }
         protoBuilder.setTermMatchType(termMatchCodeProto);
 
-        String[] schemaTypes = bundle.getStringArray(SearchSpec.SCHEMA_TYPES_FIELD);
-        if (schemaTypes != null) {
-            protoBuilder.addAllSchemaTypeFilters(Arrays.asList(schemaTypes));
-        }
-        String[] namespaces = bundle.getStringArray(SearchSpec.NAMESPACE_FIELD);
-        if (namespaces != null) {
-            protoBuilder.addAllNamespaceFilters(Arrays.asList(namespaces));
-        }
         return protoBuilder.build();
     }
 
@@ -68,27 +56,23 @@
     @NonNull
     public static ResultSpecProto toResultSpecProto(@NonNull SearchSpec spec) {
         Preconditions.checkNotNull(spec);
-        Bundle bundle = spec.getBundle();
         return ResultSpecProto.newBuilder()
-                .setNumPerPage(bundle.getInt(
-                        SearchSpec.NUM_PER_PAGE_FIELD, SearchSpec.DEFAULT_NUM_PER_PAGE))
-                .setSnippetSpec(ResultSpecProto.SnippetSpecProto.newBuilder()
-                        .setNumToSnippet(bundle.getInt(SearchSpec.SNIPPET_COUNT_FIELD))
-                        .setNumMatchesPerProperty(
-                                bundle.getInt(SearchSpec.SNIPPET_COUNT_PER_PROPERTY_FIELD))
-                        .setMaxWindowBytes(bundle.getInt(SearchSpec.MAX_SNIPPET_FIELD)))
+                .setNumPerPage(spec.getNumPerPage())
+                .setSnippetSpec(
+                        ResultSpecProto.SnippetSpecProto.newBuilder()
+                                .setNumToSnippet(spec.getSnippetCount())
+                                .setNumMatchesPerProperty(spec.getSnippetCountPerProperty())
+                                .setMaxWindowBytes(spec.getMaxSnippetSize()))
                 .build();
-
     }
 
     /** Extracts {@link ScoringSpecProto} information from a {@link SearchSpec}. */
     @NonNull
     public static ScoringSpecProto toScoringSpecProto(@NonNull SearchSpec spec) {
         Preconditions.checkNotNull(spec);
-        Bundle bundle = spec.getBundle();
         ScoringSpecProto.Builder protoBuilder = ScoringSpecProto.newBuilder();
 
-        @SearchSpec.OrderCode int orderCode = bundle.getInt(SearchSpec.ORDER_FIELD);
+        @SearchSpec.Order int orderCode = spec.getOrder();
         ScoringSpecProto.Order.Code orderCodeProto =
                 ScoringSpecProto.Order.Code.forNumber(orderCode);
         if (orderCodeProto == null) {
@@ -96,8 +80,7 @@
         }
         protoBuilder.setOrderBy(orderCodeProto);
 
-        @SearchSpec.RankingStrategyCode int rankingStrategyCode =
-                bundle.getInt(SearchSpec.RANKING_STRATEGY_FIELD);
+        @SearchSpec.RankingStrategy int rankingStrategyCode = spec.getRankingStrategy();
         ScoringSpecProto.RankingStrategy.Code rankingStrategyCodeProto =
                 ScoringSpecProto.RankingStrategy.Code.forNumber(rankingStrategyCode);
         if (rankingStrategyCodeProto == null) {
diff --git a/apex/extservices/Android.bp b/apex/extservices/Android.bp
deleted file mode 100644
index 0c6c4c2..0000000
--- a/apex/extservices/Android.bp
+++ /dev/null
@@ -1,39 +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.
-
-apex {
-    name: "com.android.extservices",
-    defaults: ["com.android.extservices-defaults"],
-    manifest: "apex_manifest.json",
-}
-
-apex_defaults {
-    name: "com.android.extservices-defaults",
-    updatable: true,
-    min_sdk_version: "current",
-    key: "com.android.extservices.key",
-    certificate: ":com.android.extservices.certificate",
-    apps: ["ExtServices"],
-}
-
-apex_key {
-    name: "com.android.extservices.key",
-    public_key: "com.android.extservices.avbpubkey",
-    private_key: "com.android.extservices.pem",
-}
-
-android_app_certificate {
-    name: "com.android.extservices.certificate",
-    certificate: "com.android.extservices",
-}
diff --git a/apex/extservices/apex_manifest.json b/apex/extservices/apex_manifest.json
deleted file mode 100644
index b4acf128..0000000
--- a/apex/extservices/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.extservices",
-  "version": 300000000
-}
diff --git a/apex/extservices/com.android.extservices.avbpubkey b/apex/extservices/com.android.extservices.avbpubkey
deleted file mode 100644
index f37d3e4..0000000
--- a/apex/extservices/com.android.extservices.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/extservices/com.android.extservices.pem b/apex/extservices/com.android.extservices.pem
deleted file mode 100644
index 7bfbd34..0000000
--- a/apex/extservices/com.android.extservices.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKAIBAAKCAgEAuYshVDiRkt3tmBhqcWkKOm5GcviKpLbHSPpYQDHGDwS0dqqL
-SqAd1/BgT/bVVtUkAciFApPnXn96WhNYCypptyC5FHCxM21uBCGmow+3WermD++w
-5dQk4QP2ONPIpG+KzOWBl9SiBud4SpOHDyr0JycBsrXS89Tln9kAsTDuDEFfXL/J
-8cX/S3IUwhPV0pAlgUIHdDp0DGFjZaJlEZBZ+HmImriC/AUNUMVb5lfbczXOEZPF
-0A9+JzYschfXUxn8nu1N7RN5GDbq+chszx1FMVhuFUheukkd4dLNSDl0O0RlUnD+
-C/xz1ilDzEVZhnMtMnxS9oJ8bA/HUVMfsFnaQbgGmQ0CcxFxnfbYyGXGG1H+b8vA
-MTVQi5rZXG2p+VgHIAKVrYmpETVnRPgoMqp18KuGtp5SDngi13G3YEzS7iFbqfYh
-6iW2G974nD/Dq0cSire8Oljd9PEaMCMZiP5PTFJp0G/mtw7ROoyZqsSM6rX3XVTo
-Y5dBmBMctSJ8rgDMi0ZNvRH+rq/E5+RT6yMAJ7DDbOJzBnQ3IIoGn8NzUT3P1FCB
-HYEp1U2N7QNirIQMAuVz3IlHae9N1kl3eGAO6f2CjV7vZmFpDeWw+KSYs71mRkOb
-WBgl6D9FFq4u1azrU3AwV0dj3x1eU6yVnKUy1J7ppF/mcR+VzH7ThzTdV7cCAwEA
-AQKCAgEApWFU2Mv/PYhg0bPZlLLKsiA+3RWaBo0AfpTd+oIjBpnr/OWweFjVoPcZ
-8cyShe4/RPOlUxHgJcO8m/MoA/PO/LLHJWf5GlzMthQEgs1sYVJVtBiydXitUn+E
-hUyIR8FAV7et1lZqAXtqJhbvSF7B9u/2vIMCv+GgtuTmkAmL9RKD3Jj6eG1CS84o
-oICrkx52v4rKOBgt/icEQMAKFCi1eRti3n3eCqK6JqdzbZIcAcoQnmw34mccy/im
-jx+fBuxf1oywa8NyqVmyAehazBVL6lrm7ENwY9zuLK4H2fuUFYu2QFCEsMxZt6da
-TgX2cTfSLnDQRfcyzeMWhu9vjHHabjpLNjiCKhIhGyO0rO1rtea8ajZHgM/2sxXq
-6gLynW0dlatlxmjANlN9WQPGNdzvcIFJ0TLnI4mlJnWpqCsN9iW1d4ey13WiZUVR
-DgtnR60zao+LRCCM4D3cuVLq0DjL2BlHGXnOPK/LpQG1LbI1TroZpgSEHSZlQRzT
-ql9txgNqTHxijXuPL2VhhwhW7cqDoO8sLwV3BqDMIH56U0cbUBiSA/G9fKeI/DEG
-i7LcrMgrBk+xnuAWoFHuzfBMAdD9i3kYyk+41tOmcza2TNJgxadVYp5woHFvYvS/
-GKaNiRz0XmcijO5Ir0yxgCq21BdkWzo5zVrTFABiKeR7YXiee8kCggEBAOeULWgR
-spolJJrACWJspRvKb9FGnbGiYOnCGJoAc751kuXmNxoyWnEwgcjrSEoayNPUfOtz
-IgA+twqjgl0Zec2XFPfUcgWUBrrvvUEV4NIH5ibaR7ezHGeovCWs9XoDyzHHvhDr
-c6T5kXFZ60rS5h6LGUnE1hkHFJoHuTIBbn9j7eIbri8S71i7HWQ04s4KuQ+Bwbxm
-UnkEhbc+zMWHXfXy7rx4/eEZcZwtEybIORcHXYNPGeqMfOlcEMHpKEOi+NvDA6cp
-vTaTSwJ6ZBgYh7Tw3bNgRxSknaIhcGwMD0ojStjC5xzXT1Zr2Z3GXwYvOGcq3MeZ
-z+V2cx5xuwyp7R0CggEBAM0cKKNZEZwi/1zBPUDMFB4iJoX12BxQX6e5wdlHGXgF
-XeZwCnaIxOxMDxH79M5Svmpdu/jkUijI/pRvcE1iohFyIBvTUSDmlAoy4keXqMEQ
-M2hA+TwVA3JLmMcV8HKy/MFlwwKJB1JDcoxGjnXsM5UjVTD2jilO7vlJZs3+0ws0
-R7qzRT3ED25QTpZyDYcKE2otc5bzIZG3yAaJtWd3NugWsKpxDgr2RFUGJiHBq72n
-48FkSjfgaDTn83zYcPvS0Uykb2ho8G/N+EurstL41n3nQo0I7FLbyptOopDDwsSp
-Ndejn08NVAQ+xFAafOyqHkA3Ytpl0QCZDpMBuLdvw+MCggEAOVMt1kgjPRMat4/4
-ArxANtvqyBRB7vnyIYthiaW5ARmbrntJgpuaVdCbIABWGbn9oqpD7gjHDuZ3axPE
-roUi6KiQkTSusQDOlbHI2Haw+2znJRD9ldSpoGNdh7oD3htYTk9Sll+ideEthrCq
-lRAV1NO8A83M7c8Z43Mr/dvq3XAAL+uIN7DpPL687NRGnJh87QDC039ExR5Ad3b9
-O5xhvwNO46rTtcgVnoJt7ji8IR46oMmQ8cWrGh0nLMkppWyPS98/ZT7ozryxYcCo
-TGquFTVWvBOGJO8G8l5ytNxbYI/R9Exy52nJAuyZpvu3BBHmVWt/0Y0asIOcxZmD
-owPhZQKCAQAfWAFBzReq05JQe1s/7q/YVwGqEQKgeQvVFsbvzDSxKajK0S5YJNhq
-/8iByA4GBZEBsidKhqGjh+uXhVwVB1Ca9+S+O9G3BGV1FYeMxzlLn40rjlpH+zIW
-okTLj6e5724+o61kUspioNn9Y77beGf9j3OyUsswttZAFB54tktL+AZKGqEnKjHt
-eqo3xWAZ1clXvXBfjfIAUaRok1y8XfRvDSCcO0CZHj8c+x6SpAT5q5FbeVb6KPnj
-s9p6ppzFbtb7Llm0C+1KOKCL98YRBWPJw7Bg2w86LkpM53xiQPgfk3gd5uwuaWwA
-ZhMb5qBWjjynNY+OrmZ8/+bBQk8XASZfAoIBAFkHOnZOD1JJQ0QvaJ9tuCgHi216
-I8QPMMTdm3ZEDHSYMNwl7ayeseBcmB2zaqBKYz75qcU0SK4lnZkR2wIpbsHZNSVM
-J0WpN6r9G4JdnVi11J04RsfSMjCUr/PTVMmPvw8xPHrCxkJmB+d56olSE80I1Jrx
-djCv1LtSsT10W7FIcY82/cOi4xxGLOA70lDCf+szofQgVP8WvuOA1YaFw98ca8zc
-A401CyNexk24/c3d6C19YW/MppdE0uGMxL/oHsPgwkZAf6LmvF/UF71PsBUEniLc
-YFaJl3wn1cPfBBo9L4sZzyP2qokL8YHdg+wW7b4IOsYwbeqceBvqPtcUUPs=
------END RSA PRIVATE KEY-----
diff --git a/apex/extservices/com.android.extservices.pk8 b/apex/extservices/com.android.extservices.pk8
deleted file mode 100644
index 59585a2..0000000
--- a/apex/extservices/com.android.extservices.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/extservices/com.android.extservices.x509.pem b/apex/extservices/com.android.extservices.x509.pem
deleted file mode 100644
index e0343b8..0000000
--- a/apex/extservices/com.android.extservices.x509.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGLTCCBBWgAwIBAgIUdqdMmx/5OsCP3Ew3/hcr7+1ACHEwDQYJKoZIhvcNAQEL
-BQAwgaQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMSAwHgYDVQQDDBdjb20uYW5kcm9pZC5leHRzZXJ2aWNlczEiMCAGCSqGSIb3
-DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAgFw0yMDAxMTcxMDIxMzZaGA80NzU3
-MTIxMzEwMjEzNlowgaQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
-MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
-VQQLDAdBbmRyb2lkMSAwHgYDVQQDDBdjb20uYW5kcm9pZC5leHRzZXJ2aWNlczEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCAiIwDQYJKoZIhvcN
-AQEBBQADggIPADCCAgoCggIBANKaSeLGaFRRt779vAtTfG3t2aQZrWOByUYc7yUN
-RdmJqWxU47OL5urYmanWPbz2f972Q9oi8x+8y4ny9SEY3wg0pUbzvKNTXpkxWyG1
-HE2C2zTfzuDDLpDIf2usWynt1wLVhpYC3k+7Yv2vOIK5dKkezh6PfdKmsbDae5DE
-d22tTSYZ5KwNpIWrgQle26cRG5sqhAFdkpgGMF00Huz06cjUoTjs2sNSlXTRBOTP
-CCy8UoRjBivQZkwHbddfsn+Z22ARPG8JDg/n4mEi8C0T6bJeQeirSPkBCkD6Djgq
-7RddJ2eLYZII8l8r6A6x+6cnTkXHaV5g3LUwPvi8XEn9IUuT9WJNRje/vfYLycTQ
-kP415CZMxDvsi1Ul4YsbL3enE89ryGMTpVZPogch/36DG5Sye28yISItNUy3urJa
-OXbg7mh+MwPd4bQaW4CJk+AUweKaF4aV0SZFT+nCewL4xLdGdy889KazlW98NqtK
-hOSxIg1jHkZq48ajuq2A+ns1yDKt1l0f9IYCz3mz/IXInokbkjPvHahJTJ+OMHXO
-THD8e5gBzcK841jJk+H3EsIYOHsp66uy2IgEHN+9pAS6vI0xfrXOYuKzuSL3oxcV
-FlVTimt4xokMMerdcW4KD+MC5NFEip4DUS4JKCyG0wRI3ffEs9Zcpxi3QSibrjLW
-rz+hAgMBAAGjUzBRMB0GA1UdDgQWBBTP2AhZzEUUgtAFlkaMaq+RvY06fDAfBgNV
-HSMEGDAWgBTP2AhZzEUUgtAFlkaMaq+RvY06fDAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBCwUAA4ICAQCbwtfo37j62Sudmt32PCfRN/r5ZNDNNA2JhR8uDUmX
-xXfF5YfDvSKsNLiQKcDagu6a+0C+QnzXHXCBlXZFrTJ8NAVMlmqdHGwoFoYMfJZH
-R1lCTidyFMoMLJ8GRGPJjzDkKnOeAqKMCtKvXoH2r12+JB2/ov4ooLREu/wPkEXT
-OymkyWNP5XLQTKWqfEQyXXFpuwZ+m35Wkr0Fm92mZeJpVeIZPK7M7aK3zyoj7XJP
-YLMsR/AQs8OULdpfNMddAuN3ndlYu03LZlsF6LG5bduaDDcESJ5hdJrgBa/NBKRU
-IbS+q/6WAjYKMNRT/fPGew4wUzlWKi1Ihdk79oaqKKijE1b2JSJD1/SEYiBf+JPE
-bXobUrMbBwFpdhT+YLMF9FsuPQKsUIONaWiO4QcQoY/rQwGxPP6fV8ZbBrUWJewj
-MpSdU9foZNa/TmOAgfS/JxH+nXnG4+H1m8mdNBsxvsYmF2ZuGb/jdEeA2cuHIJDZ
-FJeWwCFxzlCGZJaUsxsnZByADBuufUVaO/9gGs0YQC/JP1i9hK4DyZdKwZpXdLi2
-Nw27Qma4WEIZnMb6Rgk1nTV+7ALcOSIhGgFOOeDTuCGfnEcz2coai5fbD/K6Q7Xu
-IRNyxHQjheZPdei2x912Ex/KqKGfaFaZJxrvCSKdhzxcTFIsO4JuZs+SDpRTKcI7
-Cw==
------END CERTIFICATE-----
diff --git a/apex/extservices/testing/Android.bp b/apex/extservices/testing/Android.bp
deleted file mode 100644
index 88a4724..0000000
--- a/apex/extservices/testing/Android.bp
+++ /dev/null
@@ -1,25 +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.
-
-apex_test {
-    name: "test_com.android.extservices",
-    visibility: [
-        "//system/apex/tests",
-    ],
-    defaults: ["com.android.extservices-defaults"],
-    manifest: "test_manifest.json",
-    file_contexts: ":com.android.extservices-file_contexts",
-    // Test APEX, should never be installed
-    installable: false,
-}
diff --git a/apex/extservices/testing/test_manifest.json b/apex/extservices/testing/test_manifest.json
deleted file mode 100644
index 23a50e3..0000000
--- a/apex/extservices/testing/test_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.extservices",
-  "version": 2147483647
-}
diff --git a/api/current.txt b/api/current.txt
index 9ff7cc2..6459eb4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11718,10 +11718,9 @@
     method public long getFirstInstallTime();
     method public android.graphics.drawable.Drawable getIcon(int);
     method public CharSequence getLabel();
+    method public float getLoadingProgress();
     method public String getName();
-    method public float getProgress();
     method public android.os.UserHandle getUser();
-    method public boolean isLoading();
     method public boolean isStartable();
   }
 
@@ -11762,7 +11761,7 @@
     ctor public LauncherApps.Callback();
     method public abstract void onPackageAdded(String, android.os.UserHandle);
     method public abstract void onPackageChanged(String, android.os.UserHandle);
-    method public void onPackageProgressChanged(@NonNull String, @NonNull android.os.UserHandle, float);
+    method public void onPackageLoadingProgressChanged(@NonNull String, @NonNull android.os.UserHandle, float);
     method public abstract void onPackageRemoved(String, android.os.UserHandle);
     method public abstract void onPackagesAvailable(String[], android.os.UserHandle, boolean);
     method public void onPackagesSuspended(String[], android.os.UserHandle);
@@ -31862,6 +31861,15 @@
     method public void onAttached(android.net.wifi.aware.WifiAwareSession);
   }
 
+  public final class AwareResources implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getNumOfAvailableDataPaths();
+    method public int getNumOfAvailablePublishSessions();
+    method public int getNumOfAvailableSubscribeSessions();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.AwareResources> CREATOR;
+  }
+
   public final class Characteristics implements android.os.Parcelable {
     method public int describeContents();
     method public int getMaxMatchFilterLength();
@@ -31964,7 +31972,8 @@
   public class WifiAwareManager {
     method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @Nullable android.os.Handler);
     method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler);
-    method public android.net.wifi.aware.Characteristics getCharacteristics();
+    method @Nullable public android.net.wifi.aware.AwareResources getAvailableAwareResources();
+    method @Nullable public android.net.wifi.aware.Characteristics getCharacteristics();
     method public boolean isAvailable();
     method public boolean isDeviceAttached();
     method public boolean isInstantCommunicationModeEnabled();
diff --git a/api/system-current.txt b/api/system-current.txt
index 0b95c6d..9cf0926 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5725,7 +5725,7 @@
     method @NonNull public android.media.tv.tuner.frontend.AtscFrontendSettings.Builder setModulation(int);
   }
 
-  public class DtmbFrontendCapabilities extends android.media.tv.tuner.frontend.FrontendCapabilities {
+  public final class DtmbFrontendCapabilities extends android.media.tv.tuner.frontend.FrontendCapabilities {
     method public int getBandwidthCapability();
     method public int getCodeRateCapability();
     method public int getGuardIntervalCapability();
@@ -5734,7 +5734,7 @@
     method public int getTransmissionModeCapability();
   }
 
-  public class DtmbFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
+  public final class DtmbFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
     method @NonNull public static android.media.tv.tuner.frontend.DtmbFrontendSettings.Builder builder();
     method public int getBandwidth();
     method public int getCodeRate();
@@ -5797,6 +5797,7 @@
   public class DvbcFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
     method @NonNull public static android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder builder();
     method public int getAnnex();
+    method public int getBandwidth();
     method public long getInnerFec();
     method public int getModulation();
     method public int getOuterFec();
@@ -5808,6 +5809,11 @@
     field public static final int ANNEX_B = 2; // 0x2
     field public static final int ANNEX_C = 4; // 0x4
     field public static final int ANNEX_UNDEFINED = 0; // 0x0
+    field public static final int BANDWIDTH_5MHZ = 1; // 0x1
+    field public static final int BANDWIDTH_6MHZ = 2; // 0x2
+    field public static final int BANDWIDTH_7MHZ = 4; // 0x4
+    field public static final int BANDWIDTH_8MHZ = 8; // 0x8
+    field public static final int BANDWIDTH_UNDEFINED = 0; // 0x0
     field public static final int MODULATION_AUTO = 1; // 0x1
     field public static final int MODULATION_MOD_128QAM = 16; // 0x10
     field public static final int MODULATION_MOD_16QAM = 2; // 0x2
@@ -5837,6 +5843,7 @@
   public static class DvbcFrontendSettings.Builder {
     method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings build();
     method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setAnnex(int);
+    method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setBandwidth(int);
     method @IntRange(from=1) @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setFrequency(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setInnerFec(long);
     method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setModulation(int);
@@ -6130,17 +6137,17 @@
     method public int getBer();
     method @NonNull public int[] getBers();
     method @NonNull public int[] getCodeRates();
+    method @NonNull public int[] getExtendedModulations();
     method public int getFreqOffset();
     method public int getGuardInterval();
     method public int getHierarchy();
     method public long getInnerFec();
     method @NonNull public int[] getInterleaving();
-    method @NonNull public int[] getIsdbtSegment();
+    method @IntRange(from=0, to=255) @NonNull public int[] getIsdbtSegment();
     method @NonNull public boolean[] getLayerErrors();
     method public int getLnbVoltage();
     method public int getMer();
     method public int getModulation();
-    method @NonNull public int[] getModulationsExt();
     method public int getPer();
     method public int getPerBer();
     method public int getPlpId();
@@ -6149,7 +6156,7 @@
     method public int getSnr();
     method public int getSpectralInversion();
     method public int getSymbolRate();
-    method public int getSystemId();
+    method @IntRange(from=0, to=65535) public int getSystemId();
     method public int getTransmissionMode();
     method @NonNull public int[] getTsDataRate();
     method public int getUec();
@@ -7494,6 +7501,7 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApCapability> CREATOR;
     field public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1L; // 0x1L
     field public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 2L; // 0x2L
+    field public static final long SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION = 8L; // 0x8L
     field public static final long SOFTAP_FEATURE_WPA3_SAE = 4L; // 0x4L
   }
 
@@ -7675,8 +7683,11 @@
     method public double getSuccessfulRxPacketsPerSecond();
     method public double getSuccessfulTxPacketsPerSecond();
     method public boolean isEphemeral();
+    method public boolean isOemPaid();
+    method public boolean isOemPrivate();
     method public boolean isOsuAp();
     method public boolean isPasspointAp();
+    method public boolean isTrusted();
     method @Nullable public static String sanitizeSsid(@Nullable String);
     field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
     field public static final int INVALID_RSSI = -127; // 0xffffff81
@@ -7902,11 +7913,13 @@
   public final class WifiNetworkSuggestion implements android.os.Parcelable {
     method @NonNull public android.net.wifi.WifiConfiguration getWifiConfiguration();
     method public boolean isOemPaid();
+    method public boolean isOemPrivate();
   }
 
   public static final class WifiNetworkSuggestion.Builder {
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public android.net.wifi.WifiNetworkSuggestion.Builder setCarrierId(int);
     method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setOemPaid(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setOemPrivate(boolean);
   }
 
   public class WifiScanner {
@@ -9472,6 +9485,7 @@
     field public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
     field public static final String NAMESPACE_PERMISSIONS = "permissions";
     field public static final String NAMESPACE_PRIVACY = "privacy";
+    field public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot";
     field public static final String NAMESPACE_ROLLBACK = "rollback";
     field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
     field public static final String NAMESPACE_RUNTIME = "runtime";
diff --git a/api/test-current.txt b/api/test-current.txt
index 785463a9..67b496b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -290,6 +290,7 @@
     method @NonNull public android.content.res.Configuration getConfiguration();
     method @Nullable public android.app.PictureInPictureParams getPictureInPictureParams();
     method @NonNull public android.window.WindowContainerToken getToken();
+    method public boolean hasParentTask();
   }
 
   public class TimePickerDialog extends android.app.AlertDialog implements android.content.DialogInterface.OnClickListener android.widget.TimePicker.OnTimeChangedListener {
@@ -970,6 +971,14 @@
     field public static final String SAMPLE_RATE = "android.media.audiotrack.sampleRate";
   }
 
+  public abstract class Image implements java.lang.AutoCloseable {
+    ctor protected Image();
+  }
+
+  public abstract static class Image.Plane {
+    ctor protected Image.Plane();
+  }
+
   public final class MediaCas implements java.lang.AutoCloseable {
     method public void forceResourceLost();
   }
@@ -1793,6 +1802,7 @@
     method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
     method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getSupportedRadioAccessFamily();
     method public boolean modifyDevicePolicyOverrideApn(@NonNull android.content.Context, int, @NonNull android.telephony.data.ApnSetting);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile();
     method @Deprecated public void setCarrierTestOverride(String, String, String, String, String, String, String);
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h
index 2da4a186..406086d 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.h
+++ b/cmds/statsd/src/anomaly/AlarmTracker.h
@@ -73,6 +73,7 @@
 
     FRIEND_TEST(AlarmTrackerTest, TestTriggerTimestamp);
     FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
+    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlarms);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index 619752c..6aa410b 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -37,14 +37,6 @@
 AnomalyTracker::AnomalyTracker(const Alert& alert, const ConfigKey& configKey)
         : mAlert(alert), mConfigKey(configKey), mNumOfPastBuckets(mAlert.num_buckets() - 1) {
     VLOG("AnomalyTracker() called");
-    if (mAlert.num_buckets() <= 0) {
-        ALOGE("Cannot create AnomalyTracker with %lld buckets", (long long)mAlert.num_buckets());
-        return;
-    }
-    if (!mAlert.has_trigger_if_sum_gt()) {
-        ALOGE("Cannot create AnomalyTracker without threshold");
-        return;
-    }
     resetStorage();  // initialization
 }
 
@@ -52,6 +44,10 @@
     VLOG("~AnomalyTracker() called");
 }
 
+void AnomalyTracker::onConfigUpdated() {
+    mSubscriptions.clear();
+}
+
 void AnomalyTracker::resetStorage() {
     VLOG("resetStorage() called.");
     mPastBuckets.clear();
@@ -259,6 +255,15 @@
     return false;
 }
 
+std::pair<bool, uint64_t> AnomalyTracker::getProtoHash() const {
+    string serializedAlert;
+    if (!mAlert.SerializeToString(&serializedAlert)) {
+        ALOGW("Unable to serialize alert %lld", (long long)mAlert.id());
+        return {false, 0};
+    }
+    return {true, Hash64(serializedAlert)};
+}
+
 void AnomalyTracker::informSubscribers(const MetricDimensionKey& key, int64_t metric_id,
                                        int64_t metricValue) {
     triggerSubscribers(mAlert.id(), metric_id, key, metricValue, mConfigKey, mSubscriptions);
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h
index bf36a3b..9a578ee 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.h
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.h
@@ -16,15 +16,15 @@
 
 #pragma once
 
-#include <stdlib.h>
-
 #include <gtest/gtest_prod.h>
+#include <stdlib.h>
 #include <utils/RefBase.h>
 
 #include "AlarmMonitor.h"
 #include "config/ConfigKey.h"
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alert
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"    // Alert
 #include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"  // AlertMetadata
+#include "hash.h"
 #include "stats_util.h"  // HashableDimensionKey and DimToValMap
 
 namespace android {
@@ -41,6 +41,9 @@
 
     virtual ~AnomalyTracker();
 
+    // Reset appropriate state on a config update. Clear subscriptions so they can be reset.
+    void onConfigUpdated();
+
     // Add subscriptions that depend on this alert.
     void addSubscription(const Subscription& subscription) {
         mSubscriptions.push_back(subscription);
@@ -106,6 +109,26 @@
         return mNumOfPastBuckets;
     }
 
+    std::pair<bool, uint64_t> getProtoHash() const;
+
+    // Sets an alarm for the given timestamp.
+    // Replaces previous alarm if one already exists.
+    virtual void startAlarm(const MetricDimensionKey& dimensionKey, const int64_t& eventTime) {
+        return;  // The base AnomalyTracker class doesn't have alarms.
+    }
+
+    // Stops the alarm.
+    // If it should have already fired, but hasn't yet (e.g. because the AlarmManager is delayed),
+    // declare the anomaly now.
+    virtual void stopAlarm(const MetricDimensionKey& dimensionKey, const int64_t& timestampNs) {
+        return;  // The base AnomalyTracker class doesn't have alarms.
+    }
+
+    // Stop all the alarms owned by this tracker. Does not declare any anomalies.
+    virtual void cancelAllAlarms() {
+        return;  // The base AnomalyTracker class doesn't have alarms.
+    }
+
     // Declares an anomaly for each alarm in firedAlarms that belongs to this AnomalyTracker,
     // and removes it from firedAlarms. Does NOT remove the alarm from the AlarmMonitor.
     virtual void informAlarmsFired(const int64_t& timestampNs,
@@ -197,6 +220,8 @@
     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
+
+    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlerts);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
index 686d8f9..4641914 100644
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
+++ b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
@@ -34,15 +34,15 @@
 
     // Sets an alarm for the given timestamp.
     // Replaces previous alarm if one already exists.
-    void startAlarm(const MetricDimensionKey& dimensionKey, const int64_t& eventTime);
+    void startAlarm(const MetricDimensionKey& dimensionKey, const int64_t& eventTime) override;
 
     // Stops the alarm.
     // If it should have already fired, but hasn't yet (e.g. because the AlarmManager is delayed),
     // declare the anomaly now.
-    void stopAlarm(const MetricDimensionKey& dimensionKey, const int64_t& timestampNs);
+    void stopAlarm(const MetricDimensionKey& dimensionKey, const int64_t& timestampNs) override;
 
     // Stop all the alarms owned by this tracker. Does not declare any anomalies.
-    void cancelAllAlarms();
+    void cancelAllAlarms() override;
 
     // Declares an anomaly for each alarm in firedAlarms that belongs to this DurationAnomalyTracker
     // and removes it from firedAlarms. The AlarmMonitor is not informed.
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index a379847..ac2a8e4 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -9754,6 +9754,7 @@
 
 /**
  * Global display pipeline metrics reported by SurfaceFlinger.
+ * Metrics exist beginning in Android 11.
  * Pulled from:
  *    frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp
  */
@@ -9785,18 +9786,48 @@
     // perform due to falling back into GPU composition.
     optional FrameTimingHistogram render_engine_timing = 8
         [(android.os.statsd.log_mode) = MODE_BYTES];
+    // Number of frames where SF saw a frame, based on its frame timeline.
+    // Frame timelines may include transactions without updating buffer contents.
+    // Introduced in Android 12.
+    optional int32 total_timeline_frames = 9;
+    // Number of frames where SF saw a janky frame.
+    // Introduced in Android 12.
+    optional int32 total_janky_frames = 10;
+    // Number of janky frames where SF spent a long time on the CPU.
+    // Introduced in Android 12.
+    optional int32 total_janky_frames_with_long_cpu = 11;
+    // Number of janky frames where SF spent a long time on the GPU.
+    // Introduced in Android 12.
+    optional int32 total_janky_frames_with_long_gpu = 12;
+    // Number of janky frames where SF missed the frame deadline, but there
+    // was not an attributed reason (e.g., maybe HWC missed?)
+    // Introduced in Android 12.
+    optional int32 total_janky_frames_sf_unattributed = 13;
+    // Number of janky frames where the app missed the frame deadline, but
+    // there was not an attributed reason
+    // Introduced in Android 12.
+    optional int32 total_janky_frames_app_unattributed = 14;
+
+    // Next ID: 15
 }
 
 /**
  * Per-layer display pipeline metrics reported by SurfaceFlinger.
- * The number of layers uploaded will be restricted due to size limitations.
+ * Metrics exist beginning in Android 11.
+ * The number of layers uploaded may be restricted due to size limitations.
  * Pulled from:
  *    frameworks/native/services/surfaceflinger/TimeStats/TimeStats.cpp
  */
 message SurfaceflingerStatsLayerInfo {
+    // UID of the application who submitted this layer for presentation
+    // This is intended to be used as a dimension for surfacing rendering
+    // statistics to applications.
+    // Introduced in Android 12.
+    optional int32 uid = 12 [(is_uid) = true];
     // The layer for this set of metrics
-    // For now we can infer that the package name is included in the layer
-    // name.
+    // In many scenarios the package name is included in the layer name, e.g.,
+    // layers created by Window Manager. But this is not a guarantee - in the
+    // general case layer names are arbitrary debug names.
     optional string layer_name = 1;
     // Total number of frames presented
     optional int64 total_frames = 2;
@@ -9830,6 +9861,29 @@
     optional int64 late_acquire_frames = 10;
     // Frames latched early because the desired present time was bad
     optional int64 bad_desired_present_frames = 11;
+    // Number of frames where SF saw a frame, based on its frame timeline.
+    // Frame timelines may include transactions without updating buffer contents.
+    // Introduced in Android 12.
+    optional int32 total_timeline_frames = 13;
+    // Number of frames where SF saw a janky frame.
+    // Introduced in Android 12.
+    optional int32 total_janky_frames = 14;
+    // Number of janky frames where SF spent a long time on the CPU.
+    // Introduced in Android 12.
+    optional int32 total_janky_frames_with_long_cpu = 15;
+    // Number of janky frames where SF spent a long time on the GPU.
+    // Introduced in Android 12.
+    optional int32 total_janky_frames_with_long_gpu = 16;
+    // Number of janky frames where SF missed the frame deadline, but there
+    // was not an attributed reason (e.g., maybe HWC missed?)
+    // Introduced in Android 12.
+    optional int32 total_janky_frames_sf_unattributed = 17;
+    // Number of janky frames where the app missed the frame deadline, but
+    // there was not an attributed reason
+    // Introduced in Android 12.
+    optional int32 total_janky_frames_app_unattributed = 18;
+
+    // Next ID: 19
 }
 
 /**
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index b2c0b32..8869241 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -234,14 +234,26 @@
             return nullptr;
         }
     }
-    sp<DurationAnomalyTracker> anomalyTracker =
-        new DurationAnomalyTracker(alert, mConfigKey, anomalyAlarmMonitor);
-    if (anomalyTracker != nullptr) {
-        mAnomalyTrackers.push_back(anomalyTracker);
-    }
+    sp<AnomalyTracker> anomalyTracker =
+            new DurationAnomalyTracker(alert, mConfigKey, anomalyAlarmMonitor);
+    addAnomalyTrackerLocked(anomalyTracker);
     return anomalyTracker;
 }
 
+// Adds an AnomalyTracker that has already been created.
+// Note: this gets called on config updates, and will only get called if the metric and the
+// associated alert are preserved, which means the AnomalyTracker must be a DurationAnomalyTracker.
+void DurationMetricProducer::addAnomalyTracker(sp<AnomalyTracker>& anomalyTracker) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    addAnomalyTrackerLocked(anomalyTracker);
+}
+
+void DurationMetricProducer::addAnomalyTrackerLocked(sp<AnomalyTracker>& anomalyTracker) {
+    mAnomalyTrackers.push_back(anomalyTracker);
+    for (const auto& [_, durationTracker] : mCurrentSlicedDurationTrackerMap) {
+        durationTracker->addAnomalyTracker(anomalyTracker);
+    }
+}
 void DurationMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
                                             const HashableDimensionKey& primaryKey,
                                             const FieldValue& oldState,
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 01198a9..5feb09f 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -55,6 +55,8 @@
     sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
                                          const sp<AlarmMonitor>& anomalyAlarmMonitor) override;
 
+    void addAnomalyTracker(sp<AnomalyTracker>& anomalyTracker) override;
+
     void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
                         const HashableDimensionKey& primaryKey, const FieldValue& oldState,
                         const FieldValue& newState) override;
@@ -128,6 +130,8 @@
             std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
             std::vector<int>& metricsWithActivation) override;
 
+    void addAnomalyTrackerLocked(sp<AnomalyTracker>& anomalyTracker);
+
     const DurationMetric_AggregationType mAggregationType;
 
     // Index of the SimpleAtomMatcher which defines the start.
@@ -164,9 +168,6 @@
     std::unique_ptr<DurationTracker> createDurationTracker(
             const MetricDimensionKey& eventKey) const;
 
-    // This hides the base class's std::vector<sp<AnomalyTracker>> mAnomalyTrackers
-    std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers;
-
     // Util function to check whether the specified dimension hits the guardrail.
     bool hitGuardRailLocked(const MetricDimensionKey& newKey);
 
@@ -185,6 +186,7 @@
     FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket);
 
     FRIEND_TEST(ConfigUpdateTest, TestUpdateDurationMetrics);
+    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlerts);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index 95a7d40..5b321a0 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -101,6 +101,7 @@
     }
     mEventActivationMap = newEventActivationMap;
     mEventDeactivationMap = newEventDeactivationMap;
+    mAnomalyTrackers.clear();
     return true;
 }
 
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 92c1a6e..0dc8eda 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -155,6 +155,7 @@
     // Update appropriate state on config updates. Primarily, all indices need to be updated.
     // This metric and all of its dependencies are guaranteed to be preserved across the update.
     // This function also updates several maps used by metricsManager.
+    // This function clears all anomaly trackers. All anomaly trackers need to be added again.
     bool onConfigUpdated(
             const StatsdConfig& config, const int configIndex, const int metricIndex,
             const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
@@ -237,9 +238,6 @@
                 dumpLatency, str_set, protoOutput);
     }
 
-    // Update appropriate state on config updates. Primarily, all indices need to be updated.
-    // This metric and all of its dependencies are guaranteed to be preserved across the update.
-    // This function also updates several maps used by metricsManager.
     virtual bool onConfigUpdatedLocked(
             const StatsdConfig& config, const int configIndex, const int metricIndex,
             const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
@@ -338,16 +336,20 @@
         return mSlicedStateAtoms;
     }
 
-    /* If alert is valid, adds an AnomalyTracker and returns it. If invalid, returns nullptr. */
+    /* Adds an AnomalyTracker and returns it. */
     virtual sp<AnomalyTracker> addAnomalyTracker(const Alert &alert,
                                                  const sp<AlarmMonitor>& anomalyAlarmMonitor) {
         std::lock_guard<std::mutex> lock(mMutex);
         sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, mConfigKey);
-        if (anomalyTracker != nullptr) {
-            mAnomalyTrackers.push_back(anomalyTracker);
-        }
+        mAnomalyTrackers.push_back(anomalyTracker);
         return anomalyTracker;
     }
+
+    /* Adds an AnomalyTracker that has already been created */
+    virtual void addAnomalyTracker(sp<AnomalyTracker>& anomalyTracker) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mAnomalyTrackers.push_back(anomalyTracker);
+    }
     // End: getters/setters
 protected:
     /**
@@ -571,6 +573,7 @@
     FRIEND_TEST(ConfigUpdateTest, TestUpdateGaugeMetrics);
     FRIEND_TEST(ConfigUpdateTest, TestUpdateDurationMetrics);
     FRIEND_TEST(ConfigUpdateTest, TestUpdateMetricsMultipleTypes);
+    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlerts);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index ab0d286..d80f9db 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -209,6 +209,9 @@
     map<int64_t, uint64_t> newStateProtoHashes;
     vector<sp<MetricProducer>> newMetricProducers;
     unordered_map<int64_t, int> newMetricProducerMap;
+    vector<sp<AnomalyTracker>> newAnomalyTrackers;
+    unordered_map<int64_t, int> newAlertTrackerMap;
+    vector<sp<AlarmTracker>> newPeriodicAlarmTrackers;
     mTagIds.clear();
     mConditionToMetricMap.clear();
     mTrackerToMetricMap.clear();
@@ -221,11 +224,13 @@
             mConfigKey, config, mUidMap, mPullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
             timeBaseNs, currentTimeNs, mAllAtomMatchingTrackers, mAtomMatchingTrackerMap,
             mAllConditionTrackers, mConditionTrackerMap, mAllMetricProducers, mMetricProducerMap,
-            mStateProtoHashes, mTagIds, newAtomMatchingTrackers, newAtomMatchingTrackerMap,
-            newConditionTrackers, newConditionTrackerMap, newMetricProducers, newMetricProducerMap,
-            mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
-            mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap,
-            mMetricIndexesWithActivation, newStateProtoHashes, mNoReportMetricIds);
+            mAllAnomalyTrackers, mAlertTrackerMap, mStateProtoHashes, mTagIds,
+            newAtomMatchingTrackers, newAtomMatchingTrackerMap, newConditionTrackers,
+            newConditionTrackerMap, newMetricProducers, newMetricProducerMap, newAnomalyTrackers,
+            newAlertTrackerMap, newPeriodicAlarmTrackers, mConditionToMetricMap,
+            mTrackerToMetricMap, mTrackerToConditionMap, mActivationAtomTrackerToMetricMap,
+            mDeactivationAtomTrackerToMetricMap, mMetricIndexesWithActivation, newStateProtoHashes,
+            mNoReportMetricIds);
     mAllAtomMatchingTrackers = newAtomMatchingTrackers;
     mAtomMatchingTrackerMap = newAtomMatchingTrackerMap;
     mAllConditionTrackers = newConditionTrackers;
@@ -233,6 +238,9 @@
     mAllMetricProducers = newMetricProducers;
     mMetricProducerMap = newMetricProducerMap;
     mStateProtoHashes = newStateProtoHashes;
+    mAllAnomalyTrackers = newAnomalyTrackers;
+    mAlertTrackerMap = newAlertTrackerMap;
+    mAllPeriodicAlarmTrackers = newPeriodicAlarmTrackers;
     return mConfigValid;
 }
 
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 657b2e4..cf1f437 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -71,7 +71,7 @@
                     sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
                     int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs,
                     int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
-                    const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
+                    const std::vector<sp<AnomalyTracker>>& anomalyTrackers)
         : mConfigKey(key),
           mTrackerId(id),
           mEventKey(eventKey),
@@ -93,6 +93,7 @@
         sp<ConditionWizard> tmpWizard = mWizard;
         mWizard = wizard;
         mConditionTrackerIndex = conditionTrackerIndex;
+        mAnomalyTrackers.clear();
     };
 
     virtual void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
@@ -120,7 +121,7 @@
             std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) = 0;
 
     // Predict the anomaly timestamp given the current status.
-    virtual int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
+    virtual int64_t predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
                                               const int64_t currentTimestamp) const = 0;
     // Dump internal states for debugging
     virtual void dumpStates(FILE* out, bool verbose) const = 0;
@@ -132,6 +133,10 @@
     // Replace old value with new value for the given state atom.
     virtual void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState) = 0;
 
+    void addAnomalyTracker(sp<AnomalyTracker>& anomalyTracker) {
+        mAnomalyTrackers.push_back(anomalyTracker);
+    }
+
 protected:
     int64_t getCurrentBucketEndTimeNs() const {
         return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
@@ -218,13 +223,14 @@
 
     bool mHasLinksToAllConditionDimensionsInTracker;
 
-    std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers;
+    std::vector<sp<AnomalyTracker>> mAnomalyTrackers;
 
     FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
     FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionExpiredAlarm);
     FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetectionFiredAlarm);
 
     FRIEND_TEST(ConfigUpdateTest, TestUpdateDurationMetrics);
+    FRIEND_TEST(ConfigUpdateTest, TestUpdateAlerts);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index ee4e167..62f4982 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -30,7 +30,7 @@
                                        int64_t currentBucketStartNs, int64_t currentBucketNum,
                                        int64_t startTimeNs, int64_t bucketSizeNs,
                                        bool conditionSliced, bool fullLink,
-                                       const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
+                                       const vector<sp<AnomalyTracker>>& anomalyTrackers)
     : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
                       currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink,
                       anomalyTrackers) {
@@ -288,7 +288,7 @@
     // Note that we don't update mDuration here since it's only updated during noteStop.
 }
 
-int64_t MaxDurationTracker::predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
+int64_t MaxDurationTracker::predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
                                                       const int64_t currentTimestamp) const {
     // The allowed time we can continue in the current state is the
     // (anomaly threshold) - max(elapsed time of the started mInfos).
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index 2891c6e..be2707c 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -29,12 +29,10 @@
 class MaxDurationTracker : public DurationTracker {
 public:
     MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
-                       sp<ConditionWizard> wizard, int conditionIndex,
-                       bool nesting,
-                       int64_t currentBucketStartNs, int64_t currentBucketNum,
-                       int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
-                       bool fullLink,
-                       const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
+                       sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
+                       int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs,
+                       int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
+                       const std::vector<sp<AnomalyTracker>>& anomalyTrackers);
 
     MaxDurationTracker(const MaxDurationTracker& tracker) = default;
 
@@ -57,7 +55,7 @@
     void onStateChanged(const int64_t timestamp, const int32_t atomId,
                         const FieldValue& newState) override;
 
-    int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
+    int64_t predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
                                       const int64_t currentTimestamp) const override;
     void dumpStates(FILE* out, bool verbose) const override;
 
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index 0d49bbc..247e2e0 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -28,7 +28,7 @@
         const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
         sp<ConditionWizard> wizard, int conditionIndex, bool nesting, int64_t currentBucketStartNs,
         int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
-        bool fullLink, const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
+        bool fullLink, const vector<sp<AnomalyTracker>>& anomalyTrackers)
     : DurationTracker(key, id, eventKey, wizard, conditionIndex, nesting, currentBucketStartNs,
                       currentBucketNum, startTimeNs, bucketSizeNs, conditionSliced, fullLink,
                       anomalyTrackers),
@@ -344,9 +344,8 @@
     updateCurrentStateKey(atomId, newState);
 }
 
-int64_t OringDurationTracker::predictAnomalyTimestampNs(
-        const DurationAnomalyTracker& anomalyTracker, const int64_t eventTimestampNs) const {
-
+int64_t OringDurationTracker::predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
+                                                        const int64_t eventTimestampNs) const {
     // The anomaly threshold.
     const int64_t thresholdNs = anomalyTracker.getAnomalyThreshold();
 
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index bd8017a..6eddee7 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -31,7 +31,7 @@
                          int conditionIndex, bool nesting, int64_t currentBucketStartNs,
                          int64_t currentBucketNum, int64_t startTimeNs, int64_t bucketSizeNs,
                          bool conditionSliced, bool fullLink,
-                         const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
+                         const std::vector<sp<AnomalyTracker>>& anomalyTrackers);
 
     OringDurationTracker(const OringDurationTracker& tracker) = default;
 
@@ -54,7 +54,7 @@
             int64_t timestampNs,
             std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
 
-    int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
+    int64_t predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
                                       const int64_t currentTimestamp) const override;
     void dumpStates(FILE* out, bool verbose) const override;
 
diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
index 335f775..6372361 100644
--- a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
+++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp
@@ -115,7 +115,6 @@
                                 vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
                                 set<int64_t>& replacedMatchers) {
     const int atomMatcherCount = config.atom_matcher_size();
-
     vector<AtomMatcher> matcherProtos;
     matcherProtos.reserve(atomMatcherCount);
     newAtomMatchingTrackers.reserve(atomMatcherCount);
@@ -891,6 +890,111 @@
     return true;
 }
 
+bool determineAlertUpdateStatus(const Alert& alert,
+                                const unordered_map<int64_t, int>& oldAlertTrackerMap,
+                                const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
+                                const set<int64_t>& replacedMetrics, UpdateStatus& updateStatus) {
+    // Check if new alert.
+    const auto& oldAnomalyTrackerIt = oldAlertTrackerMap.find(alert.id());
+    if (oldAnomalyTrackerIt == oldAlertTrackerMap.end()) {
+        updateStatus = UPDATE_NEW;
+        return true;
+    }
+
+    // This is an existing alert, check if it has changed.
+    string serializedAlert;
+    if (!alert.SerializeToString(&serializedAlert)) {
+        ALOGW("Unable to serialize alert %lld", (long long)alert.id());
+        return false;
+    }
+    uint64_t newProtoHash = Hash64(serializedAlert);
+    const auto [success, oldProtoHash] =
+            oldAnomalyTrackers[oldAnomalyTrackerIt->second]->getProtoHash();
+    if (!success) {
+        return false;
+    }
+    if (newProtoHash != oldProtoHash) {
+        updateStatus = UPDATE_REPLACE;
+        return true;
+    }
+
+    // Check if the metric this alert relies on has changed.
+    if (replacedMetrics.find(alert.metric_id()) != replacedMetrics.end()) {
+        updateStatus = UPDATE_REPLACE;
+        return true;
+    }
+
+    updateStatus = UPDATE_PRESERVE;
+    return true;
+}
+
+bool updateAlerts(const StatsdConfig& config, const unordered_map<int64_t, int>& metricProducerMap,
+                  const set<int64_t>& replacedMetrics,
+                  const unordered_map<int64_t, int>& oldAlertTrackerMap,
+                  const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
+                  const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                  vector<sp<MetricProducer>>& allMetricProducers,
+                  unordered_map<int64_t, int>& newAlertTrackerMap,
+                  vector<sp<AnomalyTracker>>& newAnomalyTrackers) {
+    int alertCount = config.alert_size();
+    vector<UpdateStatus> alertUpdateStatuses(alertCount);
+    for (int i = 0; i < alertCount; i++) {
+        if (!determineAlertUpdateStatus(config.alert(i), oldAlertTrackerMap, oldAnomalyTrackers,
+                                        replacedMetrics, alertUpdateStatuses[i])) {
+            return false;
+        }
+    }
+
+    for (int i = 0; i < alertCount; i++) {
+        const Alert& alert = config.alert(i);
+        newAlertTrackerMap[alert.id()] = newAnomalyTrackers.size();
+        switch (alertUpdateStatuses[i]) {
+            case UPDATE_PRESERVE: {
+                // Find the alert and update it.
+                const auto& oldAnomalyTrackerIt = oldAlertTrackerMap.find(alert.id());
+                if (oldAnomalyTrackerIt == oldAlertTrackerMap.end()) {
+                    ALOGW("Could not find AnomalyTracker %lld in the previous config, but "
+                          "expected it to be there",
+                          (long long)alert.id());
+                    return false;
+                }
+                sp<AnomalyTracker> anomalyTracker = oldAnomalyTrackers[oldAnomalyTrackerIt->second];
+                anomalyTracker->onConfigUpdated();
+                // Add the alert to the relevant metric.
+                const auto& metricProducerIt = metricProducerMap.find(alert.metric_id());
+                if (metricProducerIt == metricProducerMap.end()) {
+                    ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
+                          (long long)alert.metric_id());
+                    return false;
+                }
+                allMetricProducers[metricProducerIt->second]->addAnomalyTracker(anomalyTracker);
+                newAnomalyTrackers.push_back(anomalyTracker);
+                break;
+            }
+            case UPDATE_REPLACE:
+            case UPDATE_NEW: {
+                optional<sp<AnomalyTracker>> anomalyTracker = createAnomalyTracker(
+                        alert, anomalyAlarmMonitor, metricProducerMap, allMetricProducers);
+                if (!anomalyTracker) {
+                    return false;
+                }
+                newAnomalyTrackers.push_back(anomalyTracker.value());
+                break;
+            }
+            default: {
+                ALOGE("Alert \"%lld\" update state is unknown. This should never happen",
+                      (long long)alert.id());
+                return false;
+            }
+        }
+    }
+    if (!initSubscribersForSubscriptionType(config, Subscription::ALERT, newAlertTrackerMap,
+                                            newAnomalyTrackers)) {
+        return false;
+    }
+    return true;
+}
+
 bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
                         const sp<StatsPullerManager>& pullerManager,
                         const sp<AlarmMonitor>& anomalyAlarmMonitor,
@@ -902,6 +1006,8 @@
                         const unordered_map<int64_t, int>& oldConditionTrackerMap,
                         const vector<sp<MetricProducer>>& oldMetricProducers,
                         const unordered_map<int64_t, int>& oldMetricProducerMap,
+                        const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
+                        const unordered_map<int64_t, int>& oldAlertTrackerMap,
                         const map<int64_t, uint64_t>& oldStateProtoHashes, set<int>& allTagIds,
                         vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
                         unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
@@ -909,6 +1015,9 @@
                         unordered_map<int64_t, int>& newConditionTrackerMap,
                         vector<sp<MetricProducer>>& newMetricProducers,
                         unordered_map<int64_t, int>& newMetricProducerMap,
+                        vector<sp<AnomalyTracker>>& newAnomalyTrackers,
+                        unordered_map<int64_t, int>& newAlertTrackerMap,
+                        vector<sp<AlarmTracker>>& newPeriodicAlarmTrackers,
                         unordered_map<int, vector<int>>& conditionToMetricMap,
                         unordered_map<int, vector<int>>& trackerToMetricMap,
                         unordered_map<int, vector<int>>& trackerToConditionMap,
@@ -962,10 +1071,23 @@
                        newMetricProducerMap, newMetricProducers, conditionToMetricMap,
                        trackerToMetricMap, noReportMetricIds, activationTrackerToMetricMap,
                        deactivationTrackerToMetricMap, metricsWithActivation, replacedMetrics)) {
-        ALOGE("initMetricProducers failed");
+        ALOGE("updateMetrics failed");
         return false;
     }
 
+    if (!updateAlerts(config, newMetricProducerMap, replacedMetrics, oldAlertTrackerMap,
+                      oldAnomalyTrackers, anomalyAlarmMonitor, newMetricProducers,
+                      newAlertTrackerMap, newAnomalyTrackers)) {
+        ALOGE("updateAlerts failed");
+        return false;
+    }
+
+    // Alarms do not have any state, so we can reuse the initialization logic.
+    if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
+                    newPeriodicAlarmTrackers)) {
+        ALOGE("initAlarms failed");
+        return false;
+    }
     return true;
 }
 
diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h
index 3f1c532..178a9d2 100644
--- a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h
+++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.h
@@ -19,6 +19,7 @@
 #include <vector>
 
 #include "anomaly/AlarmMonitor.h"
+#include "anomaly/AlarmTracker.h"
 #include "condition/ConditionTracker.h"
 #include "external/StatsPullerManager.h"
 #include "matchers/AtomMatchingTracker.h"
@@ -189,6 +190,45 @@
         std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
         std::vector<int>& metricsWithActivation, std::set<int64_t>& replacedMetrics);
 
+// Function to determine the update status (preserve/replace/new) of an alert.
+// [alert]: the input Alert
+// [oldAlertTrackerMap]: alert id to index mapping in the existing MetricsManager
+// [oldAnomalyTrackers]: stores the existing AnomalyTrackers
+// [replacedMetrics]: set of replaced metric ids. alerts using these metrics must be replaced
+// output:
+// [updateStatus]: update status of the alert. Will be changed from UPDATE_UNKNOWN
+// Returns whether the function was successful or not.
+bool determineAlertUpdateStatus(const Alert& alert,
+                                const std::unordered_map<int64_t, int>& oldAlertTrackerMap,
+                                const std::vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
+                                const std::set<int64_t>& replacedMetrics,
+                                UpdateStatus& updateStatus);
+
+// Update MetricProducers.
+// input:
+// [config]: the input config
+// [metricProducerMap]: metric id to index mapping in the new config
+// [replacedMetrics]: set of metric ids that have changed and were replaced
+// [oldAlertTrackerMap]: alert id to index mapping in the existing MetricsManager.
+// [oldAnomalyTrackers]: stores the existing AnomalyTrackers
+// [anomalyAlarmMonitor]: AlarmMonitor used for duration metric anomaly detection
+// [allMetricProducers]: stores the sp of the metric producers, AnomalyTrackers need to be added.
+// [stateAtomIdMap]: contains the mapping from state ids to atom ids
+// [allStateGroupMaps]: contains the mapping from atom ids and state values to
+//                      state group ids for all states
+// output:
+// [newAlertTrackerMap]: mapping of alert id to index in the new config
+// [newAnomalyTrackers]: contains the list of sp to the AnomalyTrackers created.
+bool updateAlerts(const StatsdConfig& config,
+                  const std::unordered_map<int64_t, int>& metricProducerMap,
+                  const std::set<int64_t>& replacedMetrics,
+                  const std::unordered_map<int64_t, int>& oldAlertTrackerMap,
+                  const std::vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
+                  const sp<AlarmMonitor>& anomalyAlarmMonitor,
+                  std::vector<sp<MetricProducer>>& allMetricProducers,
+                  std::unordered_map<int64_t, int>& newAlertTrackerMap,
+                  std::vector<sp<AnomalyTracker>>& newAnomalyTrackers);
+
 // Updates the existing MetricsManager from a new StatsdConfig.
 // Parameters are the members of MetricsManager. See MetricsManager for declaration.
 bool updateStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
@@ -202,6 +242,8 @@
                         const std::unordered_map<int64_t, int>& oldConditionTrackerMap,
                         const std::vector<sp<MetricProducer>>& oldMetricProducers,
                         const std::unordered_map<int64_t, int>& oldMetricProducerMap,
+                        const std::vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
+                        const std::unordered_map<int64_t, int>& oldAlertTrackerMap,
                         const std::map<int64_t, uint64_t>& oldStateProtoHashes,
                         std::set<int>& allTagIds,
                         std::vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
@@ -210,6 +252,9 @@
                         std::unordered_map<int64_t, int>& newConditionTrackerMap,
                         std::vector<sp<MetricProducer>>& newMetricProducers,
                         std::unordered_map<int64_t, int>& newMetricProducerMap,
+                        std::vector<sp<AnomalyTracker>>& newAlertTrackers,
+                        std::unordered_map<int64_t, int>& newAlertTrackerMap,
+                        std::vector<sp<AlarmTracker>>& newPeriodicAlarmTrackers,
                         std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
                         std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
                         std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
diff --git a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
index 8fc039a..4474df4 100644
--- a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
@@ -814,6 +814,35 @@
                                     pullerManager, eventActivationMap, eventDeactivationMap)};
 }
 
+optional<sp<AnomalyTracker>> createAnomalyTracker(
+        const Alert& alert, const sp<AlarmMonitor>& anomalyAlarmMonitor,
+        const unordered_map<int64_t, int>& metricProducerMap,
+        vector<sp<MetricProducer>>& allMetricProducers) {
+    const auto& itr = metricProducerMap.find(alert.metric_id());
+    if (itr == metricProducerMap.end()) {
+        ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
+              (long long)alert.metric_id());
+        return nullopt;
+    }
+    if (!alert.has_trigger_if_sum_gt()) {
+        ALOGW("invalid alert: missing threshold");
+        return nullopt;
+    }
+    if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
+        ALOGW("invalid alert: threshold=%f num_buckets= %d", alert.trigger_if_sum_gt(),
+              alert.num_buckets());
+        return nullopt;
+    }
+    const int metricIndex = itr->second;
+    sp<MetricProducer> metric = allMetricProducers[metricIndex];
+    sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert, anomalyAlarmMonitor);
+    if (anomalyTracker == nullptr) {
+        // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
+        return nullopt;
+    }
+    return {anomalyTracker};
+}
+
 bool initAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
                               unordered_map<int64_t, int>& atomMatchingTrackerMap,
                               vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
@@ -1079,49 +1108,17 @@
                 vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
     for (int i = 0; i < config.alert_size(); i++) {
         const Alert& alert = config.alert(i);
-        const auto& itr = metricProducerMap.find(alert.metric_id());
-        if (itr == metricProducerMap.end()) {
-            ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
-                  (long long)alert.metric_id());
-            return false;
-        }
-        if (!alert.has_trigger_if_sum_gt()) {
-            ALOGW("invalid alert: missing threshold");
-            return false;
-        }
-        if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
-            ALOGW("invalid alert: threshold=%f num_buckets= %d", alert.trigger_if_sum_gt(),
-                  alert.num_buckets());
-            return false;
-        }
-        const int metricIndex = itr->second;
-        sp<MetricProducer> metric = allMetricProducers[metricIndex];
-        sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert, anomalyAlarmMonitor);
-        if (anomalyTracker == nullptr) {
-            // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
-            return false;
-        }
         alertTrackerMap.insert(std::make_pair(alert.id(), allAnomalyTrackers.size()));
-        allAnomalyTrackers.push_back(anomalyTracker);
+        optional<sp<AnomalyTracker>> anomalyTracker = createAnomalyTracker(
+                alert, anomalyAlarmMonitor, metricProducerMap, allMetricProducers);
+        if (!anomalyTracker) {
+            return false;
+        }
+        allAnomalyTrackers.push_back(anomalyTracker.value());
     }
-    for (int i = 0; i < config.subscription_size(); ++i) {
-        const Subscription& subscription = config.subscription(i);
-        if (subscription.rule_type() != Subscription::ALERT) {
-            continue;
-        }
-        if (subscription.subscriber_information_case() ==
-            Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
-            ALOGW("subscription \"%lld\" has no subscriber info.\"", (long long)subscription.id());
-            return false;
-        }
-        const auto& itr = alertTrackerMap.find(subscription.rule_id());
-        if (itr == alertTrackerMap.end()) {
-            ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
-                  (long long)subscription.id(), (long long)subscription.rule_id());
-            return false;
-        }
-        const int anomalyTrackerIndex = itr->second;
-        allAnomalyTrackers[anomalyTrackerIndex]->addSubscription(subscription);
+    if (!initSubscribersForSubscriptionType(config, Subscription::ALERT, alertTrackerMap,
+                                            allAnomalyTrackers)) {
+        return false;
     }
     return true;
 }
@@ -1146,24 +1143,9 @@
         allAlarmTrackers.push_back(
                 new AlarmTracker(startMillis, currentTimeMillis, alarm, key, periodicAlarmMonitor));
     }
-    for (int i = 0; i < config.subscription_size(); ++i) {
-        const Subscription& subscription = config.subscription(i);
-        if (subscription.rule_type() != Subscription::ALARM) {
-            continue;
-        }
-        if (subscription.subscriber_information_case() ==
-            Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
-            ALOGW("subscription \"%lld\" has no subscriber info.\"", (long long)subscription.id());
-            return false;
-        }
-        const auto& itr = alarmTrackerMap.find(subscription.rule_id());
-        if (itr == alarmTrackerMap.end()) {
-            ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
-                  (long long)subscription.id(), (long long)subscription.rule_id());
-            return false;
-        }
-        const int trackerIndex = itr->second;
-        allAlarmTrackers[trackerIndex]->addSubscription(subscription);
+    if (!initSubscribersForSubscriptionType(config, Subscription::ALARM, alarmTrackerMap,
+                                            allAlarmTrackers)) {
+        return false;
     }
     return true;
 }
diff --git a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h
index e4585cd..84e1e4e 100644
--- a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h
@@ -188,6 +188,41 @@
         std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
         std::vector<int>& metricsWithActivation);
 
+// Creates an AnomalyTracker and adds it to the appropriate metric.
+// Returns an sp to the AnomalyTracker, or nullopt if there was an error.
+optional<sp<AnomalyTracker>> createAnomalyTracker(
+        const Alert& alert, const sp<AlarmMonitor>& anomalyAlarmMonitor,
+        const std::unordered_map<int64_t, int>& metricProducerMap,
+        std::vector<sp<MetricProducer>>& allMetricProducers);
+
+// Templated function for adding subscriptions to alarms or alerts. Returns true if successful.
+template <typename T>
+bool initSubscribersForSubscriptionType(const StatsdConfig& config,
+                                        const Subscription_RuleType ruleType,
+                                        const std::unordered_map<int64_t, int>& ruleMap,
+                                        std::vector<T>& allRules) {
+    for (int i = 0; i < config.subscription_size(); ++i) {
+        const Subscription& subscription = config.subscription(i);
+        if (subscription.rule_type() != ruleType) {
+            continue;
+        }
+        if (subscription.subscriber_information_case() ==
+            Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
+            ALOGW("subscription \"%lld\" has no subscriber info.\"", (long long)subscription.id());
+            return false;
+        }
+        const auto& itr = ruleMap.find(subscription.rule_id());
+        if (itr == ruleMap.end()) {
+            ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
+                  (long long)subscription.id(), (long long)subscription.rule_id());
+            return false;
+        }
+        const int ruleIndex = itr->second;
+        allRules[ruleIndex]->addSubscription(subscription);
+    }
+    return true;
+}
+
 // Helper functions for MetricsManager to initialize from StatsdConfig.
 // *Note*: only initStatsdConfig() should be called from outside.
 // All other functions are intermediate
@@ -271,6 +306,12 @@
         std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
         std::vector<int>& metricsWithActivation);
 
+// Initialize alarms
+// Is called both on initialize new configs and config updates since alarms do not have any state.
+bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
+                const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
+                const int64_t currentTimeNs, std::vector<sp<AlarmTracker>>& allAlarmTrackers);
+
 // Initialize MetricsManager from StatsdConfig.
 // Parameters are the members of MetricsManager. See MetricsManager for declaration.
 bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
diff --git a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
index 4fa9bf6..66bab4e 100644
--- a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
+++ b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
@@ -52,11 +52,15 @@
 namespace {
 
 ConfigKey key(123, 456);
-const int64_t timeBaseNs = 1000;
+const int64_t timeBaseNs = 1000 * NS_PER_SEC;
+
 sp<UidMap> uidMap = new UidMap();
 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
 sp<AlarmMonitor> anomalyAlarmMonitor;
-sp<AlarmMonitor> periodicAlarmMonitor;
+sp<AlarmMonitor> periodicAlarmMonitor = new AlarmMonitor(
+        /*minDiffToUpdateRegisteredAlarmTimeSec=*/0,
+        [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
+        [](const shared_ptr<IStatsCompanionService>&) {});
 set<int> allTagIds;
 vector<sp<AtomMatchingTracker>> oldAtomMatchingTrackers;
 unordered_map<int64_t, int> oldAtomMatchingTrackerMap;
@@ -65,13 +69,13 @@
 vector<sp<MetricProducer>> oldMetricProducers;
 unordered_map<int64_t, int> oldMetricProducerMap;
 std::vector<sp<AnomalyTracker>> oldAnomalyTrackers;
+unordered_map<int64_t, int> oldAlertTrackerMap;
 std::vector<sp<AlarmTracker>> oldAlarmTrackers;
 unordered_map<int, std::vector<int>> tmpConditionToMetricMap;
 unordered_map<int, std::vector<int>> tmpTrackerToMetricMap;
 unordered_map<int, std::vector<int>> tmpTrackerToConditionMap;
 unordered_map<int, std::vector<int>> tmpActivationAtomTrackerToMetricMap;
 unordered_map<int, std::vector<int>> tmpDeactivationAtomTrackerToMetricMap;
-unordered_map<int64_t, int> alertTrackerMap;
 vector<int> metricsWithActivation;
 map<int64_t, uint64_t> oldStateHashes;
 std::set<int64_t> noReportMetricIds;
@@ -96,7 +100,7 @@
         tmpTrackerToConditionMap.clear();
         tmpActivationAtomTrackerToMetricMap.clear();
         tmpDeactivationAtomTrackerToMetricMap.clear();
-        alertTrackerMap.clear();
+        oldAlertTrackerMap.clear();
         metricsWithActivation.clear();
         oldStateHashes.clear();
         noReportMetricIds.clear();
@@ -111,7 +115,7 @@
             oldConditionTrackers, oldConditionTrackerMap, oldMetricProducers, oldMetricProducerMap,
             oldAnomalyTrackers, oldAlarmTrackers, tmpConditionToMetricMap, tmpTrackerToMetricMap,
             tmpTrackerToConditionMap, tmpActivationAtomTrackerToMetricMap,
-            tmpDeactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
+            tmpDeactivationAtomTrackerToMetricMap, oldAlertTrackerMap, metricsWithActivation,
             oldStateHashes, noReportMetricIds);
 }
 
@@ -188,6 +192,32 @@
     }
     return metric;
 }
+
+Alert createAlert(string name, int64_t metricId, int buckets, int64_t triggerSum) {
+    Alert alert;
+    alert.set_id(StringToId(name));
+    alert.set_metric_id(metricId);
+    alert.set_num_buckets(buckets);
+    alert.set_trigger_if_sum_gt(triggerSum);
+    return alert;
+}
+
+Subscription createSubscription(string name, Subscription_RuleType type, int64_t ruleId) {
+    Subscription subscription;
+    subscription.set_id(StringToId(name));
+    subscription.set_rule_type(type);
+    subscription.set_rule_id(ruleId);
+    subscription.mutable_broadcast_subscriber_details();
+    return subscription;
+}
+
+Alarm createAlarm(string name, int64_t offsetMillis, int64_t periodMillis) {
+    Alarm alarm;
+    alarm.set_id(StringToId(name));
+    alarm.set_offset_millis(offsetMillis);
+    alarm.set_period_millis(periodMillis);
+    return alarm;
+}
 }  // anonymous namespace
 
 TEST_F(ConfigUpdateTest, TestSimpleMatcherPreserve) {
@@ -3243,6 +3273,305 @@
     // Only reference to the old wizard should be the one in the test.
     EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
 }
+
+TEST_F(ConfigUpdateTest, TestAlertPreserve) {
+    StatsdConfig config;
+    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
+    *config.add_atom_matcher() = whatMatcher;
+
+    *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
+
+    Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
+    *config.add_alert() = alert;
+    EXPECT_TRUE(initConfig(config));
+
+    UpdateStatus updateStatus = UPDATE_UNKNOWN;
+    EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
+                                           /*replacedMetrics*/ {}, updateStatus));
+    EXPECT_EQ(updateStatus, UPDATE_PRESERVE);
+}
+
+TEST_F(ConfigUpdateTest, TestAlertMetricChanged) {
+    StatsdConfig config;
+    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
+    *config.add_atom_matcher() = whatMatcher;
+
+    CountMetric metric = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
+    *config.add_count_metric() = metric;
+
+    Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
+    *config.add_alert() = alert;
+    EXPECT_TRUE(initConfig(config));
+
+    UpdateStatus updateStatus = UPDATE_UNKNOWN;
+    EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
+                                           /*replacedMetrics*/ {metric.id()}, updateStatus));
+    EXPECT_EQ(updateStatus, UPDATE_REPLACE);
+}
+
+TEST_F(ConfigUpdateTest, TestAlertDefinitionChanged) {
+    StatsdConfig config;
+    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
+    *config.add_atom_matcher() = whatMatcher;
+
+    *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
+
+    Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
+    *config.add_alert() = alert;
+    EXPECT_TRUE(initConfig(config));
+
+    alert.set_num_buckets(2);
+
+    UpdateStatus updateStatus = UPDATE_UNKNOWN;
+    EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
+                                           /*replacedMetrics*/ {}, updateStatus));
+    EXPECT_EQ(updateStatus, UPDATE_REPLACE);
+}
+
+TEST_F(ConfigUpdateTest, TestUpdateAlerts) {
+    StatsdConfig config;
+    // Add atom matchers/predicates/metrics. These are mostly needed for initStatsdConfig
+    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
+    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
+    *config.add_predicate() = CreateScreenIsOnPredicate();
+
+    CountMetric countMetric = createCountMetric("COUNT1", config.atom_matcher(0).id(), nullopt, {});
+    int64_t countMetricId = countMetric.id();
+    *config.add_count_metric() = countMetric;
+
+    DurationMetric durationMetric =
+            createDurationMetric("DURATION1", config.predicate(0).id(), nullopt, {});
+    int64_t durationMetricId = durationMetric.id();
+    *config.add_duration_metric() = durationMetric;
+
+    // Add alerts.
+    // Preserved.
+    Alert alert1 = createAlert("Alert1", durationMetricId, /*buckets*/ 1, /*triggerSum*/ 5000);
+    int64_t alert1Id = alert1.id();
+    *config.add_alert() = alert1;
+
+    // Replaced.
+    Alert alert2 = createAlert("Alert2", countMetricId, /*buckets*/ 1, /*triggerSum*/ 2);
+    int64_t alert2Id = alert2.id();
+    *config.add_alert() = alert2;
+
+    // Replaced.
+    Alert alert3 = createAlert("Alert3", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 5000);
+    int64_t alert3Id = alert3.id();
+    *config.add_alert() = alert3;
+
+    // Add Subscriptions.
+    Subscription subscription1 = createSubscription("S1", Subscription::ALERT, alert1Id);
+    *config.add_subscription() = subscription1;
+    Subscription subscription2 = createSubscription("S2", Subscription::ALERT, alert1Id);
+    *config.add_subscription() = subscription2;
+    Subscription subscription3 = createSubscription("S3", Subscription::ALERT, alert2Id);
+    *config.add_subscription() = subscription3;
+
+    EXPECT_TRUE(initConfig(config));
+
+    // Add a duration tracker to the duration metric to ensure durationTrackers are updated
+    // with the proper anomalyTrackers.
+    unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
+            timeBaseNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
+    oldMetricProducers[1]->onMatchedLogEvent(0, *event.get());
+
+    // Change the count metric. Causes alert2 to be replaced.
+    config.mutable_count_metric(0)->set_bucket(ONE_DAY);
+    // Change num buckets on alert3, causing replacement.
+    alert3.set_num_buckets(5);
+
+    // New alert.
+    Alert alert4 = createAlert("Alert4", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 10000);
+    int64_t alert4Id = alert4.id();
+
+    // Move subscription2 to be on alert2 and make a new subscription.
+    subscription2.set_rule_id(alert2Id);
+    Subscription subscription4 = createSubscription("S4", Subscription::ALERT, alert2Id);
+
+    // Create the new config. Modify the old one to avoid adding the matchers/predicates.
+    // Add alerts in different order so the map is changed.
+    config.clear_alert();
+    *config.add_alert() = alert4;
+    const int alert4Index = 0;
+    *config.add_alert() = alert3;
+    const int alert3Index = 1;
+    *config.add_alert() = alert1;
+    const int alert1Index = 2;
+    *config.add_alert() = alert2;
+    const int alert2Index = 3;
+
+    // Subscription3 is removed.
+    config.clear_subscription();
+    *config.add_subscription() = subscription4;
+    *config.add_subscription() = subscription2;
+    *config.add_subscription() = subscription1;
+
+    // Output data structures from update metrics. Don't care about the outputs besides
+    // replacedMetrics, but need to do this so that the metrics clear their anomaly trackers.
+    unordered_map<int64_t, int> newMetricProducerMap;
+    vector<sp<MetricProducer>> newMetricProducers;
+    unordered_map<int, vector<int>> conditionToMetricMap;
+    unordered_map<int, vector<int>> trackerToMetricMap;
+    set<int64_t> noReportMetricIds;
+    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
+    vector<int> metricsWithActivation;
+    set<int64_t> replacedMetrics;
+    EXPECT_TRUE(updateMetrics(
+            key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
+            oldAtomMatchingTrackerMap, oldAtomMatchingTrackerMap, /*replacedMatchers*/ {},
+            oldAtomMatchingTrackers, oldConditionTrackerMap, /*replacedConditions=*/{},
+            oldConditionTrackers, {ConditionState::kUnknown}, /*stateAtomIdMap*/ {},
+            /*allStateGroupMaps=*/{},
+            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
+            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
+            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+            metricsWithActivation, replacedMetrics));
+
+    EXPECT_EQ(replacedMetrics, set<int64_t>({countMetricId}));
+
+    unordered_map<int64_t, int> newAlertTrackerMap;
+    vector<sp<AnomalyTracker>> newAnomalyTrackers;
+    EXPECT_TRUE(updateAlerts(config, newMetricProducerMap, replacedMetrics, oldAlertTrackerMap,
+                             oldAnomalyTrackers, anomalyAlarmMonitor, newMetricProducers,
+                             newAlertTrackerMap, newAnomalyTrackers));
+
+    unordered_map<int64_t, int> expectedAlertMap = {
+            {alert1Id, alert1Index},
+            {alert2Id, alert2Index},
+            {alert3Id, alert3Index},
+            {alert4Id, alert4Index},
+    };
+    EXPECT_THAT(newAlertTrackerMap, ContainerEq(expectedAlertMap));
+
+    // Make sure preserved alerts are the same.
+    ASSERT_EQ(newAnomalyTrackers.size(), 4);
+    EXPECT_EQ(oldAnomalyTrackers[oldAlertTrackerMap.at(alert1Id)],
+              newAnomalyTrackers[newAlertTrackerMap.at(alert1Id)]);
+
+    // Make sure replaced alerts are different.
+    EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert2Id)],
+              newAnomalyTrackers[newAlertTrackerMap.at(alert2Id)]);
+    EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert3Id)],
+              newAnomalyTrackers[newAlertTrackerMap.at(alert3Id)]);
+
+    // Verify the alerts have the correct anomaly trackers.
+    ASSERT_EQ(newMetricProducers.size(), 2);
+    EXPECT_THAT(newMetricProducers[0]->mAnomalyTrackers,
+                UnorderedElementsAre(newAnomalyTrackers[alert2Index]));
+    // For durationMetric, make sure the duration trackers get the updated anomalyTrackers.
+    DurationMetricProducer* durationProducer =
+            static_cast<DurationMetricProducer*>(newMetricProducers[1].get());
+    EXPECT_THAT(
+            durationProducer->mAnomalyTrackers,
+            UnorderedElementsAre(newAnomalyTrackers[alert1Index], newAnomalyTrackers[alert3Index],
+                                 newAnomalyTrackers[alert4Index]));
+    ASSERT_EQ(durationProducer->mCurrentSlicedDurationTrackerMap.size(), 1);
+    for (const auto& durationTrackerIt : durationProducer->mCurrentSlicedDurationTrackerMap) {
+        EXPECT_EQ(durationTrackerIt.second->mAnomalyTrackers, durationProducer->mAnomalyTrackers);
+    }
+
+    // Verify alerts have the correct subscriptions. Use subscription id as proxy for equivalency.
+    vector<int64_t> alert1Subscriptions;
+    for (const Subscription& subscription : newAnomalyTrackers[alert1Index]->mSubscriptions) {
+        alert1Subscriptions.push_back(subscription.id());
+    }
+    EXPECT_THAT(alert1Subscriptions, UnorderedElementsAre(subscription1.id()));
+    vector<int64_t> alert2Subscriptions;
+    for (const Subscription& subscription : newAnomalyTrackers[alert2Index]->mSubscriptions) {
+        alert2Subscriptions.push_back(subscription.id());
+    }
+    EXPECT_THAT(alert2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription4.id()));
+    EXPECT_THAT(newAnomalyTrackers[alert3Index]->mSubscriptions, IsEmpty());
+    EXPECT_THAT(newAnomalyTrackers[alert4Index]->mSubscriptions, IsEmpty());
+}
+
+TEST_F(ConfigUpdateTest, TestUpdateAlarms) {
+    StatsdConfig config;
+    // Add alarms.
+    Alarm alarm1 = createAlarm("Alarm1", /*offset*/ 1 * MS_PER_SEC, /*period*/ 50 * MS_PER_SEC);
+    int64_t alarm1Id = alarm1.id();
+    *config.add_alarm() = alarm1;
+
+    Alarm alarm2 = createAlarm("Alarm2", /*offset*/ 1 * MS_PER_SEC, /*period*/ 2000 * MS_PER_SEC);
+    int64_t alarm2Id = alarm2.id();
+    *config.add_alarm() = alarm2;
+
+    Alarm alarm3 = createAlarm("Alarm3", /*offset*/ 10 * MS_PER_SEC, /*period*/ 5000 * MS_PER_SEC);
+    int64_t alarm3Id = alarm3.id();
+    *config.add_alarm() = alarm3;
+
+    // Add Subscriptions.
+    Subscription subscription1 = createSubscription("S1", Subscription::ALARM, alarm1Id);
+    *config.add_subscription() = subscription1;
+    Subscription subscription2 = createSubscription("S2", Subscription::ALARM, alarm1Id);
+    *config.add_subscription() = subscription2;
+    Subscription subscription3 = createSubscription("S3", Subscription::ALARM, alarm2Id);
+    *config.add_subscription() = subscription3;
+
+    EXPECT_TRUE(initConfig(config));
+
+    ASSERT_EQ(oldAlarmTrackers.size(), 3);
+    // Config is created at statsd start time, so just add the offsets.
+    EXPECT_EQ(oldAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
+    EXPECT_EQ(oldAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
+    EXPECT_EQ(oldAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);
+
+    // Change alarm2/alarm3.
+    config.mutable_alarm(1)->set_offset_millis(5 * MS_PER_SEC);
+    config.mutable_alarm(2)->set_period_millis(10000 * MS_PER_SEC);
+
+    // Move subscription2 to be on alarm2 and make a new subscription.
+    config.mutable_subscription(1)->set_rule_id(alarm2Id);
+    Subscription subscription4 = createSubscription("S4", Subscription::ALARM, alarm1Id);
+    *config.add_subscription() = subscription4;
+
+    // Update time is 2 seconds after the base time.
+    int64_t currentTimeNs = timeBaseNs + 2 * NS_PER_SEC;
+    vector<sp<AlarmTracker>> newAlarmTrackers;
+    EXPECT_TRUE(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
+                           newAlarmTrackers));
+
+    ASSERT_EQ(newAlarmTrackers.size(), 3);
+    // Config is updated 2 seconds after statsd start
+    // The offset has passed for alarm1, but not for alarms 2/3.
+    EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 50);
+    EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5);
+    EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);
+
+    // Verify alarms have the correct subscriptions. Use subscription id as proxy for equivalency.
+    vector<int64_t> alarm1Subscriptions;
+    for (const Subscription& subscription : newAlarmTrackers[0]->mSubscriptions) {
+        alarm1Subscriptions.push_back(subscription.id());
+    }
+    EXPECT_THAT(alarm1Subscriptions, UnorderedElementsAre(subscription1.id(), subscription4.id()));
+    vector<int64_t> alarm2Subscriptions;
+    for (const Subscription& subscription : newAlarmTrackers[1]->mSubscriptions) {
+        alarm2Subscriptions.push_back(subscription.id());
+    }
+    EXPECT_THAT(alarm2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription3.id()));
+    EXPECT_THAT(newAlarmTrackers[2]->mSubscriptions, IsEmpty());
+
+    // Verify the alarm monitor is updated accordingly once the old alarms are removed.
+    // Alarm2 fires the earliest.
+    oldAlarmTrackers.clear();
+    EXPECT_EQ(periodicAlarmMonitor->getRegisteredAlarmTimeSec(), timeBaseNs / NS_PER_SEC + 5);
+
+    // Do another update 60 seconds after config creation time, after the offsets of each alarm.
+    currentTimeNs = timeBaseNs + 60 * NS_PER_SEC;
+    newAlarmTrackers.clear();
+    EXPECT_TRUE(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
+                           newAlarmTrackers));
+
+    ASSERT_EQ(newAlarmTrackers.size(), 3);
+    // Config is updated one minute after statsd start.
+    // Two periods have passed for alarm 1, one has passed for alarms2/3.
+    EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 2 * 50);
+    EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5 + 2000);
+    EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10 + 10000);
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
index 0d0a896..9e2350b 100644
--- a/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
+++ b/cmds/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
@@ -27,6 +27,7 @@
 #include "src/condition/ConditionTracker.h"
 #include "src/matchers/AtomMatchingTracker.h"
 #include "src/metrics/CountMetricProducer.h"
+#include "src/metrics/DurationMetricProducer.h"
 #include "src/metrics/GaugeMetricProducer.h"
 #include "src/metrics/MetricProducer.h"
 #include "src/metrics/ValueMetricProducer.h"
@@ -793,6 +794,93 @@
     EXPECT_FALSE(tracker->IsSimpleCondition());
 }
 
+TEST(MetricsManagerTest, TestCreateAnomalyTrackerInvalidMetric) {
+    Alert alert;
+    alert.set_id(123);
+    alert.set_metric_id(1);
+    alert.set_trigger_if_sum_gt(1);
+    alert.set_num_buckets(1);
+
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    vector<sp<MetricProducer>> metricProducers;
+    // Pass in empty metric producers, causing an error.
+    EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, {}, metricProducers), nullopt);
+}
+
+TEST(MetricsManagerTest, TestCreateAnomalyTrackerNoThreshold) {
+    int64_t metricId = 1;
+    Alert alert;
+    alert.set_id(123);
+    alert.set_metric_id(metricId);
+    alert.set_num_buckets(1);
+
+    CountMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
+            kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, {{1, 0}}, metricProducers), nullopt);
+}
+
+TEST(MetricsManagerTest, TestCreateAnomalyTrackerMissingBuckets) {
+    int64_t metricId = 1;
+    Alert alert;
+    alert.set_id(123);
+    alert.set_metric_id(metricId);
+    alert.set_trigger_if_sum_gt(1);
+
+    CountMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
+            kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, {{1, 0}}, metricProducers), nullopt);
+}
+
+TEST(MetricsManagerTest, TestCreateAnomalyTrackerGood) {
+    int64_t metricId = 1;
+    Alert alert;
+    alert.set_id(123);
+    alert.set_metric_id(metricId);
+    alert.set_trigger_if_sum_gt(1);
+    alert.set_num_buckets(1);
+
+    CountMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    vector<sp<MetricProducer>> metricProducers({new CountMetricProducer(
+            kConfigKey, metric, 0, {ConditionState::kUnknown}, wizard, 0x0123456789, 0, 0)});
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    EXPECT_NE(createAnomalyTracker(alert, anomalyAlarmMonitor, {{1, 0}}, metricProducers), nullopt);
+}
+
+TEST(MetricsManagerTest, TestCreateAnomalyTrackerDurationTooLong) {
+    int64_t metricId = 1;
+    Alert alert;
+    alert.set_id(123);
+    alert.set_metric_id(metricId);
+    // Impossible for alert to fire since the time is bigger than bucketSize * numBuckets
+    alert.set_trigger_if_sum_gt(MillisToNano(TimeUnitToBucketSizeInMillis(ONE_MINUTE)) + 1);
+    alert.set_num_buckets(1);
+
+    DurationMetric metric;
+    metric.set_id(metricId);
+    metric.set_bucket(ONE_MINUTE);
+    metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
+    FieldMatcher dimensions;
+    sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+    vector<sp<MetricProducer>> metricProducers({new DurationMetricProducer(
+            kConfigKey, metric, -1 /*no condition*/, {}, 1 /* start index */, 2 /* stop index */,
+            3 /* stop_all index */, false /*nesting*/, wizard, 0x0123456789, dimensions, 0, 0)});
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    EXPECT_EQ(createAnomalyTracker(alert, anomalyAlarmMonitor, {{1, 0}}, metricProducers), nullopt);
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/non-updatable-api/Android.bp b/core/api/Android.bp
similarity index 100%
rename from non-updatable-api/Android.bp
rename to core/api/Android.bp
diff --git a/non-updatable-api/current.txt b/core/api/current.txt
similarity index 99%
rename from non-updatable-api/current.txt
rename to core/api/current.txt
index 16a5f5e..05b57af 100644
--- a/non-updatable-api/current.txt
+++ b/core/api/current.txt
@@ -11718,10 +11718,9 @@
     method public long getFirstInstallTime();
     method public android.graphics.drawable.Drawable getIcon(int);
     method public CharSequence getLabel();
+    method public float getLoadingProgress();
     method public String getName();
-    method public float getProgress();
     method public android.os.UserHandle getUser();
-    method public boolean isLoading();
     method public boolean isStartable();
   }
 
@@ -11762,7 +11761,7 @@
     ctor public LauncherApps.Callback();
     method public abstract void onPackageAdded(String, android.os.UserHandle);
     method public abstract void onPackageChanged(String, android.os.UserHandle);
-    method public void onPackageProgressChanged(@NonNull String, @NonNull android.os.UserHandle, float);
+    method public void onPackageLoadingProgressChanged(@NonNull String, @NonNull android.os.UserHandle, float);
     method public abstract void onPackageRemoved(String, android.os.UserHandle);
     method public abstract void onPackagesAvailable(String[], android.os.UserHandle, boolean);
     method public void onPackagesSuspended(String[], android.os.UserHandle);
diff --git a/non-updatable-api/module-lib-current.txt b/core/api/module-lib-current.txt
similarity index 100%
rename from non-updatable-api/module-lib-current.txt
rename to core/api/module-lib-current.txt
diff --git a/non-updatable-api/module-lib-removed.txt b/core/api/module-lib-removed.txt
similarity index 100%
rename from non-updatable-api/module-lib-removed.txt
rename to core/api/module-lib-removed.txt
diff --git a/non-updatable-api/removed.txt b/core/api/removed.txt
similarity index 100%
rename from non-updatable-api/removed.txt
rename to core/api/removed.txt
diff --git a/non-updatable-api/system-current.txt b/core/api/system-current.txt
similarity index 99%
rename from non-updatable-api/system-current.txt
rename to core/api/system-current.txt
index eea50be..b37f738 100644
--- a/non-updatable-api/system-current.txt
+++ b/core/api/system-current.txt
@@ -5665,7 +5665,7 @@
     method @NonNull public android.media.tv.tuner.frontend.AtscFrontendSettings.Builder setModulation(int);
   }
 
-  public class DtmbFrontendCapabilities extends android.media.tv.tuner.frontend.FrontendCapabilities {
+  public final class DtmbFrontendCapabilities extends android.media.tv.tuner.frontend.FrontendCapabilities {
     method public int getBandwidthCapability();
     method public int getCodeRateCapability();
     method public int getGuardIntervalCapability();
@@ -5674,7 +5674,7 @@
     method public int getTransmissionModeCapability();
   }
 
-  public class DtmbFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
+  public final class DtmbFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
     method @NonNull public static android.media.tv.tuner.frontend.DtmbFrontendSettings.Builder builder();
     method public int getBandwidth();
     method public int getCodeRate();
@@ -5737,6 +5737,7 @@
   public class DvbcFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
     method @NonNull public static android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder builder();
     method public int getAnnex();
+    method public int getBandwidth();
     method public long getInnerFec();
     method public int getModulation();
     method public int getOuterFec();
@@ -5748,6 +5749,11 @@
     field public static final int ANNEX_B = 2; // 0x2
     field public static final int ANNEX_C = 4; // 0x4
     field public static final int ANNEX_UNDEFINED = 0; // 0x0
+    field public static final int BANDWIDTH_5MHZ = 1; // 0x1
+    field public static final int BANDWIDTH_6MHZ = 2; // 0x2
+    field public static final int BANDWIDTH_7MHZ = 4; // 0x4
+    field public static final int BANDWIDTH_8MHZ = 8; // 0x8
+    field public static final int BANDWIDTH_UNDEFINED = 0; // 0x0
     field public static final int MODULATION_AUTO = 1; // 0x1
     field public static final int MODULATION_MOD_128QAM = 16; // 0x10
     field public static final int MODULATION_MOD_16QAM = 2; // 0x2
@@ -5777,6 +5783,7 @@
   public static class DvbcFrontendSettings.Builder {
     method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings build();
     method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setAnnex(int);
+    method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setBandwidth(int);
     method @IntRange(from=1) @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setFrequency(int);
     method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setInnerFec(long);
     method @NonNull public android.media.tv.tuner.frontend.DvbcFrontendSettings.Builder setModulation(int);
@@ -6070,17 +6077,17 @@
     method public int getBer();
     method @NonNull public int[] getBers();
     method @NonNull public int[] getCodeRates();
+    method @NonNull public int[] getExtendedModulations();
     method public int getFreqOffset();
     method public int getGuardInterval();
     method public int getHierarchy();
     method public long getInnerFec();
     method @NonNull public int[] getInterleaving();
-    method @NonNull public int[] getIsdbtSegment();
+    method @IntRange(from=0, to=255) @NonNull public int[] getIsdbtSegment();
     method @NonNull public boolean[] getLayerErrors();
     method public int getLnbVoltage();
     method public int getMer();
     method public int getModulation();
-    method @NonNull public int[] getModulationsExt();
     method public int getPer();
     method public int getPerBer();
     method public int getPlpId();
@@ -6089,7 +6096,7 @@
     method public int getSnr();
     method public int getSpectralInversion();
     method public int getSymbolRate();
-    method public int getSystemId();
+    method @IntRange(from=0, to=65535) public int getSystemId();
     method public int getTransmissionMode();
     method @NonNull public int[] getTsDataRate();
     method public int getUec();
@@ -8329,6 +8336,7 @@
     field public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
     field public static final String NAMESPACE_PERMISSIONS = "permissions";
     field public static final String NAMESPACE_PRIVACY = "privacy";
+    field public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot";
     field public static final String NAMESPACE_ROLLBACK = "rollback";
     field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
     field public static final String NAMESPACE_RUNTIME = "runtime";
diff --git a/non-updatable-api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
similarity index 100%
rename from non-updatable-api/system-lint-baseline.txt
rename to core/api/system-lint-baseline.txt
diff --git a/non-updatable-api/system-removed.txt b/core/api/system-removed.txt
similarity index 100%
rename from non-updatable-api/system-removed.txt
rename to core/api/system-removed.txt
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index e20ef7f..c89f16e 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;
@@ -7590,8 +7592,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 +7605,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/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 45e9c49..43b7722c 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
@@ -204,6 +206,13 @@
      */
     public ArrayList<IBinder> launchCookies = new ArrayList<>();
 
+    /**
+     * The identifier of the parent task that is created by organizer, otherwise
+     * {@link ActivityTaskManager#INVALID_TASK_ID}.
+     * @hide
+     */
+    public int parentTaskId;
+
     TaskInfo() {
         // Do nothing
     }
@@ -253,6 +262,12 @@
         launchCookies.add(cookie);
     }
 
+    /** @hide */
+    @TestApi
+    public boolean hasParentTask() {
+        return parentTaskId != INVALID_TASK_ID;
+    }
+
     /**
      * Reads the TaskInfo from a parcel.
      */
@@ -283,6 +298,7 @@
         source.readBinderList(launchCookies);
         letterboxActivityBounds = source.readTypedObject(Rect.CREATOR);
         positionInParent = source.readTypedObject(Point.CREATOR);
+        parentTaskId = source.readInt();
     }
 
     /**
@@ -316,6 +332,7 @@
         dest.writeBinderList(launchCookies);
         dest.writeTypedObject(letterboxActivityBounds, flags);
         dest.writeTypedObject(positionInParent, flags);
+        dest.writeInt(parentTaskId);
     }
 
     @Override
@@ -338,6 +355,7 @@
                 + " launchCookies" + launchCookies
                 + " letterboxActivityBounds=" + letterboxActivityBounds
                 + " positionInParent=" + positionInParent
+                + " parentTaskId: " + parentTaskId
                 + "}";
     }
 }
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index c854aba..587e883 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.XmlResourceParser;
-import android.os.Build;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.storage.StorageManager;
@@ -92,7 +91,7 @@
     /**
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @UnsupportedAppUsage
     static public native int backupToTar(String packageName, String domain,
             String linkdomain, String rootpath, String path, FullBackupDataOutput output);
 
diff --git a/core/java/android/app/backup/OWNERS b/core/java/android/app/backup/OWNERS
index 9c21e8f..7e7710b 100644
--- a/core/java/android/app/backup/OWNERS
+++ b/core/java/android/app/backup/OWNERS
@@ -1,9 +1,4 @@
-alsutton@google.com
-anniemeng@google.com
-brufino@google.com
-bryanmawhinney@google.com
-ctate@google.com
-jorlow@google.com
-nathch@google.com
-rthakohov@google.com
+# Bug component: 656484
+
+include platform/frameworks/base/services/backup:/OWNERS
 
diff --git a/core/java/android/app/time/TimeManager.java b/core/java/android/app/time/TimeManager.java
index 4796d8d..262d244 100644
--- a/core/java/android/app/time/TimeManager.java
+++ b/core/java/android/app/time/TimeManager.java
@@ -110,7 +110,7 @@
     @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION)
     public boolean updateTimeZoneConfiguration(@NonNull TimeZoneConfiguration configuration) {
         if (DEBUG) {
-            Log.d(TAG, "updateConfiguration called: " + configuration);
+            Log.d(TAG, "updateTimeZoneConfiguration called: " + configuration);
         }
         try {
             return mITimeZoneDetectorService.updateConfiguration(configuration);
diff --git a/core/java/android/app/time/TimeZoneCapabilities.java b/core/java/android/app/time/TimeZoneCapabilities.java
index 7cc67b3..a27be96 100644
--- a/core/java/android/app/time/TimeZoneCapabilities.java
+++ b/core/java/android/app/time/TimeZoneCapabilities.java
@@ -180,8 +180,7 @@
     public TimeZoneConfiguration tryApplyConfigChanges(
             @NonNull TimeZoneConfiguration config,
             @NonNull TimeZoneConfiguration requestedChanges) {
-        TimeZoneConfiguration.Builder newConfigBuilder =
-                new TimeZoneConfiguration.Builder(config);
+        TimeZoneConfiguration.Builder newConfigBuilder = new TimeZoneConfiguration.Builder(config);
         if (requestedChanges.hasIsAutoDetectionEnabled()) {
             if (this.getConfigureAutoDetectionEnabledCapability() < CAPABILITY_NOT_APPLICABLE) {
                 return null;
diff --git a/core/java/android/content/pm/IOnAppsChangedListener.aidl b/core/java/android/content/pm/IOnAppsChangedListener.aidl
index f24ed80..830cbe0 100644
--- a/core/java/android/content/pm/IOnAppsChangedListener.aidl
+++ b/core/java/android/content/pm/IOnAppsChangedListener.aidl
@@ -33,5 +33,5 @@
             in Bundle launcherExtras);
     void onPackagesUnsuspended(in UserHandle user, in String[] packageNames);
     void onShortcutChanged(in UserHandle user, String packageName, in ParceledListSlice shortcuts);
-    void onPackageProgressChanged(in UserHandle user, String packageName, float progress);
+    void onPackageLoadingProgressChanged(in UserHandle user, String packageName, float progress);
 }
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index ead80d0..fd96e85 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -91,16 +91,9 @@
     }
 
     /**
-     * @return whether the package is still loading.
+     * @return Package loading progress, range between [0, 1].
      */
-    public boolean isLoading() {
-        return mInternal.getIncrementalStatesInfo().isLoading();
-    }
-
-    /**
-     * @return Package loading progress
-     */
-    public float getProgress() {
+    public float getLoadingProgress() {
         return mInternal.getIncrementalStatesInfo().getProgress();
     }
 
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 2909d66..c964b4b 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -17,7 +17,6 @@
 package android.content.pm;
 
 import static android.Manifest.permission;
-import static android.app.PendingIntent.FLAG_IMMUTABLE;
 
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
@@ -333,7 +332,7 @@
          * @param user The UserHandle of the profile that generated the change.
          * @param progress The new progress value, between [0, 1].
          */
-        public void onPackageProgressChanged(@NonNull String packageName,
+        public void onPackageLoadingProgressChanged(@NonNull String packageName,
                 @NonNull UserHandle user, float progress) {}
     }
 
@@ -1702,15 +1701,15 @@
             }
         }
 
-        public void onPackageProgressChanged(UserHandle user, String packageName,
+        public void onPackageLoadingProgressChanged(UserHandle user, String packageName,
                 float progress) {
             if (DEBUG) {
-                Log.d(TAG, "onPackageProgressChanged " + user.getIdentifier() + ","
+                Log.d(TAG, "onPackageLoadingProgressChanged " + user.getIdentifier() + ","
                         + packageName + "," + progress);
             }
             synchronized (LauncherApps.this) {
                 for (CallbackMessageHandler callback : mCallbacks) {
-                    callback.postOnPackageProgressChanged(user, packageName, progress);
+                    callback.postOnPackageLoadingProgressChanged(user, packageName, progress);
                 }
             }
         }
@@ -1777,7 +1776,7 @@
                     mCallback.onShortcutsChanged(info.packageName, info.shortcuts, info.user);
                     break;
                 case MSG_LOADING_PROGRESS_CHANGED:
-                    mCallback.onPackageProgressChanged(info.packageName, info.user,
+                    mCallback.onPackageLoadingProgressChanged(info.packageName, info.user,
                             info.mLoadingProgress);
                     break;
             }
@@ -1847,7 +1846,7 @@
             obtainMessage(MSG_SHORTCUT_CHANGED, info).sendToTarget();
         }
 
-        public void postOnPackageProgressChanged(UserHandle user, String packageName,
+        public void postOnPackageLoadingProgressChanged(UserHandle user, String packageName,
                 float progress) {
             CallbackInfo info = new CallbackInfo();
             info.packageName = packageName;
diff --git a/core/java/android/content/pm/OWNERS b/core/java/android/content/pm/OWNERS
new file mode 100644
index 0000000..a16bb4f
--- /dev/null
+++ b/core/java/android/content/pm/OWNERS
@@ -0,0 +1 @@
+per-file PackageParser.java = chiuwinson@google.com
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c0f5817..946c634 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1712,6 +1712,15 @@
     public static final int DELETE_FAILED_USED_SHARED_LIBRARY = -6;
 
     /**
+     * Deletion failed return code: this is passed to the
+     * {@link IPackageDeleteObserver} if the system failed to delete the package
+     * because there is an app pinned.
+     *
+     * @hide
+     */
+    public static final int DELETE_FAILED_APP_PINNED = -7;
+
+    /**
      * Return code that is passed to the {@link IPackageMoveObserver} when the
      * package has been successfully moved by the system.
      *
@@ -7739,6 +7748,7 @@
             case DELETE_FAILED_OWNER_BLOCKED: return "DELETE_FAILED_OWNER_BLOCKED";
             case DELETE_FAILED_ABORTED: return "DELETE_FAILED_ABORTED";
             case DELETE_FAILED_USED_SHARED_LIBRARY: return "DELETE_FAILED_USED_SHARED_LIBRARY";
+            case DELETE_FAILED_APP_PINNED: return "DELETE_FAILED_APP_PINNED";
             default: return Integer.toString(status);
         }
     }
@@ -7753,6 +7763,7 @@
             case DELETE_FAILED_OWNER_BLOCKED: return PackageInstaller.STATUS_FAILURE_BLOCKED;
             case DELETE_FAILED_ABORTED: return PackageInstaller.STATUS_FAILURE_ABORTED;
             case DELETE_FAILED_USED_SHARED_LIBRARY: return PackageInstaller.STATUS_FAILURE_CONFLICT;
+            case DELETE_FAILED_APP_PINNED: return PackageInstaller.STATUS_FAILURE_BLOCKED;
             default: return PackageInstaller.STATUS_FAILURE;
         }
     }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 118524d..1c90d23 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -141,8 +141,14 @@
  * <li>All installations must contain a single base APK.
  * </ul>
  *
+ * @deprecated This class is mostly unused and no new changes should be added to it. Use
+ * {@link android.content.pm.parsing.ParsingPackageUtils} and related parsing v2 infrastructure in
+ * the core/services parsing subpackages. Or for a quick parse of a provided APK, use
+ * {@link PackageManager#getPackageArchiveInfo(String, int)}.
+ *
  * @hide
  */
+@Deprecated
 public class PackageParser {
 
     public static final boolean DEBUG_JAR = false;
diff --git a/core/java/android/content/pm/parsing/OWNERS b/core/java/android/content/pm/parsing/OWNERS
new file mode 100644
index 0000000..8049d5c
--- /dev/null
+++ b/core/java/android/content/pm/parsing/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 36137
+
+chiuwinson@google.com
+patb@google.com
+toddke@google.com
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/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index e65d7b5..9f322fb 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -419,6 +419,8 @@
      *
      * @see com.android.server.locksettings.LockSettingsService
      *
+     * TODO(b/171335732): should take userId
+     *
      * @hide
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
@@ -426,7 +428,7 @@
         if (mService != null) {
             try {
                 mGenerateChallengeCallback = callback;
-                mService.generateChallenge(mToken, sensorId, mServiceReceiver,
+                mService.generateChallenge(mToken, sensorId, 0 /* userId */, mServiceReceiver,
                         mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
@@ -470,13 +472,16 @@
     /**
      * Invalidates the current challenge.
      *
+     * TODO(b/171335732): should take userId and challenge
+     *
      * @hide
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
     public void revokeChallenge(int sensorId) {
         if (mService != null) {
             try {
-                mService.revokeChallenge(mToken, sensorId, mContext.getOpPackageName());
+                mService.revokeChallenge(mToken, sensorId, 0 /* userId */,
+                        mContext.getOpPackageName(), 0 /* challenge */);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index b85b6f7..490c95b 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -32,7 +32,7 @@
     List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
 
     // Authenticate the given sessionId with a face
-    void authenticate(IBinder token, long operationId, int userid, IFaceServiceReceiver receiver,
+    void authenticate(IBinder token, long operationId, int userId, IFaceServiceReceiver receiver,
             String opPackageName);
 
     // Uses the face hardware to detect for the presence of a face, without giving details
@@ -83,10 +83,10 @@
     boolean isHardwareDetected(String opPackageName);
 
     // Get a pre-enrollment authentication token
-    void generateChallenge(IBinder token, int sensorId, IFaceServiceReceiver receiver, String opPackageName);
+    void generateChallenge(IBinder token, int sensorId, int userId, IFaceServiceReceiver receiver, String opPackageName);
 
     // Finish an enrollment sequence and invalidate the authentication token
-    void revokeChallenge(IBinder token, int sensorId, String opPackageName);
+    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);
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index d2c74e9..4afe4b3 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -766,6 +766,26 @@
     }
 
     /**
+     * Checks if the specified user has enrollments in any of the specified sensors.
+     * @hide
+     */
+    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+    public boolean hasEnrolledTemplatesForAnySensor(int userId,
+            @NonNull List<FingerprintSensorPropertiesInternal> sensors) {
+        if (mService == null) {
+            Slog.w(TAG, "hasEnrolledTemplatesForAnySensor: no fingerprint service");
+            return false;
+        }
+
+        try {
+            return mService.hasEnrolledTemplatesForAnySensor(userId, sensors,
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * @hide
      */
     @RequiresPermission(USE_BIOMETRIC_INTERNAL)
@@ -778,7 +798,7 @@
         try {
             mService.setUdfpsOverlayController(controller);
         } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -795,7 +815,7 @@
         try {
             mService.onPointerDown(sensorId, x, y, minor, major);
         } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -812,7 +832,7 @@
         try {
             mService.onPointerUp(sensorId);
         } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -885,9 +905,8 @@
             }
             return mService.getSensorPropertiesInternal(mContext.getOpPackageName());
         } catch (RemoteException e) {
-            e.rethrowFromSystemServer();
+            throw e.rethrowFromSystemServer();
         }
-        return new ArrayList<>();
     }
 
     /**
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 547de9d..5b14ef7 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -100,6 +100,9 @@
     // 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 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);
 
diff --git a/core/java/android/hardware/usb/AccessoryFilter.java b/core/java/android/hardware/usb/AccessoryFilter.java
index 8345ff3..98e8c92 100644
--- a/core/java/android/hardware/usb/AccessoryFilter.java
+++ b/core/java/android/hardware/usb/AccessoryFilter.java
@@ -102,7 +102,7 @@
     public boolean matches(UsbAccessory acc) {
         if (mManufacturer != null && !acc.getManufacturer().equals(mManufacturer)) return false;
         if (mModel != null && !acc.getModel().equals(mModel)) return false;
-        return !(mVersion != null && !acc.getVersion().equals(mVersion));
+        return !(mVersion != null && !mVersion.equals(acc.getVersion()));
     }
 
     /**
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index bb2357e..3d1755e 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -213,8 +213,7 @@
                         ic,
                         info,
                         moreArgs.argi1 == 1 /* restarting */,
-                        startInputToken,
-                        moreArgs.argi2 == 1 /* shouldPreRenderIme */);
+                        startInputToken);
                 args.recycle();
                 moreArgs.recycle();
                 return;
@@ -340,14 +339,13 @@
     @Override
     public void startInput(IBinder startInputToken, IInputContext inputContext,
             @InputConnectionInspector.MissingMethodFlags final int missingMethods,
-            EditorInfo attribute, boolean restarting, boolean shouldPreRenderIme) {
+            EditorInfo attribute, boolean restarting) {
         if (mCancellationGroup == null) {
             Log.e(TAG, "startInput must be called after bindInput.");
             mCancellationGroup = new CancellationGroup();
         }
         SomeArgs args = SomeArgs.obtain();
         args.argi1 = restarting ? 1 : 0;
-        args.argi2 = shouldPreRenderIme ? 1 : 0;
         args.argi3 = missingMethods;
         mCaller.executeOrSendMessage(mCaller.obtainMessageOOOOO(DO_START_INPUT, startInputToken,
                 inputContext, attribute, mCancellationGroup, args));
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index d290465..32a8c0a 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -19,7 +19,6 @@
 import static android.graphics.Color.TRANSPARENT;
 import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VIEW_STARTED;
 import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VISIBILITY;
-import static android.inputmethodservice.InputMethodServiceProto.CAN_PRE_RENDER;
 import static android.inputmethodservice.InputMethodServiceProto.CONFIGURATION;
 import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_VISIBLE;
 import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_WAS_VISIBLE;
@@ -33,7 +32,6 @@
 import static android.inputmethodservice.InputMethodServiceProto.IN_SHOW_WINDOW;
 import static android.inputmethodservice.InputMethodServiceProto.IS_FULLSCREEN;
 import static android.inputmethodservice.InputMethodServiceProto.IS_INPUT_VIEW_SHOWN;
-import static android.inputmethodservice.InputMethodServiceProto.IS_PRE_RENDERED;
 import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.CONTENT_TOP_INSETS;
 import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_INSETS;
 import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_REGION;
@@ -421,10 +419,6 @@
     boolean mDecorViewVisible;
     boolean mDecorViewWasVisible;
     boolean mInShowWindow;
-    // True if pre-rendering of IME views/window is supported.
-    boolean mCanPreRender;
-    // If IME is pre-rendered.
-    boolean mIsPreRendered;
     // IME window visibility.
     // Use (mDecorViewVisible && mWindowVisible) to check if IME is visible to the user.
     boolean mWindowVisible;
@@ -672,10 +666,8 @@
         @Override
         public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
                 @NonNull EditorInfo editorInfo, boolean restarting,
-                @NonNull IBinder startInputToken, boolean shouldPreRenderIme) {
+                @NonNull IBinder startInputToken) {
             mPrivOps.reportStartInput(startInputToken);
-            mCanPreRender = shouldPreRenderIme;
-            if (DEBUG) Log.v(TAG, "Will Pre-render IME: " + mCanPreRender);
 
             if (restarting) {
                 restartInput(inputConnection, editorInfo);
@@ -712,22 +704,12 @@
                         + " Use requestHideSelf(int) itself");
                 return;
             }
-            final boolean wasVisible = mIsPreRendered
-                    ? mDecorViewVisible && mWindowVisible : isInputViewShown();
+            final boolean wasVisible = isInputViewShown();
             applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */);
-            if (mIsPreRendered) {
-                if (DEBUG) {
-                    Log.v(TAG, "Making IME window invisible");
-                }
-                setImeWindowStatus(IME_ACTIVE | IME_INVISIBLE, mBackDisposition);
-                onPreRenderedWindowVisibilityChanged(false /* setVisible */);
-            } else {
-                mShowInputFlags = 0;
-                mShowInputRequested = false;
-                doHideWindow();
-            }
-            final boolean isVisible = mIsPreRendered
-                    ? mDecorViewVisible && mWindowVisible : isInputViewShown();
+            mShowInputFlags = 0;
+            mShowInputRequested = false;
+            doHideWindow();
+            final boolean isVisible = isInputViewShown();
             final boolean visibilityChanged = isVisible != wasVisible;
             if (resultReceiver != null) {
                 resultReceiver.send(visibilityChanged
@@ -766,23 +748,15 @@
                         + " Use requestShowSelf(int) itself");
                 return;
             }
-            final boolean wasVisible = mIsPreRendered
-                    ? mDecorViewVisible && mWindowVisible : isInputViewShown();
+            final boolean wasVisible = isInputViewShown();
             if (dispatchOnShowInputRequested(flags, false)) {
-                if (mIsPreRendered) {
-                    if (DEBUG) {
-                        Log.v(TAG, "Making IME window visible");
-                    }
-                    onPreRenderedWindowVisibilityChanged(true /* setVisible */);
-                } else {
-                    showWindow(true);
-                }
+
+                showWindow(true);
                 applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */);
             }
             // If user uses hard keyboard, IME button should always be shown.
             setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
-            final boolean isVisible = mIsPreRendered
-                    ? mDecorViewVisible && mWindowVisible : isInputViewShown();
+            final boolean isVisible = isInputViewShown();
             final boolean visibilityChanged = isVisible != wasVisible;
             if (resultReceiver != null) {
                 resultReceiver.send(visibilityChanged
@@ -1798,7 +1772,7 @@
      * applied by {@link #updateInputViewShown()}.
      */
     public boolean isInputViewShown() {
-        return mCanPreRender ? mWindowVisible : mIsInputViewShown && mDecorViewVisible;
+        return mDecorViewVisible;
     }
 
     /**
@@ -2151,10 +2125,9 @@
 
         mDecorViewWasVisible = mDecorViewVisible;
         mInShowWindow = true;
-        boolean isPreRenderedAndInvisible = mIsPreRendered && !mWindowVisible;
         final int previousImeWindowStatus =
                 (mDecorViewVisible ? IME_ACTIVE : 0) | (isInputViewShown()
-                        ? (isPreRenderedAndInvisible ? IME_INVISIBLE : IME_VISIBLE) : 0);
+                        ? (!mWindowVisible ? IME_INVISIBLE : IME_VISIBLE) : 0);
         startViews(prepareWindow(showInput));
         final int nextImeWindowStatus = mapToImeWindowStatus();
         if (previousImeWindowStatus != nextImeWindowStatus) {
@@ -2163,14 +2136,7 @@
 
         // compute visibility
         onWindowShown();
-        mIsPreRendered = mCanPreRender;
-        if (mIsPreRendered) {
-            onPreRenderedWindowVisibilityChanged(true /* setVisible */);
-        } else {
-            // Pre-rendering not supported.
-            if (DEBUG) Log.d(TAG, "No pre-rendering supported");
-            mWindowVisible = true;
-        }
+        mWindowVisible = true;
 
         // request draw for the IME surface.
         // When IME is not pre-rendered, this will actually show the IME.
@@ -2178,22 +2144,10 @@
             if (DEBUG) Log.v(TAG, "showWindow: draw decorView!");
             mWindow.show();
         }
-        maybeNotifyPreRendered();
         mDecorViewWasVisible = true;
         mInShowWindow = false;
     }
 
-    /**
-     * Notify {@link android.view.ImeInsetsSourceConsumer} if IME has been pre-rendered
-     * for current EditorInfo, when pre-rendering is enabled.
-     */
-    private void maybeNotifyPreRendered() {
-        if (!mCanPreRender || !mIsPreRendered) {
-            return;
-        }
-        mPrivOps.reportPreRendered(getCurrentInputEditorInfo());
-    }
-
 
     private boolean prepareWindow(boolean showInput) {
         boolean doShowInput = false;
@@ -2237,16 +2191,6 @@
         if (doShowInput) startExtractingText(false);
     }
 
-    private void onPreRenderedWindowVisibilityChanged(boolean setVisible) {
-        mWindowVisible = setVisible;
-        mShowInputFlags = setVisible ? mShowInputFlags : 0;
-        mShowInputRequested = setVisible;
-        mDecorViewVisible = setVisible;
-        if (setVisible) {
-            onWindowShown();
-        }
-    }
-
     /**
      * Applies the IME visibility in {@link android.view.ImeInsetsSourceConsumer}.
      *
@@ -2277,7 +2221,6 @@
 
     public void hideWindow() {
         if (DEBUG) Log.v(TAG, "CALL: hideWindow");
-        mIsPreRendered = false;
         mWindowVisible = false;
         finishViews(false /* finishingInput */);
         if (mDecorViewVisible) {
@@ -2384,32 +2327,6 @@
                 mCandidatesViewStarted = true;
                 onStartCandidatesView(mInputEditorInfo, restarting);
             }
-        } else if (mCanPreRender && mInputEditorInfo != null && mStartedInputConnection != null) {
-            // Pre-render IME views and window when real EditorInfo is available.
-            // pre-render IME window and keep it invisible.
-            if (DEBUG) Log.v(TAG, "Pre-Render IME for " + mInputEditorInfo.fieldName);
-            if (mInShowWindow) {
-                Log.w(TAG, "Re-entrance in to showWindow");
-                return;
-            }
-
-            mDecorViewWasVisible = mDecorViewVisible;
-            mInShowWindow = true;
-            startViews(prepareWindow(true /* showInput */));
-
-            // compute visibility
-            mIsPreRendered = true;
-            onPreRenderedWindowVisibilityChanged(false /* setVisible */);
-
-            // request draw for the IME surface.
-            // When IME is not pre-rendered, this will actually show the IME.
-            if (DEBUG) Log.v(TAG, "showWindow: draw decorView!");
-            mWindow.show();
-            maybeNotifyPreRendered();
-            mDecorViewWasVisible = true;
-            mInShowWindow = false;
-        } else {
-            mIsPreRendered = false;
         }
     }
     
@@ -3309,9 +3226,7 @@
 
     private int mapToImeWindowStatus() {
         return IME_ACTIVE
-                | (isInputViewShown()
-                        ? (mCanPreRender ? (mWindowVisible ? IME_VISIBLE : IME_INVISIBLE)
-                        : IME_VISIBLE) : 0);
+                | (isInputViewShown() ? IME_VISIBLE : 0);
     }
 
     private boolean isAutomotive() {
@@ -3349,8 +3264,6 @@
 
         p.println("  mShowInputRequested=" + mShowInputRequested
                 + " mLastShowInputRequested=" + mLastShowInputRequested
-                + " mCanPreRender=" + mCanPreRender
-                + " mIsPreRendered=" + mIsPreRendered
                 + " mShowInputFlags=0x" + Integer.toHexString(mShowInputFlags));
         p.println("  mCandidatesVisibility=" + mCandidatesVisibility
                 + " mFullscreenApplied=" + mFullscreenApplied
@@ -3401,8 +3314,6 @@
         }
         proto.write(SHOW_INPUT_REQUESTED, mShowInputRequested);
         proto.write(LAST_SHOW_INPUT_REQUESTED, mLastShowInputRequested);
-        proto.write(CAN_PRE_RENDER, mCanPreRender);
-        proto.write(IS_PRE_RENDERED, mIsPreRendered);
         proto.write(SHOW_INPUT_FLAGS, mShowInputFlags);
         proto.write(CANDIDATES_VISIBILITY, mCandidatesVisibility);
         proto.write(FULLSCREEN_APPLIED, mFullscreenApplied);
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 0a4e867..97c9f4b 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -251,6 +251,15 @@
     public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";
 
     /**
+     * Namespace for features related to the Profcollect native Service.
+     * These features are applied at reboot.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_PROFCOLLECT_NATIVE_BOOT = "profcollect_native_boot";
+
+    /**
      * Namespace for Rollback flags that are applied immediately.
      *
      * @hide
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 780c4fa..cc3d92d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9758,6 +9758,14 @@
                 "render_shadows_in_compositor";
 
         /**
+         * If true, submit buffers using blast in ViewRootImpl.
+         * (0 = false, 1 = true)
+         * @hide
+         */
+        public static final String DEVELOPMENT_USE_BLAST_ADAPTER_VR =
+                "use_blast_adapter_vr";
+
+        /**
          * If true, submit buffers using blast in SurfaceView.
          * (0 = false, 1 = true)
          * @hide
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index e4ba87c..f08756a 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -218,6 +218,7 @@
     public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58;
     public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59;
     public static final int KM_ERROR_CANNOT_ATTEST_IDS = -66;
+    public static final int KM_ERROR_HARDWARE_TYPE_UNAVAILABLE = -68;
     public static final int KM_ERROR_DEVICE_LOCKED = -72;
     public static final int KM_ERROR_UNIMPLEMENTED = -100;
     public static final int KM_ERROR_VERSION_MISMATCH = -101;
@@ -265,6 +266,8 @@
         sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH,
                 "Invalid MAC or authentication tag length");
         sErrorCodeToString.put(KM_ERROR_CANNOT_ATTEST_IDS, "Unable to attest device ids");
+        sErrorCodeToString.put(KM_ERROR_HARDWARE_TYPE_UNAVAILABLE, "Requested security level "
+                        + "(likely Strongbox) is not available.");
         sErrorCodeToString.put(KM_ERROR_DEVICE_LOCKED, "Device locked");
         sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
         sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index dd1a194..5780d4f 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -16,7 +16,6 @@
 
 package android.view;
 
-import static android.view.ImeInsetsSourceConsumerProto.FOCUSED_EDITOR;
 import static android.view.ImeInsetsSourceConsumerProto.INSETS_SOURCE_CONSUMER;
 import static android.view.ImeInsetsSourceConsumerProto.IS_REQUESTED_VISIBLE_AWAITING_CONTROL;
 import static android.view.InsetsController.AnimationType;
@@ -25,16 +24,10 @@
 import android.annotation.Nullable;
 import android.inputmethodservice.InputMethodService;
 import android.os.IBinder;
-import android.os.Parcel;
-import android.text.TextUtils;
 import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl.Transaction;
-import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Arrays;
 import java.util.function.Supplier;
 
 /**
@@ -42,13 +35,6 @@
  * @hide
  */
 public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
-    private EditorInfo mFocusedEditor;
-    private EditorInfo mPreRenderedEditor;
-    /**
-     * Determines if IME would be shown next time IME is pre-rendered for currently focused
-     * editor {@link #mFocusedEditor} if {@link #isServedEditorRendered} is {@code true}.
-     */
-    private boolean mShowOnNextImeRender;
 
     /**
      * Tracks whether we have an outstanding request from the IME to show, but weren't able to
@@ -62,23 +48,6 @@
         super(ITYPE_IME, state, transactionSupplier, controller);
     }
 
-    public void onPreRendered(EditorInfo info) {
-        mPreRenderedEditor = info;
-        if (mShowOnNextImeRender) {
-            mShowOnNextImeRender = false;
-            if (isServedEditorRendered()) {
-                applyImeVisibility(true /* setVisible */);
-            }
-        }
-    }
-
-    public void onServedEditorChanged(EditorInfo info) {
-        if (isFallbackOrEmptyEditor(info)) {
-            mShowOnNextImeRender = false;
-        }
-        mFocusedEditor = info;
-    }
-
     public void applyImeVisibility(boolean setVisible) {
         mController.applyImeVisibility(setVisible);
     }
@@ -170,73 +139,10 @@
         }
     }
 
-    private boolean isFallbackOrEmptyEditor(EditorInfo info) {
-        // TODO(b/123044812): Handle fallback input gracefully in IME Insets API
-        return info == null || (info.fieldId <= 0 && info.inputType <= 0);
-    }
-
-    private boolean isServedEditorRendered() {
-        if (mFocusedEditor == null || mPreRenderedEditor == null
-                || isFallbackOrEmptyEditor(mFocusedEditor)
-                || isFallbackOrEmptyEditor(mPreRenderedEditor)) {
-            // No view is focused or ready.
-            return false;
-        }
-        return areEditorsSimilar(mFocusedEditor, mPreRenderedEditor);
-    }
-
-    @VisibleForTesting
-    public static boolean areEditorsSimilar(EditorInfo info1, EditorInfo info2) {
-        // We don't need to compare EditorInfo.fieldId (View#id) since that shouldn't change
-        // IME views.
-        boolean areOptionsSimilar =
-                info1.imeOptions == info2.imeOptions
-                && info1.inputType == info2.inputType
-                && TextUtils.equals(info1.packageName, info2.packageName);
-        areOptionsSimilar &= info1.privateImeOptions != null
-                ? info1.privateImeOptions.equals(info2.privateImeOptions) : true;
-
-        if (!areOptionsSimilar) {
-            return false;
-        }
-
-        // compare bundle extras.
-        if ((info1.extras == null && info2.extras == null) || info1.extras == info2.extras) {
-            return true;
-        }
-        if ((info1.extras == null && info2.extras != null)
-                || (info1.extras == null && info2.extras != null)) {
-            return false;
-        }
-        if (info1.extras.hashCode() == info2.extras.hashCode()
-                || info1.extras.equals(info1)) {
-            return true;
-        }
-        if (info1.extras.size() != info2.extras.size()) {
-            return false;
-        }
-        if (info1.extras.toString().equals(info2.extras.toString())) {
-            return true;
-        }
-
-        // Compare bytes
-        Parcel parcel1 = Parcel.obtain();
-        info1.extras.writeToParcel(parcel1, 0);
-        parcel1.setDataPosition(0);
-        Parcel parcel2 = Parcel.obtain();
-        info2.extras.writeToParcel(parcel2, 0);
-        parcel2.setDataPosition(0);
-
-        return Arrays.equals(parcel1.createByteArray(), parcel2.createByteArray());
-    }
-
     @Override
     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         super.dumpDebug(proto, INSETS_SOURCE_CONSUMER);
-        if (mFocusedEditor != null) {
-            mFocusedEditor.dumpDebug(proto, FOCUSED_EDITOR);
-        }
         proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingControl);
         proto.end(token);
     }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 3a15aa2..af31b81 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -135,6 +135,8 @@
             int blurRadius);
     private static native void nativeSetLayerStack(long transactionObj, long nativeObject,
             int layerStack);
+    private static native void nativeSetBlurRegions(long transactionObj, long nativeObj,
+            float[][] regions, int length);
 
     private static native boolean nativeClearContentFrameStats(long nativeObject);
     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
@@ -546,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.
      *
@@ -654,6 +662,7 @@
         private final float mFrameScale;
         private final boolean mCaptureSecureLayers;
         private final boolean mAllowProtected;
+        private final long mUid;
 
         private CaptureArgs(Builder<? extends Builder<?>> builder) {
             mPixelFormat = builder.mPixelFormat;
@@ -661,6 +670,7 @@
             mFrameScale = builder.mFrameScale;
             mCaptureSecureLayers = builder.mCaptureSecureLayers;
             mAllowProtected = builder.mAllowProtected;
+            mUid = builder.mUid;
         }
 
         /**
@@ -674,6 +684,7 @@
             private float mFrameScale = 1;
             private boolean mCaptureSecureLayers;
             private boolean mAllowProtected;
+            private long mUid = -1;
 
             /**
              * The desired pixel format of the returned buffer.
@@ -723,6 +734,15 @@
             }
 
             /**
+             * Set the uid of the content that should be screenshot. The code will skip any surfaces
+             * that don't belong to the specified uid.
+             */
+            public T setUid(long uid) {
+                mUid = uid;
+                return getThis();
+            }
+
+            /**
              * Each sub class should return itself to allow the builder to chain properly
              */
             abstract T getThis();
@@ -2942,6 +2962,21 @@
         }
 
         /**
+         * Specify what regions should be blurred on the {@link SurfaceControl}.
+         *
+         * @param sc SurfaceControl.
+         * @param regions List of regions that will have blurs.
+         * @return itself.
+         * @see BlurRegion#toFloatArray()
+         * @hide
+         */
+        public Transaction setBlurRegions(SurfaceControl sc, float[][] regions) {
+            checkPreconditions(sc);
+            nativeSetBlurRegions(mNativeObject, sc.mNativeObject, regions, regions.length);
+            return this;
+        }
+
+        /**
          * @hide
          */
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
@@ -3470,4 +3505,64 @@
     public static Transaction getGlobalTransaction() {
         return sGlobalTransaction;
     }
+
+    /**
+     * Wrapper for sending blur data to SurfaceFlinger.
+     * @hide
+     */
+    public static final class BlurRegion {
+        public int blurRadius;
+        public float cornerRadiusTL;
+        public float cornerRadiusTR;
+        public float cornerRadiusBL;
+        public float cornerRadiusBR;
+        public float alpha = 1;
+        public boolean visible = true;
+        public final Rect rect = new Rect();
+
+        private final float[] mFloatArray = new float[10];
+
+        public BlurRegion() {
+        }
+
+        public BlurRegion(BlurRegion other) {
+            rect.set(other.rect);
+            blurRadius = other.blurRadius;
+            alpha = other.alpha;
+            cornerRadiusTL = other.cornerRadiusTL;
+            cornerRadiusTR = other.cornerRadiusTR;
+            cornerRadiusBL = other.cornerRadiusBL;
+            cornerRadiusBR = other.cornerRadiusBR;
+        }
+
+        /**
+         * Serializes this class into a float array that's more JNI friendly.
+         */
+        public float[] toFloatArray() {
+            mFloatArray[0] = blurRadius;
+            mFloatArray[1] = alpha;
+            mFloatArray[2] = rect.left;
+            mFloatArray[3] = rect.top;
+            mFloatArray[4] = rect.right;
+            mFloatArray[5] = rect.bottom;
+            mFloatArray[6] = cornerRadiusTL;
+            mFloatArray[7] = cornerRadiusTR;
+            mFloatArray[8] = cornerRadiusBL;
+            mFloatArray[9] = cornerRadiusBR;
+            return mFloatArray;
+        }
+
+        @Override
+        public String toString() {
+            return "BlurRegion{"
+                    + "blurRadius=" + blurRadius
+                    + ", corners={" + cornerRadiusTL
+                    + "," + cornerRadiusTR
+                    + "," + cornerRadiusBL
+                    + "," + cornerRadiusBR
+                    + "}, alpha=" + alpha
+                    + ", rect=" + rect
+                    + "}";
+        }
+    }
 }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 14ba699..0e8cd54 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -187,6 +187,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.drawable.BackgroundBlurDrawable;
 import com.android.internal.inputmethod.InputMethodDebug;
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.os.SomeArgs;
@@ -654,6 +655,9 @@
 
     private ScrollCaptureConnection mScrollCaptureConnection;
 
+    private final BackgroundBlurDrawable.Aggregator mBlurRegionAggregator =
+            new BackgroundBlurDrawable.Aggregator(this);
+
     /**
      * @return {@link ImeFocusController} for this instance.
      */
@@ -3819,6 +3823,8 @@
     private HardwareRenderer.FrameCompleteCallback createFrameCompleteCallback(Handler handler,
             boolean reportNextDraw, ArrayList<Runnable> commitCallbacks) {
         return frameNr -> {
+            mBlurRegionAggregator.dispatchBlurTransactionIfNeeded(frameNr);
+
             // Use a new transaction here since mRtBLASTSyncTransaction can only be accessed by
             // the render thread and mSurfaceChangedTransaction can only be accessed by the UI
             // thread. The temporary transaction is used so mRtBLASTSyncTransaction can be merged
@@ -3849,7 +3855,8 @@
                 .captureFrameCommitCallbacks();
         final boolean needFrameCompleteCallback =
                 mNextDrawUseBLASTSyncTransaction || mReportNextDraw
-                        || (commitCallbacks != null && commitCallbacks.size() > 0);
+                        || (commitCallbacks != null && commitCallbacks.size() > 0)
+                        || mBlurRegionAggregator.hasRegions();
         if (needFrameCompleteCallback) {
             mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(
                     createFrameCompleteCallback(mAttachInfo.mHandler, mReportNextDraw,
@@ -9915,6 +9922,36 @@
         }
     }
 
+    /**
+     * Sends a list of blur regions to SurfaceFlinger, tagged with a frame.
+     *
+     * @param regionCopy List of regions
+     * @param frameNumber Frame where it should be applied (or current when using BLAST)
+     */
+    public void dispatchBlurRegions(float[][] regionCopy, long frameNumber) {
+        final SurfaceControl surfaceControl = getSurfaceControl();
+        if (!surfaceControl.isValid()) {
+            return;
+        }
+        if (useBLAST()) {
+            synchronized (getBlastTransactionLock()) {
+                getBLASTSyncTransaction().setBlurRegions(surfaceControl, regionCopy);
+            }
+        } else {
+            SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+            transaction.setBlurRegions(surfaceControl, regionCopy);
+            transaction.deferTransactionUntil(surfaceControl, getSurfaceControl(), frameNumber);
+            transaction.apply();
+        }
+    }
+
+    /**
+     * Creates a background blur drawable for the backing {@link Surface}.
+     */
+    public BackgroundBlurDrawable createBackgroundBlurDrawable() {
+        return mBlurRegionAggregator.createBackgroundBlurDrawable(mContext);
+    }
+
     SurfaceControl.Transaction getBLASTSyncTransaction() {
         return mRtBLASTSyncTransaction;
     }
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index f44ab3a..de4554b 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -243,7 +243,7 @@
     @MainThread
     default void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
             @NonNull EditorInfo editorInfo, boolean restarting,
-            @NonNull IBinder startInputToken, boolean shouldPreRenderIme) {
+            @NonNull IBinder startInputToken) {
         if (restarting) {
             restartInput(inputConnection, editorInfo);
         } else {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 1931174..6243c63 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -489,7 +489,6 @@
     static final int MSG_TIMEOUT_INPUT_EVENT = 6;
     static final int MSG_FLUSH_INPUT_EVENT = 7;
     static final int MSG_REPORT_FULLSCREEN_MODE = 10;
-    static final int MSG_REPORT_PRE_RENDERED = 15;
     static final int MSG_APPLY_IME_VISIBILITY = 20;
     static final int MSG_UPDATE_ACTIVITY_VIEW_TO_SCREEN_MATRIX = 30;
 
@@ -584,17 +583,6 @@
                 mServedConnecting = true;
                 servedView = getServedViewLocked();
             }
-            if (servedView != null && servedView.getHandler() != null) {
-                // Make sure View checks should be on the UI thread.
-                servedView.getHandler().post(() -> {
-                    if (!servedView.onCheckIsTextEditor()) {
-                        // servedView has changed and it's not editable.
-                        synchronized (mH) {
-                            maybeCallServedViewChangedLocked(null);
-                        }
-                    }
-                });
-            }
             return startInputInner(startInputReason,
                     focusedView != null ? focusedView.getWindowToken() : null, startInputFlags,
                     softInputMode, windowFlags);
@@ -919,15 +907,6 @@
                     }
                     return;
                 }
-                case MSG_REPORT_PRE_RENDERED: {
-                    synchronized (mH) {
-                        if (mImeInsetsConsumer != null) {
-                            mImeInsetsConsumer.onPreRendered((EditorInfo) msg.obj);
-                        }
-                    }
-                    return;
-
-                }
                 case MSG_APPLY_IME_VISIBILITY: {
                     synchronized (mH) {
                         if (mImeInsetsConsumer != null) {
@@ -1100,12 +1079,6 @@
         }
 
         @Override
-        public void reportPreRendered(EditorInfo info) {
-            mH.obtainMessage(MSG_REPORT_PRE_RENDERED, 0, 0, info)
-                    .sendToTarget();
-        }
-
-        @Override
         public void applyImeVisibility(boolean setVisible) {
             mH.obtainMessage(MSG_APPLY_IME_VISIBILITY, setVisible ? 1 : 0, 0)
                     .sendToTarget();
@@ -1981,7 +1954,7 @@
 
             // Hook 'em up and let 'er rip.
             mCurrentTextBoxAttribute = tba;
-            maybeCallServedViewChangedLocked(tba);
+
             mServedConnecting = false;
             if (mServedInputConnectionWrapper != null) {
                 mServedInputConnectionWrapper.deactivate();
@@ -3141,12 +3114,6 @@
         }
     }
 
-    private void maybeCallServedViewChangedLocked(EditorInfo tba) {
-        if (mImeInsetsConsumer != null) {
-            mImeInsetsConsumer.onServedEditorChanged(tba);
-        }
-    }
-
     /**
      * <p>This is used for CTS test only. Do not use this method outside of CTS package.<p/>
      * @return the ID of this display which this {@link InputMethodManager} resides
diff --git a/core/java/com/android/internal/BrightnessSynchronizer.java b/core/java/com/android/internal/BrightnessSynchronizer.java
index c98477e..15463cb 100644
--- a/core/java/com/android/internal/BrightnessSynchronizer.java
+++ b/core/java/com/android/internal/BrightnessSynchronizer.java
@@ -22,6 +22,7 @@
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.UserHandle;
@@ -55,7 +56,7 @@
 
     private final Queue<Object> mWriteHistory = new LinkedList<>();
 
-    private final Handler mHandler = new Handler() {
+    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -72,7 +73,6 @@
         }
     };
 
-
     public BrightnessSynchronizer(Context context) {
         final BrightnessSyncObserver mBrightnessSyncObserver;
         mContext = context;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index cb4f285..2e3d560 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1090,7 +1090,7 @@
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         ViewPager viewPager = findViewById(R.id.profile_pager);
-        if (shouldShowTabs() && viewPager.isLayoutRtl()) {
+        if (viewPager.isLayoutRtl()) {
             mMultiProfilePagerAdapter.setupViewPager(viewPager);
         }
 
diff --git a/core/java/com/android/internal/app/ChooserFlags.java b/core/java/com/android/internal/app/ChooserFlags.java
index 3e26679..1a93f1b 100644
--- a/core/java/com/android/internal/app/ChooserFlags.java
+++ b/core/java/com/android/internal/app/ChooserFlags.java
@@ -33,7 +33,7 @@
      */
     public static final boolean USE_SERVICE_TARGETS_FOR_DIRECT_TARGETS =
             DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SHARE_USE_SERVICE_TARGETS, true);
+                SystemUiDeviceConfigFlags.SHARE_USE_SERVICE_TARGETS, false);
 
     /**
      * Whether to use {@link AppPredictionManager} to query for direct share targets (as opposed to
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index a2af4d6..777534e 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -430,6 +430,11 @@
     public static final String USE_BACK_GESTURE_ML_MODEL = "use_back_gesture_ml_model";
 
     /**
+     * (string) The name of the ML model for Back Gesture.
+     */
+    public static final String BACK_GESTURE_ML_MODEL_NAME = "back_gesture_ml_model_name";
+
+    /**
      * (float) Threshold for Back Gesture ML model prediction.
      */
     public static final String BACK_GESTURE_ML_MODEL_THRESHOLD = "back_gesture_ml_model_threshold";
diff --git a/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java b/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java
new file mode 100644
index 0000000..6ea9e66
--- /dev/null
+++ b/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java
@@ -0,0 +1,257 @@
+/*
+ * 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.internal.graphics.drawable;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RenderNode;
+import android.graphics.drawable.Drawable;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.SurfaceControl;
+import android.view.ViewRootImpl;
+
+import com.android.internal.R;
+
+/**
+ * A drawable that keeps track of a blur region, pokes a hole under it, and propagates its state
+ * to SurfaceFlinger.
+ */
+public final class BackgroundBlurDrawable extends Drawable {
+
+    private static final String TAG = BackgroundBlurDrawable.class.getSimpleName();
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final Aggregator mAggregator;
+    private final RenderNode mRenderNode;
+    private final Paint mPaint = new Paint();
+    private final Path mRectPath = new Path();
+    private final float[] mTmpRadii = new float[8];
+    private final SurfaceControl.BlurRegion mBlurRegion = new SurfaceControl.BlurRegion();
+
+    // This will be called from a thread pool.
+    private final RenderNode.PositionUpdateListener mPositionUpdateListener =
+            new RenderNode.PositionUpdateListener() {
+            @Override
+            public void positionChanged(long frameNumber, int left, int top, int right,
+                    int bottom) {
+                synchronized (mAggregator) {
+                    mBlurRegion.rect.set(left, top, right, bottom);
+                    mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion);
+                }
+            }
+
+            @Override
+            public void positionLost(long frameNumber) {
+                synchronized (mAggregator) {
+                    mBlurRegion.rect.setEmpty();
+                    mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion);
+                }
+            }
+        };
+
+    private BackgroundBlurDrawable(Aggregator aggregator) {
+        mAggregator = aggregator;
+        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+        mRenderNode = new RenderNode("BackgroundBlurDrawable");
+        mRenderNode.addPositionUpdateListener(mPositionUpdateListener);
+    }
+
+    @Override
+    public void draw(@NonNull Canvas canvas) {
+        if (mRectPath.isEmpty() || !isVisible() || getAlpha() == 0) {
+            return;
+        }
+        canvas.drawPath(mRectPath, mPaint);
+        canvas.drawRenderNode(mRenderNode);
+    }
+
+    @Override
+    public boolean setVisible(boolean visible, boolean restart) {
+        boolean changed = super.setVisible(visible, restart);
+        if (changed) {
+            mBlurRegion.visible = visible;
+        }
+        return changed;
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        mBlurRegion.alpha = alpha / 255f;
+        invalidateSelf();
+    }
+
+    /**
+     * Blur radius in pixels.
+     */
+    public void setBlurRadius(int blurRadius) {
+        mBlurRegion.blurRadius = blurRadius;
+        invalidateSelf();
+    }
+
+    /**
+     * Sets the corner radius, in degrees.
+     */
+    public void setCornerRadius(float cornerRadius) {
+        setCornerRadius(cornerRadius, cornerRadius, cornerRadius, cornerRadius);
+    }
+
+    /**
+     * Sets the corner radius in degrees.
+     * @param cornerRadiusTL top left radius.
+     * @param cornerRadiusTR top right radius.
+     * @param cornerRadiusBL bottom left radius.
+     * @param cornerRadiusBR bottom right radius.
+     */
+    public void setCornerRadius(float cornerRadiusTL, float cornerRadiusTR, float cornerRadiusBL,
+            float cornerRadiusBR) {
+        synchronized (mAggregator) {
+            mBlurRegion.cornerRadiusTL = cornerRadiusTL;
+            mBlurRegion.cornerRadiusTR = cornerRadiusTR;
+            mBlurRegion.cornerRadiusBL = cornerRadiusBL;
+            mBlurRegion.cornerRadiusBR = cornerRadiusBR;
+        }
+        updatePath();
+        invalidateSelf();
+    }
+
+    @Override
+    public void setBounds(int left, int top, int right, int bottom) {
+        super.setBounds(left, top, right, bottom);
+        mRenderNode.setPosition(left, top, right, bottom);
+        updatePath();
+    }
+
+    private void updatePath() {
+        synchronized (mAggregator) {
+            mTmpRadii[0] = mTmpRadii[1] = mBlurRegion.cornerRadiusTL;
+            mTmpRadii[2] = mTmpRadii[3] = mBlurRegion.cornerRadiusTR;
+            mTmpRadii[4] = mTmpRadii[5] = mBlurRegion.cornerRadiusBL;
+            mTmpRadii[6] = mTmpRadii[7] = mBlurRegion.cornerRadiusBR;
+        }
+        mRectPath.reset();
+        if (getAlpha() == 0 || !isVisible()) {
+            return;
+        }
+        Rect bounds = getBounds();
+        mRectPath.addRoundRect(bounds.left, bounds.top, bounds.right, bounds.bottom, mTmpRadii,
+                Path.Direction.CW);
+    }
+
+    @Override
+    public void setColorFilter(@Nullable ColorFilter colorFilter) {
+        throw new IllegalArgumentException("not implemented");
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    /**
+     * Responsible for keeping track of all blur regions of a {@link ViewRootImpl} and posting a
+     * message when it's time to propagate them.
+     */
+    public static final class Aggregator {
+
+        private final ArrayMap<BackgroundBlurDrawable, SurfaceControl.BlurRegion> mBlurRegions =
+                new ArrayMap<>();
+        private final ViewRootImpl mViewRoot;
+        private float[][] mTmpBlurRegionsArray;
+        private boolean mNeedsUpdate;
+
+        public Aggregator(ViewRootImpl viewRoot) {
+            mViewRoot = viewRoot;
+        }
+
+        /**
+         * Creates a blur region with default radius.
+         */
+        public BackgroundBlurDrawable createBackgroundBlurDrawable(Context context) {
+            BackgroundBlurDrawable drawable = new BackgroundBlurDrawable(this);
+            drawable.setBlurRadius(context.getResources().getDimensionPixelSize(
+                    R.dimen.default_background_blur_radius));
+            return drawable;
+        }
+
+        /**
+         * Called from RenderThread only, already locked.
+         * @param drawable
+         * @param blurRegion
+         */
+        void onBlurRegionUpdated(BackgroundBlurDrawable drawable,
+                SurfaceControl.BlurRegion blurRegion) {
+            if (blurRegion.rect.isEmpty() || blurRegion.alpha == 0 || blurRegion.blurRadius == 0
+                    || !blurRegion.visible) {
+                mBlurRegions.remove(drawable);
+                mNeedsUpdate = true;
+                if (DEBUG) {
+                    Log.d(TAG, "Remove " + blurRegion);
+                }
+            } else {
+                mBlurRegions.put(drawable, blurRegion);
+                mNeedsUpdate = true;
+                if (DEBUG) {
+                    Log.d(TAG, "Update " + blurRegion);
+                }
+            }
+        }
+
+        /**
+         * If there are any blur regions visible on the screen at the moment.
+         */
+        public boolean hasRegions() {
+            return mBlurRegions.size() > 0;
+        }
+
+        /**
+         * Dispatch blur updates, if there were any.
+         * @param frameNumber Frame where the update should happen.
+         */
+        public void dispatchBlurTransactionIfNeeded(long frameNumber) {
+            synchronized (this) {
+                if (!mNeedsUpdate) {
+                    return;
+                }
+                mNeedsUpdate = false;
+
+                if (mTmpBlurRegionsArray == null
+                        || mTmpBlurRegionsArray.length != mBlurRegions.size()) {
+                    mTmpBlurRegionsArray = new float[mBlurRegions.size()][];
+                }
+                if (DEBUG) {
+                    Log.d(TAG, "onBlurRegionUpdated will dispatch " + mTmpBlurRegionsArray.length
+                            + " regions for frame " + frameNumber);
+                }
+                for (int i = 0; i < mTmpBlurRegionsArray.length; i++) {
+                    mTmpBlurRegionsArray[i] = mBlurRegions.valueAt(i).toFloatArray();
+                }
+
+                mViewRoot.dispatchBlurRegions(mTmpBlurRegionsArray, frameNumber);
+            }
+        }
+    }
+}
diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
index 9a22686..f0e26cf 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
@@ -17,7 +17,6 @@
 package com.android.internal.inputmethod;
 
 import android.net.Uri;
-import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.internal.inputmethod.IInputContentUriToken;
@@ -40,6 +39,5 @@
     boolean switchToNextInputMethod(boolean onlyCurrentIme);
     boolean shouldOfferSwitchingToNextInputMethod();
     void notifyUserAction();
-    void reportPreRendered(in EditorInfo info);
     void applyImeVisibility(IBinder showOrHideInputToken, boolean setVisible);
 }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index 9b1299e..d6730e8 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -24,7 +24,6 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.View;
-import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.internal.annotations.GuardedBy;
@@ -351,24 +350,6 @@
     }
 
     /**
-     * Calls {@link IInputMethodPrivilegedOperations#reportPreRendered(info)}.
-     *
-     * @param info {@link EditorInfo} of the currently rendered {@link TextView}.
-     */
-    @AnyThread
-    public void reportPreRendered(EditorInfo info) {
-        final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
-        if (ops == null) {
-            return;
-        }
-        try {
-            ops.reportPreRendered(info);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Calls {@link IInputMethodPrivilegedOperations#applyImeVisibility(IBinder, boolean)}.
      *
      * @param showOrHideInputToken placeholder token that maps to window requesting
diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl
index 40e4f4d..c336373 100644
--- a/core/java/com/android/internal/view/IInputMethod.aidl
+++ b/core/java/com/android/internal/view/IInputMethod.aidl
@@ -45,7 +45,7 @@
     void unbindInput();
 
     void startInput(in IBinder startInputToken, in IInputContext inputContext, int missingMethods,
-            in EditorInfo attribute, boolean restarting, boolean preRenderImeViews);
+            in EditorInfo attribute, boolean restarting);
 
     void createSession(in InputChannel channel, IInputSessionCallback callback);
 
diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl
index c9443b0..1145f51 100644
--- a/core/java/com/android/internal/view/IInputMethodClient.aidl
+++ b/core/java/com/android/internal/view/IInputMethodClient.aidl
@@ -16,8 +16,6 @@
 
 package com.android.internal.view;
 
-import android.view.inputmethod.EditorInfo;
-
 import com.android.internal.view.InputBindResult;
 
 /**
@@ -30,7 +28,6 @@
     void setActive(boolean active, boolean fullscreen);
     void scheduleStartInputIfNecessary(boolean fullscreen);
     void reportFullscreenMode(boolean fullscreen);
-    void reportPreRendered(in EditorInfo info);
     void applyImeVisibility(boolean setVisible);
     void updateActivityViewToScreenMatrix(int bindSequence, in float[] matrixValues);
     void setImeTraceEnabled(boolean enabled);
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index ce8b599..832c066 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -256,11 +256,13 @@
 }
 
 static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords,
-        float xOffset, float yOffset, jobject outPointerCoordsObj) {
-    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x,
-            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset);
-    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y,
-            rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset);
+                                    ui::Transform transform, jobject outPointerCoordsObj) {
+    float rawX = rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X);
+    float rawY = rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y);
+    vec2 transformed = transform.transform(rawX, rawY);
+
+    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x, transformed.x);
+    env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y, transformed.y);
     env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure,
             rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
     env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size,
@@ -433,8 +435,7 @@
         }
         rawPointerCoords = event->getHistoricalRawPointerCoords(pointerIndex, historyPos);
     }
-    pointerCoordsFromNative(env, rawPointerCoords, event->getXOffset(), event->getYOffset(),
-            outPointerCoordsObj);
+    pointerCoordsFromNative(env, rawPointerCoords, event->getTransform(), outPointerCoordsObj);
 }
 
 static void android_view_MotionEvent_nativeGetPointerProperties(JNIEnv* env, jclass clazz,
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 94151b5..f1ec85a 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -40,6 +40,7 @@
 #include <private/gui/ComposerService.h>
 #include <stdio.h>
 #include <system/graphics.h>
+#include <ui/BlurRegion.h>
 #include <ui/ConfigStoreTypes.h>
 #include <ui/DeviceProductInfo.h>
 #include <ui/DisplayConfig.h>
@@ -111,6 +112,7 @@
     jfieldID frameScale;
     jfieldID captureSecureLayers;
     jfieldID allowProtected;
+    jfieldID uid;
 } gCaptureArgsClassInfo;
 
 static struct {
@@ -371,6 +373,7 @@
             env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers);
     captureArgs.allowProtected =
             env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.allowProtected);
+    captureArgs.uid = env->GetLongField(captureArgsObject, gCaptureArgsClassInfo.uid);
 }
 
 static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
@@ -520,6 +523,43 @@
     transaction->setGeometry(ctrl, source, dst, orientation);
 }
 
+static void nativeSetBlurRegions(JNIEnv* env, jclass clazz, jlong transactionObj,
+                                 jlong nativeObject, jobjectArray regions, jint regionsLength) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+
+    std::vector<BlurRegion> blurRegionVector;
+    const int size = regionsLength;
+    float region[10];
+    for (int i = 0; i < size; i++) {
+        jfloatArray regionArray = (jfloatArray)env->GetObjectArrayElement(regions, i);
+        env->GetFloatArrayRegion(regionArray, 0, 10, region);
+        float blurRadius = region[0];
+        float alpha = region[1];
+        float left = region[2];
+        float top = region[3];
+        float right = region[4];
+        float bottom = region[5];
+        float cornerRadiusTL = region[6];
+        float cornerRadiusTR = region[7];
+        float cornerRadiusBL = region[8];
+        float cornerRadiusBR = region[9];
+
+        blurRegionVector.push_back(BlurRegion{.blurRadius = static_cast<uint32_t>(blurRadius),
+                                              .cornerRadiusTL = cornerRadiusTL,
+                                              .cornerRadiusTR = cornerRadiusTR,
+                                              .cornerRadiusBL = cornerRadiusBL,
+                                              .cornerRadiusBR = cornerRadiusBR,
+                                              .alpha = alpha,
+                                              .left = static_cast<int>(left),
+                                              .top = static_cast<int>(top),
+                                              .right = static_cast<int>(right),
+                                              .bottom = static_cast<int>(bottom)});
+    }
+
+    transaction->setBlurRegions(ctrl, blurRegionVector);
+}
+
 static void nativeSetSize(JNIEnv* env, jclass clazz, jlong transactionObj,
         jlong nativeObject, jint w, jint h) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -1624,6 +1664,8 @@
             (void*)nativeSetBackgroundBlurRadius },
     {"nativeSetLayerStack", "(JJI)V",
             (void*)nativeSetLayerStack },
+    {"nativeSetBlurRegions", "(JJ[[FI)V",
+            (void*)nativeSetBlurRegions },
     {"nativeSetShadowRadius", "(JJF)V",
             (void*)nativeSetShadowRadius },
     {"nativeSetFrameRate", "(JJFI)V",
@@ -1895,6 +1937,7 @@
             GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z");
     gCaptureArgsClassInfo.allowProtected =
             GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z");
+    gCaptureArgsClassInfo.uid = GetFieldIDOrDie(env, captureArgsClazz, "mUid", "J");
 
     jclass displayCaptureArgsClazz =
             FindClassOrDie(env, "android/view/SurfaceControl$DisplayCaptureArgs");
diff --git a/core/proto/android/inputmethodservice/inputmethodservice.proto b/core/proto/android/inputmethodservice/inputmethodservice.proto
index 3b4ebb5..e5d1713 100644
--- a/core/proto/android/inputmethodservice/inputmethodservice.proto
+++ b/core/proto/android/inputmethodservice/inputmethodservice.proto
@@ -39,8 +39,8 @@
     optional .android.view.inputmethod.EditorInfoProto input_editor_info = 13;
     optional bool show_input_requested = 14;
     optional bool last_show_input_requested = 15;
-    optional bool can_pre_render = 16;
-    optional bool is_pre_rendered = 17;
+    reserved 16;  // can_pre_render
+    reserved 17;  // is_pre_rendered
     optional int32 show_input_flags = 18;
     optional int32 candidates_visibility = 19;
     optional bool fullscreen_applied = 20;
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/imeinsetssourceconsumer.proto b/core/proto/android/view/imeinsetssourceconsumer.proto
index 5bee81b..1b9aff9 100644
--- a/core/proto/android/view/imeinsetssourceconsumer.proto
+++ b/core/proto/android/view/imeinsetssourceconsumer.proto
@@ -28,6 +28,6 @@
  */
 message ImeInsetsSourceConsumerProto {
     optional InsetsSourceConsumerProto insets_source_consumer = 1;
-    optional .android.view.inputmethod.EditorInfoProto focused_editor = 2;
+    reserved 2; // focused_editor = 2
     optional bool is_requested_visible_awaiting_control = 3;
 }
\ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3248cfe..4df7d58 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -669,10 +669,6 @@
     <!-- For tether entitlement recheck-->
     <protected-broadcast
         android:name="com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM" />
-
-    <!-- Made protected in S (was added in R) -->
-    <protected-broadcast android:name="com.android.internal.intent.action.BUGREPORT_REQUESTED" />
-
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
diff --git a/core/res/res/layout/notification_material_action_list.xml b/core/res/res/layout/notification_material_action_list.xml
index ffb9603..bf66e69 100644
--- a/core/res/res/layout/notification_material_action_list.xml
+++ b/core/res/res/layout/notification_material_action_list.xml
@@ -44,6 +44,14 @@
             </com.android.internal.widget.NotificationActionListLayout>
 
             <ImageView
+                android:id="@+id/snooze_button"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:layout_gravity="center_vertical|end"
+                android:visibility="gone"
+                android:scaleType="centerInside"
+                />
+            <ImageView
                 android:id="@+id/bubble_button"
                 android:layout_width="48dp"
                 android:layout_height="48dp"
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index d0fceb0..393f229b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1129,10 +1129,8 @@
     <string name="capital_off" msgid="7443704171014626777">"DESACTIVADO"</string>
     <string name="checked" msgid="9179896827054513119">"seleccionado"</string>
     <string name="not_checked" msgid="7972320087569023342">"no seleccionado"</string>
-    <!-- no translation found for selected (6614607926197755875) -->
-    <skip />
-    <!-- no translation found for not_selected (410652016565864475) -->
-    <skip />
+    <string name="selected" msgid="6614607926197755875">"seleccionado"</string>
+    <string name="not_selected" msgid="410652016565864475">"no seleccionado"</string>
     <string name="whichApplication" msgid="5432266899591255759">"Completar acción utilizando"</string>
     <string name="whichApplicationNamed" msgid="6969946041713975681">"Completar acción con %1$s"</string>
     <string name="whichApplicationLabel" msgid="7852182961472531728">"Completar acción"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index a3b8f64..f7f6214 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -940,7 +940,7 @@
     <string name="double_tap_toast" msgid="7065519579174882778">"ટિપ: ઝૂમ વધારવા અને ઘટાડવા માટે બે વાર ટેપ કરો."</string>
     <string name="autofill_this_form" msgid="3187132440451621492">"સ્વતઃભરણ"</string>
     <string name="setup_autofill" msgid="5431369130866618567">"સ્વતઃભરણ સેટ કરો"</string>
-    <string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> સાથે આપમેળે ભરો"</string>
+    <string name="autofill_window_title" msgid="4379134104008111961">"<xliff:g id="SERVICENAME">%1$s</xliff:g> સાથે ઑટોમૅટિક રીતે ભરો"</string>
     <string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3402882515222673691">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="760522655085707045">", "</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 82a27a8..53c92af 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1798,7 +1798,7 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"ធ្វើ​បច្ចុប្បន្នភាព​ដោយ​អ្នកគ្រប់គ្រង​របស់​អ្នក"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"លុប​ដោយ​អ្នកគ្រប់គ្រង​របស់​អ្នក"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"យល់ព្រម"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"ដើម្បី​បង្កើនកម្រិត​ថាមពលថ្ម កម្មវិធី​សន្សំថ្ម៖\n\n• បើករចនាប័ទ្មងងឹត\n• បិទ ឬដាក់កំហិតលើ​សកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពល​ជារូបភាពមួយចំនួន និងមុខងារផ្សេងទៀត​ដូចជា “Ok Google” ជាដើម\n\n"<annotation id="url">"ស្វែងយល់​បន្ថែម"</annotation></string>
+    <string name="battery_saver_description_with_learn_more" msgid="4424488535318105801">"ដើម្បី​បង្កើនកម្រិត​ថាមពលថ្ម មុខងារ​សន្សំ​ថ្ម៖\n\n• បើករចនាប័ទ្មងងឹត\n• បិទ ឬដាក់កំហិតលើ​សកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពល​ជារូបភាពមួយចំនួន និងមុខងារផ្សេងទៀត​ដូចជា “Hey Google” ជាដើម\n\n"<annotation id="url">"ស្វែងយល់​បន្ថែម"</annotation></string>
     <string name="battery_saver_description" msgid="6794188153647295212">"ដើម្បី​បង្កើនកម្រិត​ថាមពលថ្ម មុខងារ​សន្សំថ្ម៖\n\n• បើករចនាប័ទ្មងងឹត\n• បិទ ឬដាក់កំហិតលើ​សកម្មភាពផ្ទៃខាងក្រោយ ឥទ្ធិពលរូបភាពមួយចំនួន និងមុខងារផ្សេងទៀត​ដូចជា “Ok Google” ជាដើម"</string>
     <string name="data_saver_description" msgid="4995164271550590517">"ដើម្បីជួយកាត់បន្ថយការប្រើប្រាស់ទិន្នន័យ កម្មវិធីសន្សំសំចៃទិន្នន័យរារាំងកម្មវិធីមួយចំនួនមិនឲ្យបញ្ជូន ឬទទួលទិន្នន័យនៅផ្ទៃខាងក្រោយទេ។ កម្មវិធីដែលអ្នកកំពុងប្រើនាពេលបច្ចុប្បន្នអាចចូលប្រើប្រាស់​ទិន្នន័យបាន ប៉ុន្តែអាចនឹងមិនញឹកញាប់ដូចមុនទេ។ ឧទាហរណ៍ រូបភាពមិនបង្ហាញទេ លុះត្រាតែអ្នកប៉ះរូបភាពទាំងនោះ។"</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"បើកកម្មវិធីសន្សំសំចៃទិន្នន័យ?"</string>
@@ -2007,9 +2007,9 @@
     <string name="notification_feedback_indicator" msgid="663476517711323016">"ផ្ដល់​មតិកែលម្អ"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ការ​ជូនដំណឹង​ព័ត៌មាន​របស់​មុខងារ​ទម្លាប់"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ថ្ម​អាច​នឹង​អស់ មុនពេល​សាកថ្មធម្មតា"</string>
-    <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"បាន​បើក​ដំណើរការកម្មវិធី​សន្សំ​ថ្ម ដើម្បីបង្កើនកម្រិត​ថាមពល​​ថ្ម"</string>
+    <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"បាន​បើក​ដំណើរការមុខងារ​សន្សំ​ថ្ម ដើម្បីបង្កើនកម្រិត​ថាមពល​​ថ្ម"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"មុខងារ​សន្សំ​ថ្ម"</string>
-    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"កម្មវិធី​សន្សំ​ថ្ម​ត្រូវបានបិទ"</string>
+    <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"មុខងារ​សន្សំ​ថ្ម​ត្រូវបានបិទ"</string>
     <string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"ទូរសព្ទ​មាន​កម្រិតថ្ម​គ្រប់គ្រាន់​។ មុខងារ​ផ្សេងៗ​មិន​ត្រូវបាន​រឹតបន្តឹងទៀត​ទេ។"</string>
     <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"ថេប្លេត​មាន​កម្រិតថ្ម​គ្រប់គ្រាន់​។ មុខងារ​ផ្សេងៗ​មិន​ត្រូវបាន​រឹតបន្តឹងទៀត​ទេ។"</string>
     <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"ឧបករណ៍​មាន​កម្រិតថ្ម​គ្រប់គ្រាន់​។ មុខងារ​ផ្សេងៗ​មិន​ត្រូវបាន​រឹតបន្តឹងទៀត​ទេ។"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index db5603c..e39d46d 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1129,10 +1129,8 @@
     <string name="capital_off" msgid="7443704171014626777">"बंद"</string>
     <string name="checked" msgid="9179896827054513119">"तपासले"</string>
     <string name="not_checked" msgid="7972320087569023342">"तपासले नाही"</string>
-    <!-- no translation found for selected (6614607926197755875) -->
-    <skip />
-    <!-- no translation found for not_selected (410652016565864475) -->
-    <skip />
+    <string name="selected" msgid="6614607926197755875">"निवडला"</string>
+    <string name="not_selected" msgid="410652016565864475">"निवडला नाही"</string>
     <string name="whichApplication" msgid="5432266899591255759">"याचा वापर करून क्रिया पूर्ण करा"</string>
     <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s वापरून क्रिया पूर्ण करा"</string>
     <string name="whichApplicationLabel" msgid="7852182961472531728">"क्रिया पूर्ण झाली"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index b5fd7b2..915e158 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1129,10 +1129,8 @@
     <string name="capital_off" msgid="7443704171014626777">"बन्द"</string>
     <string name="checked" msgid="9179896827054513119">"जाँच गरिएको"</string>
     <string name="not_checked" msgid="7972320087569023342">"जाँच गरिएको छैन"</string>
-    <!-- no translation found for selected (6614607926197755875) -->
-    <skip />
-    <!-- no translation found for not_selected (410652016565864475) -->
-    <skip />
+    <string name="selected" msgid="6614607926197755875">"चयन गरियो"</string>
+    <string name="not_selected" msgid="410652016565864475">"चयन गरिएन"</string>
     <string name="whichApplication" msgid="5432266899591255759">"प्रयोग गरेर कारबाही पुरा गर्नुहोस्"</string>
     <string name="whichApplicationNamed" msgid="6969946041713975681">"निम्न एपको प्रयोग गरी कारबाही पुरा गर्नुहोस्: %1$s"</string>
     <string name="whichApplicationLabel" msgid="7852182961472531728">"पूर्ण कारबाही"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index df03ccc..6e03398 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1694,7 +1694,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/dimens.xml b/core/res/res/values/dimens.xml
index 84e7d42..544be54e 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -207,9 +207,6 @@
     <!-- Default padding for dialogs. -->
     <dimen name="dialog_padding">16dp</dimen>
 
-    <!-- The horizontal margin of the content in the notification shade -->
-    <dimen name="notification_shade_content_margin_horizontal">16dp</dimen>
-
     <!-- The margin on the start of the content view -->
     <dimen name="notification_content_margin_start">16dp</dimen>
 
@@ -861,6 +858,7 @@
     <dimen name="waterfall_display_right_edge_size">0px</dimen>
     <dimen name="waterfall_display_bottom_edge_size">0px</dimen>
 
+    <dimen name="default_background_blur_radius">100dp</dimen>
     <!-- The maximum height of a thumbnail in a ThumbnailTemplate. The image will be reduced to that height in case they are bigger. -->
     <dimen name="controls_thumbnail_image_max_height">140dp</dimen>
     <!-- The maximum width of a thumbnail in a ThumbnailTemplate. The image will be reduced to that width in case they are bigger.-->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a716875..a294c9d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2864,7 +2864,6 @@
   <java-symbol type="drawable" name="ic_collapse_bundle" />
   <java-symbol type="dimen" name="notification_min_content_height" />
   <java-symbol type="dimen" name="notification_header_shrink_min_width" />
-  <java-symbol type="dimen" name="notification_shade_content_margin_horizontal" />
   <java-symbol type="dimen" name="notification_content_margin_start" />
   <java-symbol type="dimen" name="notification_content_margin_end" />
   <java-symbol type="dimen" name="notification_reply_inset" />
@@ -3554,6 +3553,7 @@
   <java-symbol type="id" name="clip_to_padding_tag" />
   <java-symbol type="id" name="clip_children_tag" />
   <java-symbol type="id" name="bubble_button" />
+  <java-symbol type="id" name="snooze_button" />
   <java-symbol type="dimen" name="bubble_visible_padding_end" />
   <java-symbol type="dimen" name="bubble_gone_padding_end" />
   <java-symbol type="dimen" name="text_size_body_2_material" />
@@ -4079,6 +4079,7 @@
   <java-symbol type="integer" name="config_defaultBinderHeavyHitterAutoSamplerBatchSize" />
   <java-symbol type="dimen" name="config_defaultBinderHeavyHitterAutoSamplerThreshold" />
 
+  <java-symbol type="dimen" name="default_background_blur_radius" />
   <java-symbol type="array" name="config_keep_warming_services" />
   <java-symbol type="string" name="config_display_features" />
   <java-symbol type="array" name="config_internalFoldedPhysicalDisplayIds" />
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
index ac2d4b5..2f2bef8 100644
--- a/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/AppSearchEmailTest.java
@@ -30,7 +30,7 @@
                 // Score and Property are mixed into the middle to make sure DocumentBuilder's
                 // methods can be interleaved with EmailBuilder's methods.
                 .setScore(1)
-                .setProperty("propertyKey", "propertyValue1", "propertyValue2")
+                .setPropertyString("propertyKey", "propertyValue1", "propertyValue2")
                 .setSubject("subject")
                 .setBody("EmailBody")
                 .build();
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
index 1f2c12b..9c29943 100644
--- a/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/GenericDocumentTest.java
@@ -39,22 +39,22 @@
         GenericDocument document1 = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
                 .setTtlMillis(1L)
-                .setProperty("longKey1", 1L, 2L, 3L)
-                .setProperty("doubleKey1", 1.0, 2.0, 3.0)
-                .setProperty("booleanKey1", true, false, true)
-                .setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
-                .setProperty("byteKey1", sByteArray1, sByteArray2)
-                .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
+                .setPropertyLong("longKey1", 1L, 2L, 3L)
+                .setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
+                .setPropertyBoolean("booleanKey1", true, false, true)
+                .setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
+                .setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
+                .setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
                 .build();
         GenericDocument document2 = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
                 .setTtlMillis(1L)
-                .setProperty("longKey1", 1L, 2L, 3L)
-                .setProperty("doubleKey1", 1.0, 2.0, 3.0)
-                .setProperty("booleanKey1", true, false, true)
-                .setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
-                .setProperty("byteKey1", sByteArray1, sByteArray2)
-                .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
+                .setPropertyLong("longKey1", 1L, 2L, 3L)
+                .setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
+                .setPropertyBoolean("booleanKey1", true, false, true)
+                .setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
+                .setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
+                .setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
                 .build();
         assertThat(document1).isEqualTo(document2);
         assertThat(document1.hashCode()).isEqualTo(document2.hashCode());
@@ -64,23 +64,23 @@
     public void testDocumentEquals_DifferentOrder() {
         GenericDocument document1 = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
-                .setProperty("longKey1", 1L, 2L, 3L)
-                .setProperty("byteKey1", sByteArray1, sByteArray2)
-                .setProperty("doubleKey1", 1.0, 2.0, 3.0)
-                .setProperty("booleanKey1", true, false, true)
-                .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
-                .setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
+                .setPropertyLong("longKey1", 1L, 2L, 3L)
+                .setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
+                .setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
+                .setPropertyBoolean("booleanKey1", true, false, true)
+                .setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
+                .setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
                 .build();
 
         // Create second document with same parameter but different order.
         GenericDocument document2 = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
-                .setProperty("booleanKey1", true, false, true)
-                .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
-                .setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
-                .setProperty("doubleKey1", 1.0, 2.0, 3.0)
-                .setProperty("byteKey1", sByteArray1, sByteArray2)
-                .setProperty("longKey1", 1L, 2L, 3L)
+                .setPropertyBoolean("booleanKey1", true, false, true)
+                .setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
+                .setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
+                .setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
+                .setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
+                .setPropertyLong("longKey1", 1L, 2L, 3L)
                 .build();
         assertThat(document1).isEqualTo(document2);
         assertThat(document1.hashCode()).isEqualTo(document2.hashCode());
@@ -90,13 +90,13 @@
     public void testDocumentEquals_Failure() {
         GenericDocument document1 = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
-                .setProperty("longKey1", 1L, 2L, 3L)
+                .setPropertyLong("longKey1", 1L, 2L, 3L)
                 .build();
 
         // Create second document with same order but different value.
         GenericDocument document2 = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
-                .setProperty("longKey1", 1L, 2L, 4L) // Different
+                .setPropertyLong("longKey1", 1L, 2L, 4L) // Different
                 .build();
         assertThat(document1).isNotEqualTo(document2);
         assertThat(document1.hashCode()).isNotEqualTo(document2.hashCode());
@@ -106,13 +106,13 @@
     public void testDocumentEquals_Failure_RepeatedFieldOrder() {
         GenericDocument document1 = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
-                .setProperty("booleanKey1", true, false, true)
+                .setPropertyBoolean("booleanKey1", true, false, true)
                 .build();
 
         // Create second document with same order but different value.
         GenericDocument document2 = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
-                .setProperty("booleanKey1", true, true, false) // Different
+                .setPropertyBoolean("booleanKey1", true, true, false) // Different
                 .build();
         assertThat(document1).isNotEqualTo(document2);
         assertThat(document1.hashCode()).isNotEqualTo(document2.hashCode());
@@ -124,12 +124,12 @@
                 .setCreationTimestampMillis(5L)
                 .setScore(1)
                 .setTtlMillis(1L)
-                .setProperty("longKey1", 1L)
-                .setProperty("doubleKey1", 1.0)
-                .setProperty("booleanKey1", true)
-                .setProperty("stringKey1", "test-value1")
-                .setProperty("byteKey1", sByteArray1)
-                .setProperty("documentKey1", sDocumentProperties1)
+                .setPropertyLong("longKey1", 1L)
+                .setPropertyDouble("doubleKey1", 1.0)
+                .setPropertyBoolean("booleanKey1", true)
+                .setPropertyString("stringKey1", "test-value1")
+                .setPropertyBytes("byteKey1", sByteArray1)
+                .setPropertyDocument("documentKey1", sDocumentProperties1)
                 .build();
         assertThat(document.getUri()).isEqualTo("uri1");
         assertThat(document.getTtlMillis()).isEqualTo(1L);
@@ -149,12 +149,12 @@
     public void testDocumentGetArrayValues() {
         GenericDocument document = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
-                .setProperty("longKey1", 1L, 2L, 3L)
-                .setProperty("doubleKey1", 1.0, 2.0, 3.0)
-                .setProperty("booleanKey1", true, false, true)
-                .setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
-                .setProperty("byteKey1", sByteArray1, sByteArray2)
-                .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
+                .setPropertyLong("longKey1", 1L, 2L, 3L)
+                .setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
+                .setPropertyBoolean("booleanKey1", true, false, true)
+                .setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
+                .setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
+                .setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
                 .build();
 
         assertThat(document.getUri()).isEqualTo("uri1");
@@ -176,12 +176,12 @@
     public void testDocument_ToString() throws Exception {
         GenericDocument document = new GenericDocument.Builder("uri1", "schemaType1")
                 .setCreationTimestampMillis(5L)
-                .setProperty("longKey1", 1L, 2L, 3L)
-                .setProperty("doubleKey1", 1.0, 2.0, 3.0)
-                .setProperty("booleanKey1", true, false, true)
-                .setProperty("stringKey1", "String1", "String2", "String3")
-                .setProperty("byteKey1", sByteArray1, sByteArray2)
-                .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
+                .setPropertyLong("longKey1", 1L, 2L, 3L)
+                .setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
+                .setPropertyBoolean("booleanKey1", true, false, true)
+                .setPropertyString("stringKey1", "String1", "String2", "String3")
+                .setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
+                .setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
                 .build();
         String exceptedString = "{ key: 'creationTimestampMillis' value: 5 } "
                 + "{ key: 'namespace' value:  } "
@@ -219,9 +219,9 @@
     public void testDocumentGetValues_DifferentTypes() {
         GenericDocument document = new GenericDocument.Builder("uri1", "schemaType1")
                 .setScore(1)
-                .setProperty("longKey1", 1L)
-                .setProperty("booleanKey1", true, false, true)
-                .setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
+                .setPropertyLong("longKey1", 1L)
+                .setPropertyBoolean("booleanKey1", true, false, true)
+                .setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
                 .build();
 
         // Get a value for a key that doesn't exist
@@ -246,6 +246,7 @@
     public void testDocumentInvalid() {
         GenericDocument.Builder builder = new GenericDocument.Builder("uri1", "schemaType1");
         expectThrows(
-                IllegalArgumentException.class, () -> builder.setProperty("test", new boolean[]{}));
+                IllegalArgumentException.class,
+                () -> builder.setPropertyBoolean("test", new boolean[]{}));
     }
 }
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/SearchResultsTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/SearchResultsTest.java
deleted file mode 100644
index acbf11a..0000000
--- a/core/tests/coretests/src/android/app/appsearch/external/app/SearchResultsTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.app.appsearch;
-
-import static org.testng.Assert.expectThrows;
-
-import org.junit.Test;
-
-public class SearchResultsTest {
-    @Test
-    public void buildSearchSpecWithoutTermMatchType() {
-        expectThrows(RuntimeException.class, () -> new SearchSpec.Builder()
-                .setSchemaTypes("testSchemaType")
-                .build());
-    }
-}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/SearchSpecTest.java
new file mode 100644
index 0000000..d4635fd
--- /dev/null
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/SearchSpecTest.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.app.appsearch;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.expectThrows;
+
+import android.os.Bundle;
+
+import org.junit.Test;
+
+public class SearchSpecTest {
+    @Test
+    public void buildSearchSpecWithoutTermMatchType() {
+        expectThrows(RuntimeException.class, () -> new SearchSpec.Builder()
+                .addSchema("testSchemaType")
+                .build());
+    }
+
+    @Test
+    public void testBuildSearchSpec() {
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
+                .addNamespace("namespace1", "namespace2")
+                .addSchema("schemaTypes1", "schemaTypes2")
+                .setSnippetCount(5)
+                .setSnippetCountPerProperty(10)
+                .setMaxSnippetSize(15)
+                .setNumPerPage(42)
+                .setOrder(SearchSpec.ORDER_ASCENDING)
+                .setRankingStrategy(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE)
+                .build();
+
+        assertThat(searchSpec.getTermMatch()).isEqualTo(SearchSpec.TERM_MATCH_PREFIX);
+        assertThat(searchSpec.getNamespaces())
+                .containsExactly("namespace1", "namespace2").inOrder();
+        assertThat(searchSpec.getSchemas())
+                .containsExactly("schemaTypes1", "schemaTypes2").inOrder();
+        assertThat(searchSpec.getSnippetCount()).isEqualTo(5);
+        assertThat(searchSpec.getSnippetCountPerProperty()).isEqualTo(10);
+        assertThat(searchSpec.getMaxSnippetSize()).isEqualTo(15);
+        assertThat(searchSpec.getNumPerPage()).isEqualTo(42);
+        assertThat(searchSpec.getOrder()).isEqualTo(SearchSpec.ORDER_ASCENDING);
+        assertThat(searchSpec.getRankingStrategy())
+                .isEqualTo(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE);
+    }
+
+    @Test
+    public void testGetBundle() {
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
+                .addNamespace("namespace1", "namespace2")
+                .addSchema("schemaTypes1", "schemaTypes2")
+                .setSnippetCount(5)
+                .setSnippetCountPerProperty(10)
+                .setMaxSnippetSize(15)
+                .setNumPerPage(42)
+                .setOrder(SearchSpec.ORDER_ASCENDING)
+                .setRankingStrategy(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE)
+                .build();
+
+        Bundle bundle = searchSpec.getBundle();
+        assertThat(bundle.getInt(SearchSpec.TERM_MATCH_TYPE_FIELD))
+                .isEqualTo(SearchSpec.TERM_MATCH_PREFIX);
+        assertThat(bundle.getStringArrayList(SearchSpec.NAMESPACE_FIELD)).containsExactly(
+                "namespace1", "namespace2");
+        assertThat(bundle.getStringArrayList(SearchSpec.SCHEMA_TYPE_FIELD)).containsExactly(
+                "schemaTypes1", "schemaTypes2");
+        assertThat(bundle.getInt(SearchSpec.SNIPPET_COUNT_FIELD)).isEqualTo(5);
+        assertThat(bundle.getInt(SearchSpec.SNIPPET_COUNT_PER_PROPERTY_FIELD)).isEqualTo(10);
+        assertThat(bundle.getInt(SearchSpec.MAX_SNIPPET_FIELD)).isEqualTo(15);
+        assertThat(bundle.getInt(SearchSpec.NUM_PER_PAGE_FIELD)).isEqualTo(42);
+        assertThat(bundle.getInt(SearchSpec.ORDER_FIELD)).isEqualTo(SearchSpec.ORDER_ASCENDING);
+        assertThat(bundle.getInt(SearchSpec.RANKING_STRATEGY_FIELD))
+                .isEqualTo(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE);
+    }
+}
diff --git a/core/tests/coretests/src/android/app/appsearch/external/app/customer/CustomerDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/external/app/customer/CustomerDocumentTest.java
index 2c7c35f..d56d0c3 100644
--- a/core/tests/coretests/src/android/app/appsearch/external/app/customer/CustomerDocumentTest.java
+++ b/core/tests/coretests/src/android/app/appsearch/external/app/customer/CustomerDocumentTest.java
@@ -46,12 +46,12 @@
         CustomerDocument customerDocument = new CustomerDocument.Builder("uri1")
                 .setScore(1)
                 .setCreationTimestampMillis(0)
-                .setProperty("longKey1", 1L, 2L, 3L)
-                .setProperty("doubleKey1", 1.0, 2.0, 3.0)
-                .setProperty("booleanKey1", true, false, true)
-                .setProperty("stringKey1", "test-value1", "test-value2", "test-value3")
-                .setProperty("byteKey1", sByteArray1, sByteArray2)
-                .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2)
+                .setPropertyLong("longKey1", 1L, 2L, 3L)
+                .setPropertyDouble("doubleKey1", 1.0, 2.0, 3.0)
+                .setPropertyBoolean("booleanKey1", true, false, true)
+                .setPropertyString("stringKey1", "test-value1", "test-value2", "test-value3")
+                .setPropertyBytes("byteKey1", sByteArray1, sByteArray2)
+                .setPropertyDocument("documentKey1", sDocumentProperties1, sDocumentProperties2)
                 .build();
 
         assertThat(customerDocument.getUri()).isEqualTo("uri1");
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index a5b7c61..db838e8 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -17,7 +17,6 @@
 package android.view;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.view.ImeInsetsSourceConsumer.areEditorsSimilar;
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -33,11 +32,9 @@
 import android.graphics.Insets;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
 import android.view.WindowManager.BadTokenException;
 import android.view.WindowManager.LayoutParams;
-import android.view.inputmethod.EditorInfo;
 import android.widget.TextView;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -50,8 +47,6 @@
 import org.mockito.Mockito;
 import org.mockito.Spy;
 
-import java.util.ArrayList;
-
 /**
  * Test {@link InsetsSourceConsumer} with IME type.
  *
@@ -133,50 +128,4 @@
                     eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(true) /* fromIme */);
         });
     }
-
-    @Test
-    public void testAreEditorsSimilar() {
-        EditorInfo info1 = new EditorInfo();
-        info1.privateImeOptions = "dummy";
-        EditorInfo info2 = new EditorInfo();
-
-        assertFalse(areEditorsSimilar(info1, info2));
-
-        info1.privateImeOptions = null;
-        assertTrue(areEditorsSimilar(info1, info2));
-
-        info1.inputType = info2.inputType = 3;
-        info1.imeOptions = info2.imeOptions = 0x4;
-        info1.packageName = info2.packageName = "dummy.package";
-        assertTrue(areEditorsSimilar(info1, info2));
-
-        Bundle extras1 = new Bundle();
-        extras1.putByteArray("key1", "value1".getBytes());
-        extras1.putChar("key2", 'c');
-        Bundle extras2 = new Bundle();
-        extras2.putByteArray("key1", "value1".getBytes());
-        extras2.putChar("key2", 'c');
-        info1.extras = extras1;
-        info2.extras = extras2;
-        assertTrue(areEditorsSimilar(info1, info2));
-
-        Bundle extraBundle = new Bundle();
-        ArrayList<Integer> list = new ArrayList<>();
-        list.add(2);
-        list.add(5);
-        extraBundle.putByteArray("key1", "value1".getBytes());
-        extraBundle.putChar("key2", 'c');
-        extraBundle.putIntegerArrayList("key3", list);
-
-        extras1.putAll(extraBundle);
-        extras2.putAll(extraBundle);
-        assertTrue(areEditorsSimilar(info1, info2));
-
-        extras2.putChar("key2", 'd');
-        assertFalse(areEditorsSimilar(info1, info2));
-
-        extras2.putChar("key2", 'c');
-        extras2.putInt("key4", 1);
-        assertFalse(areEditorsSimilar(info1, info2));
-    }
 }
diff --git a/core/tests/coretests/src/android/widget/TextViewOnReceiveContentCallbackTest.java b/core/tests/coretests/src/android/widget/TextViewOnReceiveContentTest.java
similarity index 98%
rename from core/tests/coretests/src/android/widget/TextViewOnReceiveContentCallbackTest.java
rename to core/tests/coretests/src/android/widget/TextViewOnReceiveContentTest.java
index ef659af6..8efd3b4 100644
--- a/core/tests/coretests/src/android/widget/TextViewOnReceiveContentCallbackTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewOnReceiveContentTest.java
@@ -63,12 +63,12 @@
 
 /**
  * Tests for {@link TextViewOnReceiveContentCallback}. Most of the test cases are in the CTS test
- * {@link android.widget.cts.TextViewOnReceiveContentCallbackTest}. This class tests some internal
+ * {@link android.widget.cts.TextViewOnReceiveContentTest}. This class tests some internal
  * implementation details, e.g. fallback to the keyboard image API.
  */
 @MediumTest
 @RunWith(AndroidJUnit4.class)
-public class TextViewOnReceiveContentCallbackTest {
+public class TextViewOnReceiveContentTest {
     private static final Uri SAMPLE_CONTENT_URI = Uri.parse("content://com.example/path");
 
     @Rule
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index 8f5982c..7abcfdc 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -49,18 +49,38 @@
 
     public static final String INSTALL_AS_USER_ACTION = "android.credentials.INSTALL_AS_USER";
 
-    /** Key prefix for CA certificates. */
+    /**
+     * Key prefix for CA certificates.
+     *
+     * @deprecated Keystore no longer supports unstructured blobs. Public certificates are
+     *             stored in typed slots associated with a given alias.
+     */
+    @Deprecated
     public static final String CA_CERTIFICATE = "CACERT_";
 
-    /** Key prefix for user certificates. */
+    /**
+     * Key prefix for user certificates.
+     *
+     * @deprecated Keystore no longer supports unstructured blobs. Public certificates are
+     *             stored in typed slots associated with a given alias.
+     */
+    @Deprecated
     public static final String USER_CERTIFICATE = "USRCERT_";
 
-    /** Key prefix for user private and secret keys. */
+    /**
+     * Key prefix for user private and secret keys.
+     *
+     * @deprecated Keystore no longer uses alias prefixes to discriminate between entry types.
+     */
+    @Deprecated
     public static final String USER_PRIVATE_KEY = "USRPKEY_";
 
-    /** Key prefix for user secret keys.
-     *  @deprecated use {@code USER_PRIVATE_KEY} for this category instead.
+    /**
+     * Key prefix for user secret keys.
+     *
+     * @deprecated use {@code USER_PRIVATE_KEY} for this category instead.
      */
+    @Deprecated
     public static final String USER_SECRET_KEY = "USRSKEY_";
 
     /** Key prefix for VPN. */
@@ -72,7 +92,13 @@
     /** Key prefix for WIFI. */
     public static final String WIFI = "WIFI_";
 
-    /** Key prefix for App Source certificates. */
+    /**
+     * Key prefix for App Source certificates.
+     *
+     * @deprecated This was intended for FS-verity but never used. FS-verity is not
+     *             going to use this constant moving forward.
+     */
+    @Deprecated
     public static final String APP_SOURCE_CERTIFICATE = "FSV_";
 
     /** Key containing suffix of lockdown VPN profile. */
@@ -150,6 +176,7 @@
         pw.close();
         return bao.toByteArray();
     }
+
     /**
      * Convert objects from PEM format, which is used for
      * CA_CERTIFICATE and USER_CERTIFICATE entries.
@@ -167,7 +194,8 @@
             PemObject o;
             while ((o = pr.readPemObject()) != null) {
                 if (o.getType().equals("CERTIFICATE")) {
-                    Certificate c = cf.generateCertificate(new ByteArrayInputStream(o.getContent()));
+                    Certificate c = cf.generateCertificate(
+                            new ByteArrayInputStream(o.getContent()));
                     result.add((X509Certificate) c);
                 } else {
                     throw new IllegalArgumentException("Unknown type " + o.getType());
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index d5b34c4..1c1c2ee 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -16,9 +16,9 @@
 
 package android.security;
 
-import android.app.KeyguardManager;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.KeyguardManager;
 import android.content.Context;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
@@ -78,8 +78,6 @@
 
     private final Date mEndDate;
 
-    private final int mFlags;
-
     /**
      * Parameter specification for the "{@code AndroidKeyPairGenerator}"
      * instance of the {@link java.security.KeyPairGenerator} API. The
@@ -144,7 +142,6 @@
         mSerialNumber = serialNumber;
         mStartDate = startDate;
         mEndDate = endDate;
-        mFlags = flags;
     }
 
     /**
@@ -229,7 +226,7 @@
      * @hide
      */
     public int getFlags() {
-        return mFlags;
+        return 0;
     }
 
     /**
@@ -243,9 +240,15 @@
      * screen after boot.
      *
      * @see KeyguardManager#isDeviceSecure()
+     *
+     * @deprecated Encryption at rest is on by default. If extra binding to the lockscreen screen
+     *             credential is desired use
+     *             {@link KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)}.
+     *             This flag will be ignored from Android S.
      */
+    @Deprecated
     public boolean isEncryptionRequired() {
-        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
+        return false;
     }
 
     /**
@@ -292,8 +295,6 @@
 
         private Date mEndDate;
 
-        private int mFlags;
-
         /**
          * Creates a new instance of the {@code Builder} with the given
          * {@code context}. The {@code context} passed in may be used to pop up
@@ -431,10 +432,15 @@
          * secure lock screen after boot.
          *
          * @see KeyguardManager#isDeviceSecure()
+         *
+         * @deprecated Data at rest encryption is enabled by default. If extra binding to the
+         *             lockscreen credential is desired, use
+         *             {@link KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean)}.
+         *             This flag will be ignored from Android S.
          */
         @NonNull
+        @Deprecated
         public Builder setEncryptionRequired() {
-            mFlags |= KeyStore.FLAG_ENCRYPTED;
             return this;
         }
 
@@ -455,7 +461,7 @@
                     mSerialNumber,
                     mStartDate,
                     mEndDate,
-                    mFlags);
+                    0);
         }
     }
 }
diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
index 66c87ed..51d29b1 100644
--- a/keystore/java/android/security/KeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -48,18 +48,16 @@
  */
 @Deprecated
 public final class KeyStoreParameter implements ProtectionParameter {
-    private final int mFlags;
 
     private KeyStoreParameter(
             int flags) {
-        mFlags = flags;
     }
 
     /**
      * @hide
      */
     public int getFlags() {
-        return mFlags;
+        return 0;
     }
 
     /**
@@ -74,9 +72,16 @@
      * screen after boot.
      *
      * @see KeyguardManager#isDeviceSecure()
+     *
+     * @deprecated Data at rest encryption is enabled by default. If extra binding to the
+     *             lockscreen credential is desired, use
+     *             {@link android.security.keystore.KeyGenParameterSpec
+     *             .Builder#setUserAuthenticationRequired(boolean)}.
+     *             This flag will be ignored from Android S.
      */
+    @Deprecated
     public boolean isEncryptionRequired() {
-        return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
+        return false;
     }
 
     /**
@@ -100,7 +105,6 @@
      */
     @Deprecated
     public final static class Builder {
-        private int mFlags;
 
         /**
          * Creates a new instance of the {@code Builder} with the given
@@ -126,14 +130,15 @@
          * the user unlocks the secure lock screen after boot.
          *
          * @see KeyguardManager#isDeviceSecure()
+         *
+         * @deprecated Data at rest encryption is enabled by default. If extra binding to the
+         *             lockscreen credential is desired, use
+         *             {@link android.security.keystore.KeyGenParameterSpec
+         *             .Builder#setUserAuthenticationRequired(boolean)}.
+         *             This flag will be ignored from Android S.
          */
         @NonNull
         public Builder setEncryptionRequired(boolean required) {
-            if (required) {
-                mFlags |= KeyStore.FLAG_ENCRYPTED;
-            } else {
-                mFlags &= ~KeyStore.FLAG_ENCRYPTED;
-            }
             return this;
         }
 
@@ -145,8 +150,7 @@
          */
         @NonNull
         public KeyStoreParameter build() {
-            return new KeyStoreParameter(
-                    mFlags);
+            return new KeyStoreParameter(0 /* flags */);
         }
     }
 }
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 1d85e9f..b87a642 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -57,6 +57,9 @@
     <dimen name="pip_resize_handle_margin">4dp</dimen>
     <dimen name="pip_resize_handle_padding">0dp</dimen>
 
+    <!-- PIP stash offset size, which is the width of visible PIP region when stashed. -->
+    <dimen name="pip_stash_offset">32dp</dimen>
+
     <dimen name="dismiss_target_x_size">24dp</dimen>
     <dimen name="floating_dismiss_bottom_margin">50dp</dimen>
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index d4ff275..51ddb17 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -335,6 +335,12 @@
         listener = mTaskListeners.get(taskId);
         if (listener != null) return listener;
 
+        // Next priority goes to the listener listening to its parent.
+        if (runningTaskInfo.hasParentTask()) {
+            listener = mTaskListeners.get(runningTaskInfo.parentTaskId);
+            if (listener != null) return listener;
+        }
+
         // Next we try type specific listeners.
         final int taskListenerType = taskInfoToTaskListenerType(runningTaskInfo);
         return mTaskListeners.get(taskListenerType);
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 d0ab31d..fc523aef 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
@@ -37,6 +37,7 @@
 
     private final @NonNull Rect mBounds = new Rect();
     private float mAspectRatio;
+    private boolean mIsStashed;
     private PipReentryState mPipReentryState;
     private ComponentName mLastPipComponentName;
     private final DisplayInfo mDisplayInfo = new DisplayInfo();
@@ -54,6 +55,20 @@
         return new Rect(mBounds);
     }
 
+    /**
+     * Dictate where PiP currently should be stashed or not.
+     */
+    public void setStashed(boolean isStashed) {
+        mIsStashed = isStashed;
+    }
+
+    /**
+     * Whether PiP is stashed or not.
+     */
+    public boolean isStashed() {
+        return mIsStashed;
+    }
+
     public void setAspectRatio(float aspectRatio) {
         mAspectRatio = aspectRatio;
     }
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 f44ebf3..833924c 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
@@ -63,7 +63,6 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.pip.phone.PipMenuActivityController;
 import com.android.wm.shell.pip.phone.PipMotionHelper;
 import com.android.wm.shell.pip.phone.PipUpdateThread;
@@ -137,7 +136,6 @@
     private final PipBoundsState mPipBoundsState;
     private final PipBoundsHandler mPipBoundsHandler;
     private final PipMenuActivityController mMenuActivityController;
-    private final SystemWindows mSystemWindows;
     private final PipAnimationController mPipAnimationController;
     private final PipUiEventLogger mPipUiEventLoggerLogger;
     private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
@@ -270,14 +268,12 @@
             Optional<SplitScreen> splitScreenOptional,
             @NonNull DisplayController displayController,
             @NonNull PipUiEventLogger pipUiEventLogger,
-            @NonNull ShellTaskOrganizer shellTaskOrganizer,
-            @NonNull SystemWindows systemWindows) {
+            @NonNull ShellTaskOrganizer shellTaskOrganizer) {
         mMainHandler = new Handler(Looper.getMainLooper());
         mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
         mPipBoundsState = pipBoundsState;
         mPipBoundsHandler = boundsHandler;
         mMenuActivityController = menuActivityController;
-        mSystemWindows = systemWindows;
         mEnterExitAnimationDuration = context.getResources()
                 .getInteger(R.integer.config_pipResizeAnimationDuration);
         mSurfaceTransactionHelper = surfaceTransactionHelper;
@@ -499,9 +495,13 @@
         }
 
         if (mShouldIgnoreEnteringPipTransition) {
+            final Rect destinationBounds = mPipBoundsState.getBounds();
             // animation is finished in the Launcher and here we directly apply the final touch.
-            applyEnterPipSyncTransaction(mPipBoundsState.getBounds(),
-                    () -> sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP));
+            applyEnterPipSyncTransaction(destinationBounds, () -> {
+                // ensure menu's settled in its final bounds first
+                finishResizeForMenu(destinationBounds);
+                sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP);
+            });
             mShouldIgnoreEnteringPipTransition = false;
             return;
         }
@@ -995,16 +995,21 @@
             return;
         } else if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) {
             // TODO: Synchronize this correctly in #applyEnterPipSyncTransaction
-            runOnMainHandler(() -> {
-                mMenuActivityController.movePipMenu(null, null, destinationBounds);
-                mMenuActivityController.updateMenuBounds(destinationBounds);
-            });
+            finishResizeForMenu(destinationBounds);
             return;
         }
 
         WindowContainerTransaction wct = new WindowContainerTransaction();
         prepareFinishResizeTransaction(destinationBounds, direction, tx, wct);
         applyFinishBoundsResize(wct, direction);
+        finishResizeForMenu(destinationBounds);
+    }
+
+    private void finishResizeForMenu(Rect destinationBounds) {
+        if (mMenuActivityController == null) {
+            if (DEBUG) Log.d(TAG, "mMenuActivityController is null");
+            return;
+        }
         runOnMainHandler(() -> {
             mMenuActivityController.movePipMenu(null, null, destinationBounds);
             mMenuActivityController.updateMenuBounds(destinationBounds);
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 a525265..24144b2 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
@@ -305,8 +305,8 @@
     }
 
     private boolean maybeCreateSyncApplier() {
-        if (mPipMenuView == null) {
-            Log.v(TAG, "Not going to move PiP since the menu is not created.");
+        if (mPipMenuView == null || mPipMenuView.getViewRootImpl() == null) {
+            Log.v(TAG, "Not going to move PiP, either menu or its parent is not created.");
             return false;
         }
 
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 9240b3f..9247c68 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
@@ -33,6 +33,7 @@
 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;
@@ -60,7 +61,6 @@
     private static final int EXPAND_STACK_TO_MENU_DURATION = 250;
     private static final int LEAVE_PIP_DURATION = 300;
     private static final int SHIFT_DURATION = 300;
-    private static final float STASH_RATIO = 0.25f;
 
     /** Friction to use for PIP when it moves via physics fling animations. */
     private static final float DEFAULT_FRICTION = 2f;
@@ -94,6 +94,8 @@
     /** 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;
 
@@ -189,6 +191,7 @@
         mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback);
         mTemporaryBoundsPhysicsAnimator.setCustomAnimationHandler(
                 mSfAnimationHandlerThreadLocal.get());
+        reloadResources();
 
         mResizePipUpdateListener = (target, values) -> {
             if (!mTemporaryBounds.isEmpty()) {
@@ -198,6 +201,11 @@
         };
     }
 
+    void reloadResources() {
+        mStashOffset = mContext.getResources()
+                .getDimensionPixelSize(R.dimen.pip_stash_offset);
+    }
+
     @NonNull
     @Override
     public Rect getFloatingBoundsOnScreen() {
@@ -414,9 +422,10 @@
                         FloatProperties.RECT_Y, velocityY, mFlingConfigY, mSpringConfig)
                 .withEndActions(endAction);
 
-        final float offset = ((float) getBounds().width()) * (1.0f - STASH_RATIO);
-        final float leftEdge = isStash ? mMovementBounds.left - offset : mMovementBounds.left;
-        final float rightEdge = isStash ?  mMovementBounds.right + offset : mMovementBounds.right;
+        final float leftEdge = isStash ? mStashOffset - mPipBoundsState.getBounds().width()
+                : mMovementBounds.left;
+        final float rightEdge = isStash ?  mPipBoundsState.getDisplayBounds().right - mStashOffset
+                : mMovementBounds.right;
 
         final float xEndValue = velocityX < 0 ? leftEdge : rightEdge;
         final float estimatedFlingYEndValue =
@@ -524,9 +533,9 @@
                 DEFAULT_FRICTION, mMovementBounds.left, mMovementBounds.right);
         mFlingConfigY = new PhysicsAnimator.FlingConfig(
                 DEFAULT_FRICTION, mMovementBounds.top, mMovementBounds.bottom);
-        final float offset = ((float) getBounds().width()) * (1.0f - STASH_RATIO);
         mStashConfigX = new PhysicsAnimator.FlingConfig(
-                DEFAULT_FRICTION, mMovementBounds.left - offset, mMovementBounds.right + offset);
+                DEFAULT_FRICTION, mStashOffset - mPipBoundsState.getBounds().width(),
+                mPipBoundsState.getDisplayBounds().right - mStashOffset);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index ef38755..f3d8c7b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -47,6 +47,7 @@
 import com.android.internal.policy.TaskResizingAlgorithm;
 import com.android.wm.shell.R;
 import com.android.wm.shell.pip.PipBoundsHandler;
+import com.android.wm.shell.pip.PipBoundsState;
 import com.android.wm.shell.pip.PipTaskOrganizer;
 import com.android.wm.shell.pip.PipUiEventLogger;
 
@@ -67,6 +68,7 @@
     private final Context mContext;
     private final PipBoundsHandler mPipBoundsHandler;
     private final PipMotionHelper mMotionHelper;
+    private final PipBoundsState mPipBoundsState;
     private final int mDisplayId;
     private final Executor mMainExecutor;
     private final ScaleGestureDetector mScaleGestureDetector;
@@ -107,13 +109,15 @@
     private int mCtrlType;
 
     public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler,
-            PipMotionHelper motionHelper, PipTaskOrganizer pipTaskOrganizer,
-            Function<Rect, Rect> movementBoundsSupplier, Runnable updateMovementBoundsRunnable,
-            PipUiEventLogger pipUiEventLogger, PipMenuActivityController menuActivityController) {
+            PipBoundsState pipBoundsState, PipMotionHelper motionHelper,
+            PipTaskOrganizer pipTaskOrganizer, Function<Rect, Rect> movementBoundsSupplier,
+            Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger,
+            PipMenuActivityController menuActivityController) {
         mContext = context;
         mDisplayId = context.getDisplayId();
         mMainExecutor = context.getMainExecutor();
         mPipBoundsHandler = pipBoundsHandler;
+        mPipBoundsState = pipBoundsState;
         mMotionHelper = motionHelper;
         mPipTaskOrganizer = pipTaskOrganizer;
         mMovementBoundsSupplier = movementBoundsSupplier;
@@ -263,6 +267,11 @@
     }
 
     private void onInputEvent(InputEvent ev) {
+        // Don't allow resize when PiP is stashed.
+        if (mPipBoundsState.isStashed()) {
+            return;
+        }
+
         if (ev instanceof MotionEvent) {
             if (mUsingPinchToZoom) {
                 mScaleGestureDetector.onTouchEvent((MotionEvent) ev);
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 e95e4a0..d820e77 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
@@ -179,8 +179,8 @@
         mMotionHelper = new PipMotionHelper(mContext, pipBoundsState, pipTaskOrganizer,
                 mMenuController, mPipBoundsHandler.getSnapAlgorithm(), floatingContentCoordinator);
         mPipResizeGestureHandler =
-                new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper,
-                        pipTaskOrganizer, this::getMovementBounds,
+                new PipResizeGestureHandler(context, pipBoundsHandler, pipBoundsState,
+                        mMotionHelper, pipTaskOrganizer, this::getMovementBounds,
                         this::updateMovementBounds, pipUiEventLogger, menuController);
         mPipDismissTargetHandler = new PipDismissTargetHandler(context, pipUiEventLogger,
                 mMotionHelper, mHandler);
@@ -221,6 +221,7 @@
                 R.dimen.pip_expanded_shortest_edge_size);
         mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset);
         mPipDismissTargetHandler.updateMagneticTargetSize();
+        mMotionHelper.reloadResources();
     }
 
     private boolean shouldShowResizeHandle() {
@@ -463,7 +464,7 @@
         }
 
         MotionEvent ev = (MotionEvent) inputEvent;
-        if (mPipResizeGestureHandler.willStartResizeGesture(ev)) {
+        if (!mPipBoundsState.isStashed() && mPipResizeGestureHandler.willStartResizeGesture(ev)) {
             // Initialize the touch state for the gesture, but immediately reset to invalidate the
             // gesture
             mTouchState.onTouchEvent(ev);
@@ -553,6 +554,8 @@
             }
         }
 
+        shouldDeliverToMenu |= !mPipBoundsState.isStashed();
+
         // Deliver the event to PipMenuActivity to handle button click if the menu has shown.
         if (shouldDeliverToMenu) {
             final MotionEvent cloneEvent = MotionEvent.obtain(ev);
@@ -715,7 +718,7 @@
 
             // If the menu is still visible then just poke the menu
             // so that it will timeout after the user stops touching it
-            if (mMenuState != MENU_STATE_NONE) {
+            if (mMenuState != MENU_STATE_NONE && !mPipBoundsState.isStashed()) {
                 mMenuController.pokeMenu();
             }
         }
@@ -727,6 +730,7 @@
             }
 
             if (touchState.startedDragging()) {
+                mPipBoundsState.setStashed(false);
                 mSavedSnapFraction = -1f;
                 mPipDismissTargetHandler.showDismissTargetMaybe();
             }
@@ -785,12 +789,13 @@
                 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,
                             this::flingEndAction /* endAction */);
                 }
-            } else if (mTouchState.isDoubleTap()) {
+            } else if (mTouchState.isDoubleTap() && !mPipBoundsState.isStashed()) {
                 // If using pinch to zoom, double-tap functions as resizing between max/min size
                 if (mPipResizeGestureHandler.isUsingPinchToZoom()) {
                     final boolean toExpand =
@@ -809,7 +814,7 @@
                     setTouchEnabled(false);
                     mMotionHelper.expandLeavePip();
                 }
-            } else if (mMenuState != MENU_STATE_FULL) {
+            } else if (mMenuState != MENU_STATE_FULL && !mPipBoundsState.isStashed()) {
                 if (!mTouchState.isWaitingForDoubleTap()) {
                     // User has stalled long enough for this not to be a drag or a double tap, just
                     // expand the menu
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 69d428a..8b616e8 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
@@ -117,7 +117,7 @@
         mTransactionPool = transactionPool;
         mWindowManagerProxy = new WindowManagerProxy(syncQueue, shellTaskOrganizer);
         mTaskOrganizer = shellTaskOrganizer;
-        mSplits = new SplitScreenTaskListener(this, shellTaskOrganizer);
+        mSplits = new SplitScreenTaskListener(this, shellTaskOrganizer, syncQueue);
         mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler,
                 shellTaskOrganizer);
         mRotationController =
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 191a317..f709fed 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
@@ -27,8 +27,10 @@
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
 
 import android.app.ActivityManager.RunningTaskInfo;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.Log;
+import android.util.SparseArray;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 
@@ -36,6 +38,8 @@
 
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.Transitions;
+import com.android.wm.shell.common.SyncTransactionQueue;
 
 import java.io.PrintWriter;
 
@@ -44,6 +48,8 @@
     private static final boolean DEBUG = SplitScreenController.DEBUG;
 
     private final ShellTaskOrganizer mTaskOrganizer;
+    private final SyncTransactionQueue mSyncQueue;
+    private final SparseArray<SurfaceControl> mLeashByTaskId = new SparseArray<>();
 
     RunningTaskInfo mPrimary;
     RunningTaskInfo mSecondary;
@@ -58,9 +64,11 @@
     final SurfaceSession mSurfaceSession = new SurfaceSession();
 
     SplitScreenTaskListener(SplitScreenController splitScreenController,
-                    ShellTaskOrganizer shellTaskOrganizer) {
+                    ShellTaskOrganizer shellTaskOrganizer,
+                    SyncTransactionQueue syncQueue) {
         mSplitScreenController = splitScreenController;
         mTaskOrganizer = shellTaskOrganizer;
+        mSyncQueue = syncQueue;
     }
 
     void init() {
@@ -93,6 +101,11 @@
     @Override
     public void onTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
         synchronized (this) {
+            if (taskInfo.hasParentTask()) {
+                handleChildTaskAppeared(taskInfo, leash);
+                return;
+            }
+
             final int winMode = getWindowingMode(taskInfo);
             if (winMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
                 ProtoLog.v(WM_SHELL_TASK_ORG,
@@ -139,6 +152,11 @@
     @Override
     public void onTaskVanished(RunningTaskInfo taskInfo) {
         synchronized (this) {
+            if (taskInfo.hasParentTask()) {
+                mLeashByTaskId.remove(taskInfo.taskId);
+                return;
+            }
+
             final boolean isPrimaryTask = mPrimary != null
                     && taskInfo.token.equals(mPrimary.token);
             final boolean isSecondaryTask = mSecondary != null
@@ -165,7 +183,41 @@
         if (taskInfo.displayId != DEFAULT_DISPLAY) {
             return;
         }
-        mSplitScreenController.post(() -> handleTaskInfoChanged(taskInfo));
+        synchronized (this) {
+            if (taskInfo.hasParentTask()) {
+                handleChildTaskChanged(taskInfo);
+                return;
+            }
+
+            mSplitScreenController.post(() -> handleTaskInfoChanged(taskInfo));
+        }
+    }
+
+    private void handleChildTaskAppeared(RunningTaskInfo taskInfo, SurfaceControl leash) {
+        mLeashByTaskId.put(taskInfo.taskId, leash);
+        updateChildTaskSurface(taskInfo, leash, true /* firstAppeared */);
+    }
+
+    private void handleChildTaskChanged(RunningTaskInfo taskInfo) {
+        final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);
+        updateChildTaskSurface(taskInfo, leash, false /* firstAppeared */);
+    }
+
+    private void updateChildTaskSurface(
+            RunningTaskInfo taskInfo, SurfaceControl leash, boolean firstAppeared) {
+        final Rect taskBounds = taskInfo.getConfiguration().windowConfiguration.getBounds();
+        final Point taskPositionInParent = taskInfo.positionInParent;
+        final Rect corp =  new Rect(taskBounds);
+        corp.offset(-taskBounds.left, -taskBounds.top);
+        mSyncQueue.runInSync(t -> {
+            t.setWindowCrop(leash, corp);
+            t.setPosition(leash, taskPositionInParent.x, taskPositionInParent.y);
+            if (firstAppeared && !Transitions.ENABLE_SHELL_TRANSITIONS) {
+                t.setAlpha(leash, 1f);
+                t.setMatrix(leash, 1, 0, 0, 1);
+                t.show(leash);
+            }
+        });
     }
 
     /**
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index 35a2293c..e4155a2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -248,6 +248,20 @@
     }
 
     @Test
+    public void testGetParentTaskListener() {
+        RunningTaskInfo task1 = createTaskInfo(1, WINDOWING_MODE_MULTI_WINDOW);
+        TrackingTaskListener mwListener = new TrackingTaskListener();
+        mOrganizer.onTaskAppeared(task1, null);
+        mOrganizer.addListenerForTaskId(mwListener, task1.taskId);
+        RunningTaskInfo task2 = createTaskInfo(1, WINDOWING_MODE_MULTI_WINDOW);
+        task2.parentTaskId = task1.taskId;
+
+        mOrganizer.onTaskAppeared(task2, null);
+
+        assertTrue(mwListener.appeared.contains(task2));
+    }
+
+    @Test
     public void testTaskInfoToTaskListenerType_whenLetterboxBoundsPassed_returnsLetterboxType() {
         RunningTaskInfo taskInfo = createTaskInfo(
                 /* taskId */ 1,
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 ccc6797..39381c6 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
@@ -41,7 +41,6 @@
 
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.pip.phone.PipMenuActivityController;
 import com.android.wm.shell.splitscreen.SplitScreen;
 
@@ -69,7 +68,6 @@
     @Mock private PipUiEventLogger mMockPipUiEventLogger;
     @Mock private Optional<SplitScreen> mMockOptionalSplitScreen;
     @Mock private ShellTaskOrganizer mMockShellTaskOrganizer;
-    @Mock private SystemWindows mSystemWindows;
     private PipBoundsState mPipBoundsState;
 
     private ComponentName mComponent1;
@@ -84,7 +82,7 @@
         mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipBoundsState,
                 mMockPipBoundsHandler, mMenuActivityController, mMockPipSurfaceTransactionHelper,
                 mMockOptionalSplitScreen, mMockdDisplayController, mMockPipUiEventLogger,
-                mMockShellTaskOrganizer, mSystemWindows));
+                mMockShellTaskOrganizer));
         preparePipTaskOrg();
     }
 
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 1d06e28..a2861c2 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -943,7 +943,7 @@
          * with named endpoint channels. The samples in the frame correspond to the
          * named set bits in the channel position mask, in ascending bit order.
          * See {@link #setChannelIndexMask(int)} to specify channels
-         * based on endpoint numbered channels. This <a href="#channelPositionMask>description of
+         * based on endpoint numbered channels. This <a href="#channelPositionMask">description of
          * channel position masks</a> covers the concept in more details.
          * @param channelMask describes the configuration of the audio channels.
          *    <p> For output, the channelMask can be an OR-ed combination of
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 79b8611..610bffe 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -17,6 +17,7 @@
 package android.media;
 
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
@@ -58,6 +59,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @TestApi
     protected Image() {
     }
 
@@ -387,6 +389,7 @@
          * @hide
          */
         @UnsupportedAppUsage
+        @TestApi
         protected Plane() {
         }
 
diff --git a/media/java/android/media/tv/tuner/frontend/DtmbFrontendCapabilities.java b/media/java/android/media/tv/tuner/frontend/DtmbFrontendCapabilities.java
index 9fc3a23..dd386b0 100644
--- a/media/java/android/media/tv/tuner/frontend/DtmbFrontendCapabilities.java
+++ b/media/java/android/media/tv/tuner/frontend/DtmbFrontendCapabilities.java
@@ -25,7 +25,7 @@
  * @hide
  */
 @SystemApi
-public class DtmbFrontendCapabilities extends FrontendCapabilities {
+public final class DtmbFrontendCapabilities extends FrontendCapabilities {
     private final int mModulationCap;
     private final int mTransmissionModeCap;
     private final int mGuardIntervalCap;
diff --git a/media/java/android/media/tv/tuner/frontend/DtmbFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/DtmbFrontendSettings.java
index 2c3fe6a..d85e60d 100644
--- a/media/java/android/media/tv/tuner/frontend/DtmbFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/DtmbFrontendSettings.java
@@ -34,7 +34,7 @@
  * @hide
  */
 @SystemApi
-public class DtmbFrontendSettings extends FrontendSettings {
+public final class DtmbFrontendSettings extends FrontendSettings {
 
     /** @hide */
     @IntDef(flag = true,
diff --git a/media/java/android/media/tv/tuner/frontend/DvbcFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/DvbcFrontendSettings.java
index e6968bb..a611da6 100644
--- a/media/java/android/media/tv/tuner/frontend/DvbcFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/DvbcFrontendSettings.java
@@ -223,6 +223,40 @@
     public static final int TIME_INTERLEAVE_MODE_128_4 = android.hardware.tv.tuner.V1_1.Constants
             .FrontendCableTimeInterleaveMode.INTERLEAVING_128_4;
 
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "BANDWIDTH_",
+            value = {BANDWIDTH_UNDEFINED, BANDWIDTH_5MHZ, BANDWIDTH_6MHZ, BANDWIDTH_7MHZ,
+                    BANDWIDTH_8MHZ})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Bandwidth {}
+
+    /**
+     * Bandwidth undefined.
+     */
+    public static final int BANDWIDTH_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.UNDEFINED;
+    /**
+     * 5 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_5MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.BANDWIDTH_5MHZ;
+    /**
+     * 6 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_6MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.BANDWIDTH_6MHZ;
+    /**
+     * 7 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_7MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.BANDWIDTH_7MHZ;
+    /**
+     * 8 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_8MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.BANDWIDTH_8MHZ;
+
 
     private final int mModulation;
     private final long mInnerFec;
@@ -232,9 +266,11 @@
     private final int mSpectralInversion;
     // Dvbc time interleave mode is only supported in Tuner 1.1 or higher.
     private final int mInterleaveMode;
+    // Dvbc bandwidth is only supported in Tuner 1.1 or higher.
+    private final int mBandwidth;
 
     private DvbcFrontendSettings(int frequency, int modulation, long innerFec, int symbolRate,
-            int outerFec, int annex, int spectralInversion, int interleaveMode) {
+            int outerFec, int annex, int spectralInversion, int interleaveMode, int bandwidth) {
         super(frequency);
         mModulation = modulation;
         mInnerFec = innerFec;
@@ -243,6 +279,7 @@
         mAnnex = annex;
         mSpectralInversion = spectralInversion;
         mInterleaveMode = interleaveMode;
+        mBandwidth = bandwidth;
     }
 
     /**
@@ -293,6 +330,13 @@
     public int getTimeInterleaveMode() {
         return mInterleaveMode;
     }
+    /**
+     * Gets Bandwidth.
+     */
+    @Bandwidth
+    public int getBandwidth() {
+        return mBandwidth;
+    }
 
     /**
      * Creates a builder for {@link DvbcFrontendSettings}.
@@ -314,6 +358,7 @@
         private int mAnnex = ANNEX_UNDEFINED;
         private int mSpectralInversion = FrontendSettings.FRONTEND_SPECTRAL_INVERSION_UNDEFINED;
         private int mInterleaveMode = TIME_INTERLEAVE_MODE_UNDEFINED;
+        private int mBandwidth = BANDWIDTH_UNDEFINED;
 
         private Builder() {
         }
@@ -407,6 +452,23 @@
             }
             return this;
         }
+        /**
+         * Set the Bandwidth.
+         *
+         * <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.
+         *
+         * @param bandwidth the value to set as the bandwidth. Default value is
+         * {@link #BANDWIDTH_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setBandwidth(@Bandwidth int bandwidth) {
+            if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                        TunerVersionChecker.TUNER_VERSION_1_1, "setBandwidth")) {
+                mBandwidth = bandwidth;
+            }
+            return this;
+        }
 
         /**
          * Builds a {@link DvbcFrontendSettings} object.
@@ -414,7 +476,7 @@
         @NonNull
         public DvbcFrontendSettings build() {
             return new DvbcFrontendSettings(mFrequency, mModulation, mInnerFec, mSymbolRate,
-                mOuterFec, mAnnex, mSpectralInversion, mInterleaveMode);
+                mOuterFec, mAnnex, mSpectralInversion, mInterleaveMode, mBandwidth);
         }
     }
 
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
index dd9347c..c93e079 100644
--- a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
+++ b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java
@@ -17,6 +17,7 @@
 package android.media.tv.tuner.frontend;
 
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.hardware.tv.tuner.V1_0.Constants;
@@ -634,7 +635,7 @@
     }
 
     /**
-     * Gets an array of BERS status.
+     * Gets an array of extended bit error ratio status.
      *
      * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
@@ -650,12 +651,14 @@
     }
 
     /**
-     * Gets an array of code rates status.
+     * Gets an array of code rates status. The {@link FrontendSettings.InnerFec} would be used to
+     * show the code rate.
      *
      * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
+    @FrontendSettings.InnerFec
     public int[] getCodeRates() {
         TunerVersionChecker.checkHigherOrEqualVersionTo(
                 TunerVersionChecker.TUNER_VERSION_1_1, "getCodeRates status");
@@ -714,7 +717,8 @@
     }
 
     /**
-     * Gets UEC status.
+     * Gets the Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP) since the
+     * last tune operation.
      *
      * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
@@ -729,11 +733,12 @@
     }
 
     /**
-     * Gets system id status.
+     * Gets the current DVB-T2 system id status.
      *
      * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
+    @IntRange(from = 0, to = 0xffff)
     public int getSystemId() {
         TunerVersionChecker.checkHigherOrEqualVersionTo(
                 TunerVersionChecker.TUNER_VERSION_1_1, "getSystemId status");
@@ -744,13 +749,14 @@
     }
 
     /**
-     * Gets an array of interleaving status. Array value should be withink {@link
+     * Gets an array of interleaving status. Array value should be within {@link
      * FrontendInterleaveMode}.
      *
      * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
+    @FrontendInterleaveMode
     public int[] getInterleaving() {
         TunerVersionChecker.checkHigherOrEqualVersionTo(
                 TunerVersionChecker.TUNER_VERSION_1_1, "getInterleaving status");
@@ -761,12 +767,13 @@
     }
 
     /**
-     * Gets an array of isdbt segment status.
+     * Gets an array of the segments status in ISDB-T Specification of all the channels.
      *
      * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
+    @IntRange(from = 0, to = 0xff)
     public int[] getIsdbtSegment() {
         TunerVersionChecker.checkHigherOrEqualVersionTo(
                 TunerVersionChecker.TUNER_VERSION_1_1, "getIsdbtSegment status");
@@ -777,7 +784,7 @@
     }
 
     /**
-     * Gets an array of TS data rate status.
+     * Gets an array of the Transport Stream Data Rate in BPS of the current channel.
      *
      * <p>This status query is only supported by Tuner HAL 1.1 or higher. Use
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
@@ -800,9 +807,9 @@
      * {@link TunerVersionChecker.getTunerVersion()} to check the version.
      */
     @NonNull
-    public int[] getModulationsExt() {
+    public int[] getExtendedModulations() {
         TunerVersionChecker.checkHigherOrEqualVersionTo(
-                TunerVersionChecker.TUNER_VERSION_1_1, "getModulationsExt status");
+                TunerVersionChecker.TUNER_VERSION_1_1, "getExtendedModulations status");
         if (mModulationsExt == null) {
             throw new IllegalStateException();
         }
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 1be0d44..27e1992 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -140,6 +140,7 @@
 using ::android::hardware::tv::tuner::V1_1::FrontendAnalogSettingsExt1_1;
 using ::android::hardware::tv::tuner::V1_1::FrontendBandwidth;
 using ::android::hardware::tv::tuner::V1_1::FrontendCableTimeInterleaveMode;
+using ::android::hardware::tv::tuner::V1_1::FrontendDvbcBandwidth;
 using ::android::hardware::tv::tuner::V1_1::FrontendDvbsScanType;
 using ::android::hardware::tv::tuner::V1_1::FrontendDvbcSettingsExt1_1;
 using ::android::hardware::tv::tuner::V1_1::FrontendDvbsSettingsExt1_1;
@@ -2725,9 +2726,13 @@
     FrontendCableTimeInterleaveMode interleaveMode =
             static_cast<FrontendCableTimeInterleaveMode>(
                     env->GetIntField(settings, env->GetFieldID(clazz, "mInterleaveMode", "I")));
+    FrontendDvbcBandwidth bandwidth =
+            static_cast<FrontendDvbcBandwidth>(
+                    env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I")));
 
     FrontendDvbcSettingsExt1_1 dvbcExt1_1 {
         .interleaveMode = interleaveMode,
+        .bandwidth = bandwidth,
     };
     settingsExt1_1.settingExt.dvbc(dvbcExt1_1);
 }
diff --git a/packages/CompanionDeviceManager/res/layout/buttons.xml b/packages/CompanionDeviceManager/res/layout/buttons.xml
index 7de0035..b190a7f 100644
--- a/packages/CompanionDeviceManager/res/layout/buttons.xml
+++ b/packages/CompanionDeviceManager/res/layout/buttons.xml
@@ -30,13 +30,13 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@android:string/cancel"
-        style="@android:style/Widget.Material.Light.Button.Borderless.Colored"
+        style="@android:style/Widget.Material.Button.Borderless.Colored"
     />
     <Button
         android:id="@+id/button_pair"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@android:string/ok"
-        style="@android:style/Widget.Material.Light.Button.Borderless.Colored"
+        style="@android:style/Widget.Material.Button.Borderless.Colored"
     />
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/device_chooser.xml b/packages/CompanionDeviceManager/res/layout/device_chooser.xml
index 88de33f..db014ae 100644
--- a/packages/CompanionDeviceManager/res/layout/device_chooser.xml
+++ b/packages/CompanionDeviceManager/res/layout/device_chooser.xml
@@ -29,7 +29,7 @@
         android:layout_height="match_parent"
         android:layout_below="@+id/title"
         android:layout_above="@+id/buttons"
-        style="@android:style/Widget.Material.Light.ListView"
+        style="@android:style/Widget.Material.ListView"
     />
 
     <include layout="@layout/buttons" />
diff --git a/packages/CompanionDeviceManager/res/layout/title.xml b/packages/CompanionDeviceManager/res/layout/title.xml
index dfa71e2..0a44fbb 100644
--- a/packages/CompanionDeviceManager/res/layout/title.xml
+++ b/packages/CompanionDeviceManager/res/layout/title.xml
@@ -20,6 +20,5 @@
     android:id="@+id/title"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:textColor="@android:color/black"
     style="@*android:style/TextAppearance.Widget.Toolbar.Title"
 />
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/themes.xml b/packages/CompanionDeviceManager/res/values/themes.xml
index e3fc67c..66729347 100644
--- a/packages/CompanionDeviceManager/res/values/themes.xml
+++ b/packages/CompanionDeviceManager/res/values/themes.xml
@@ -21,6 +21,7 @@
         <item name="*android:windowFixedHeightMajor">100%</item>
         <item name="*android:windowFixedHeightMinor">100%</item>
         <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:forceDarkAllowed">true</item>
     </style>
 
 </resources>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index f108e06..c5876af 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -49,6 +49,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.net.wifi.WifiManager;
@@ -58,6 +59,8 @@
 import android.os.RemoteException;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.SparseArray;
+import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
@@ -317,6 +320,8 @@
         private Drawable BLUETOOTH_ICON = icon(android.R.drawable.stat_sys_data_bluetooth);
         private Drawable WIFI_ICON = icon(com.android.internal.R.drawable.ic_wifi_signal_3);
 
+        private SparseArray<Integer> mColors = new SparseArray();
+
         private Drawable icon(int drawableRes) {
             Drawable icon = getResources().getDrawable(drawableRes, null);
             icon.setTint(Color.DKGRAY);
@@ -343,24 +348,36 @@
             textView.setText(device.getDisplayName());
             textView.setBackgroundColor(
                     device.equals(mSelectedDevice)
-                            ? Color.GRAY
+                            ? getColor(android.R.attr.colorControlHighlight)
                             : Color.TRANSPARENT);
             textView.setCompoundDrawablesWithIntrinsicBounds(
                     device.device instanceof android.net.wifi.ScanResult
                         ? WIFI_ICON
                         : BLUETOOTH_ICON,
                     null, null, null);
+            textView.getCompoundDrawables()[0].setTint(getColor(android.R.attr.colorForeground));
         }
 
-        //TODO move to a layout file
         private TextView newView() {
             final TextView textView = new TextView(DeviceDiscoveryService.this);
-            textView.setTextColor(Color.BLACK);
+            textView.setTextColor(getColor(android.R.attr.colorForeground));
             final int padding = DeviceChooserActivity.getPadding(getResources());
             textView.setPadding(padding, padding, padding, padding);
             textView.setCompoundDrawablePadding(padding);
             return textView;
         }
+
+        private int getColor(int colorAttr) {
+            if (mColors.contains(colorAttr)) {
+                return mColors.get(colorAttr);
+            }
+            TypedValue typedValue = new TypedValue();
+            TypedArray a = obtainStyledAttributes(typedValue.data, new int[] { colorAttr });
+            int result = a.getColor(0, 0);
+            a.recycle();
+            mColors.put(colorAttr, result);
+            return result;
+        }
     }
 
     /**
diff --git a/packages/DynamicSystemInstallationService/res/values-af/strings.xml b/packages/DynamicSystemInstallationService/res/values-af/strings.xml
index 1829d34..1b300358 100644
--- a/packages/DynamicSystemInstallationService/res/values-af/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-af/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-am/strings.xml b/packages/DynamicSystemInstallationService/res/values-am/strings.xml
index 7fcc40d..a8a7b00 100644
--- a/packages/DynamicSystemInstallationService/res/values-am/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-am/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ar/strings.xml b/packages/DynamicSystemInstallationService/res/values-ar/strings.xml
index be705c3..44a6503 100644
--- a/packages/DynamicSystemInstallationService/res/values-ar/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ar/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-as/strings.xml b/packages/DynamicSystemInstallationService/res/values-as/strings.xml
index 14eead9..e93ad9b 100644
--- a/packages/DynamicSystemInstallationService/res/values-as/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-as/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-az/strings.xml b/packages/DynamicSystemInstallationService/res/values-az/strings.xml
index d1f0a4b..ad3d3e7 100644
--- a/packages/DynamicSystemInstallationService/res/values-az/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-az/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
index ea23a28..0107047 100644
--- a/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-b+sr+Latn/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-be/strings.xml b/packages/DynamicSystemInstallationService/res/values-be/strings.xml
index 7eef297..5a52f73 100644
--- a/packages/DynamicSystemInstallationService/res/values-be/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-be/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,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-bg/strings.xml b/packages/DynamicSystemInstallationService/res/values-bg/strings.xml
index 9176676..194bf2d 100644
--- a/packages/DynamicSystemInstallationService/res/values-bg/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-bg/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-bn/strings.xml b/packages/DynamicSystemInstallationService/res/values-bn/strings.xml
index 38ef649..43886b3 100644
--- a/packages/DynamicSystemInstallationService/res/values-bn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-bn/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-bs/strings.xml b/packages/DynamicSystemInstallationService/res/values-bs/strings.xml
index 84ba540..342230b2 100644
--- a/packages/DynamicSystemInstallationService/res/values-bs/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-bs/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ca/strings.xml b/packages/DynamicSystemInstallationService/res/values-ca/strings.xml
index 787e496..e9e4d35 100644
--- a/packages/DynamicSystemInstallationService/res/values-ca/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ca/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-cs/strings.xml b/packages/DynamicSystemInstallationService/res/values-cs/strings.xml
index 3dfb23f..6ae71c6 100644
--- a/packages/DynamicSystemInstallationService/res/values-cs/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-cs/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-da/strings.xml b/packages/DynamicSystemInstallationService/res/values-da/strings.xml
index 20005e7..10b798c 100644
--- a/packages/DynamicSystemInstallationService/res/values-da/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-da/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-de/strings.xml b/packages/DynamicSystemInstallationService/res/values-de/strings.xml
index 3f000ea..82459b2 100644
--- a/packages/DynamicSystemInstallationService/res/values-de/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-de/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-el/strings.xml b/packages/DynamicSystemInstallationService/res/values-el/strings.xml
index 4d830dd..ef02906 100644
--- a/packages/DynamicSystemInstallationService/res/values-el/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-el/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml
index d728631..6f3f887 100644
--- a/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-en-rAU/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml
index d728631..6f3f887 100644
--- a/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-en-rCA/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml
index d728631..6f3f887 100644
--- a/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-en-rGB/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml
index d728631..6f3f887 100644
--- a/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-en-rIN/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-en-rXC/strings.xml b/packages/DynamicSystemInstallationService/res/values-en-rXC/strings.xml
index 6ac3763..2e83672 100644
--- a/packages/DynamicSystemInstallationService/res/values-en-rXC/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-en-rXC/strings.xml
@@ -13,4 +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>
+    <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 9ec8196..aeb65be 100644
--- a/packages/DynamicSystemInstallationService/res/values-es-rUS/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-es-rUS/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-es/strings.xml b/packages/DynamicSystemInstallationService/res/values-es/strings.xml
index cd9db07..0c3ae53 100644
--- a/packages/DynamicSystemInstallationService/res/values-es/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-es/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-et/strings.xml b/packages/DynamicSystemInstallationService/res/values-et/strings.xml
index 64968b60..ab20a04 100644
--- a/packages/DynamicSystemInstallationService/res/values-et/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-et/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-eu/strings.xml b/packages/DynamicSystemInstallationService/res/values-eu/strings.xml
index 7c4a67d..1863778 100644
--- a/packages/DynamicSystemInstallationService/res/values-eu/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-eu/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-fa/strings.xml b/packages/DynamicSystemInstallationService/res/values-fa/strings.xml
index 7533e71..5b0b218 100644
--- a/packages/DynamicSystemInstallationService/res/values-fa/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-fa/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-fi/strings.xml b/packages/DynamicSystemInstallationService/res/values-fi/strings.xml
index 948c333..b4315e7 100644
--- a/packages/DynamicSystemInstallationService/res/values-fi/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-fi/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml b/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml
index 6e2f235..973efef 100644
--- a/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-fr-rCA/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-fr/strings.xml b/packages/DynamicSystemInstallationService/res/values-fr/strings.xml
index 67f7997..5422e8e 100644
--- a/packages/DynamicSystemInstallationService/res/values-fr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-fr/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-gl/strings.xml b/packages/DynamicSystemInstallationService/res/values-gl/strings.xml
index 8ea6d1c..e24f495a 100644
--- a/packages/DynamicSystemInstallationService/res/values-gl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-gl/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-gu/strings.xml b/packages/DynamicSystemInstallationService/res/values-gu/strings.xml
index aec1804..6c2e673 100644
--- a/packages/DynamicSystemInstallationService/res/values-gu/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-gu/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-hi/strings.xml b/packages/DynamicSystemInstallationService/res/values-hi/strings.xml
index efedbe8..13dc9e8 100644
--- a/packages/DynamicSystemInstallationService/res/values-hi/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-hi/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-hr/strings.xml b/packages/DynamicSystemInstallationService/res/values-hr/strings.xml
index 50ceaa1..3318d20 100644
--- a/packages/DynamicSystemInstallationService/res/values-hr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-hr/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-hu/strings.xml b/packages/DynamicSystemInstallationService/res/values-hu/strings.xml
index 94afa3b..208ab3b 100644
--- a/packages/DynamicSystemInstallationService/res/values-hu/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-hu/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-hy/strings.xml b/packages/DynamicSystemInstallationService/res/values-hy/strings.xml
index b0cd740..4dcc72e 100644
--- a/packages/DynamicSystemInstallationService/res/values-hy/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-hy/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-in/strings.xml b/packages/DynamicSystemInstallationService/res/values-in/strings.xml
index 44b4aee..2fa4f11 100644
--- a/packages/DynamicSystemInstallationService/res/values-in/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-in/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-is/strings.xml b/packages/DynamicSystemInstallationService/res/values-is/strings.xml
index 048d1bc..ef7484c 100644
--- a/packages/DynamicSystemInstallationService/res/values-is/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-is/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-it/strings.xml b/packages/DynamicSystemInstallationService/res/values-it/strings.xml
index f70b381..c8fa41b 100644
--- a/packages/DynamicSystemInstallationService/res/values-it/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-it/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-iw/strings.xml b/packages/DynamicSystemInstallationService/res/values-iw/strings.xml
index aff7c82..d9bf983 100644
--- a/packages/DynamicSystemInstallationService/res/values-iw/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-iw/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ja/strings.xml b/packages/DynamicSystemInstallationService/res/values-ja/strings.xml
index 46c0930..2082d91 100644
--- a/packages/DynamicSystemInstallationService/res/values-ja/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ja/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ka/strings.xml b/packages/DynamicSystemInstallationService/res/values-ka/strings.xml
index f841a59..e57de2c 100644
--- a/packages/DynamicSystemInstallationService/res/values-ka/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ka/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-kk/strings.xml b/packages/DynamicSystemInstallationService/res/values-kk/strings.xml
index d367b61..da10e9c 100644
--- a/packages/DynamicSystemInstallationService/res/values-kk/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-kk/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-km/strings.xml b/packages/DynamicSystemInstallationService/res/values-km/strings.xml
index 56a3716..7bb5980 100644
--- a/packages/DynamicSystemInstallationService/res/values-km/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-km/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-kn/strings.xml b/packages/DynamicSystemInstallationService/res/values-kn/strings.xml
index b4063df..f41f2ef 100644
--- a/packages/DynamicSystemInstallationService/res/values-kn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-kn/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ko/strings.xml b/packages/DynamicSystemInstallationService/res/values-ko/strings.xml
index 24ac924..bca9e07 100644
--- a/packages/DynamicSystemInstallationService/res/values-ko/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ko/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ky/strings.xml b/packages/DynamicSystemInstallationService/res/values-ky/strings.xml
index a4387e7..d2ad56a 100644
--- a/packages/DynamicSystemInstallationService/res/values-ky/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ky/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-lo/strings.xml b/packages/DynamicSystemInstallationService/res/values-lo/strings.xml
index f17ca16..a732aa4 100644
--- a/packages/DynamicSystemInstallationService/res/values-lo/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-lo/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-lt/strings.xml b/packages/DynamicSystemInstallationService/res/values-lt/strings.xml
index 8128eb7..b25c62a 100644
--- a/packages/DynamicSystemInstallationService/res/values-lt/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-lt/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-lv/strings.xml b/packages/DynamicSystemInstallationService/res/values-lv/strings.xml
index cfe7a08..4ca6ace 100644
--- a/packages/DynamicSystemInstallationService/res/values-lv/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-lv/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-mk/strings.xml b/packages/DynamicSystemInstallationService/res/values-mk/strings.xml
index 21215aa..52a52a5 100644
--- a/packages/DynamicSystemInstallationService/res/values-mk/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-mk/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ml/strings.xml b/packages/DynamicSystemInstallationService/res/values-ml/strings.xml
index 951a0b9..2504069 100644
--- a/packages/DynamicSystemInstallationService/res/values-ml/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ml/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-mn/strings.xml b/packages/DynamicSystemInstallationService/res/values-mn/strings.xml
index d0965d0..fe93f65 100644
--- a/packages/DynamicSystemInstallationService/res/values-mn/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-mn/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-mr/strings.xml b/packages/DynamicSystemInstallationService/res/values-mr/strings.xml
index 268e1d3..5f27af0 100644
--- a/packages/DynamicSystemInstallationService/res/values-mr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-mr/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ms/strings.xml b/packages/DynamicSystemInstallationService/res/values-ms/strings.xml
index bba8b97..797152c 100644
--- a/packages/DynamicSystemInstallationService/res/values-ms/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ms/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-my/strings.xml b/packages/DynamicSystemInstallationService/res/values-my/strings.xml
index b2488ec..3ee85b2 100644
--- a/packages/DynamicSystemInstallationService/res/values-my/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-my/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-nb/strings.xml b/packages/DynamicSystemInstallationService/res/values-nb/strings.xml
index 36e3d69..88087e5 100644
--- a/packages/DynamicSystemInstallationService/res/values-nb/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-nb/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ne/strings.xml b/packages/DynamicSystemInstallationService/res/values-ne/strings.xml
index ee92678..da98fee 100644
--- a/packages/DynamicSystemInstallationService/res/values-ne/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ne/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
index 2b9fa41..5120c90 100644
--- a/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-nl/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-or/strings.xml b/packages/DynamicSystemInstallationService/res/values-or/strings.xml
index e0c8470..878947e 100644
--- a/packages/DynamicSystemInstallationService/res/values-or/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-or/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pa/strings.xml b/packages/DynamicSystemInstallationService/res/values-pa/strings.xml
index c5f7a3d..2695aaf 100644
--- a/packages/DynamicSystemInstallationService/res/values-pa/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pa/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pl/strings.xml b/packages/DynamicSystemInstallationService/res/values-pl/strings.xml
index bc7d5fe..33592c8 100644
--- a/packages/DynamicSystemInstallationService/res/values-pl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pl/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml b/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml
index 31a9bb4..43bd021 100644
--- a/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pt-rBR/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml b/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml
index d917c6a..dc29a65 100644
--- a/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pt-rPT/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-pt/strings.xml b/packages/DynamicSystemInstallationService/res/values-pt/strings.xml
index 31a9bb4..43bd021 100644
--- a/packages/DynamicSystemInstallationService/res/values-pt/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-pt/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ro/strings.xml b/packages/DynamicSystemInstallationService/res/values-ro/strings.xml
index c211318..c9d391a 100644
--- a/packages/DynamicSystemInstallationService/res/values-ro/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ro/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ru/strings.xml b/packages/DynamicSystemInstallationService/res/values-ru/strings.xml
index bf94c99..cba9a71 100644
--- a/packages/DynamicSystemInstallationService/res/values-ru/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ru/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-si/strings.xml b/packages/DynamicSystemInstallationService/res/values-si/strings.xml
index e6a6ea2..7aab6e9 100644
--- a/packages/DynamicSystemInstallationService/res/values-si/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-si/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sk/strings.xml b/packages/DynamicSystemInstallationService/res/values-sk/strings.xml
index 99390cf..61c176f 100644
--- a/packages/DynamicSystemInstallationService/res/values-sk/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sk/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sl/strings.xml b/packages/DynamicSystemInstallationService/res/values-sl/strings.xml
index 3ffd741..0be1248 100644
--- a/packages/DynamicSystemInstallationService/res/values-sl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sl/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sq/strings.xml b/packages/DynamicSystemInstallationService/res/values-sq/strings.xml
index 704b512..43a5f7b 100644
--- a/packages/DynamicSystemInstallationService/res/values-sq/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sq/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sr/strings.xml b/packages/DynamicSystemInstallationService/res/values-sr/strings.xml
index 5e4540a..a5ba656 100644
--- a/packages/DynamicSystemInstallationService/res/values-sr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sr/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sv/strings.xml b/packages/DynamicSystemInstallationService/res/values-sv/strings.xml
index 546ffdd..99e6752 100644
--- a/packages/DynamicSystemInstallationService/res/values-sv/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sv/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-sw/strings.xml b/packages/DynamicSystemInstallationService/res/values-sw/strings.xml
index 53414d5..8af9ad3 100644
--- a/packages/DynamicSystemInstallationService/res/values-sw/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-sw/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ta/strings.xml b/packages/DynamicSystemInstallationService/res/values-ta/strings.xml
index e0aaaf7..bbe8c4e 100644
--- a/packages/DynamicSystemInstallationService/res/values-ta/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ta/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-te/strings.xml b/packages/DynamicSystemInstallationService/res/values-te/strings.xml
index d497630..4a9433e7 100644
--- a/packages/DynamicSystemInstallationService/res/values-te/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-te/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-th/strings.xml b/packages/DynamicSystemInstallationService/res/values-th/strings.xml
index 786324f..5b81a03 100644
--- a/packages/DynamicSystemInstallationService/res/values-th/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-th/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-tl/strings.xml b/packages/DynamicSystemInstallationService/res/values-tl/strings.xml
index df39f7b..d6c2f15 100644
--- a/packages/DynamicSystemInstallationService/res/values-tl/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-tl/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-tr/strings.xml b/packages/DynamicSystemInstallationService/res/values-tr/strings.xml
index 1446f96..a98526e 100644
--- a/packages/DynamicSystemInstallationService/res/values-tr/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-tr/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-uk/strings.xml b/packages/DynamicSystemInstallationService/res/values-uk/strings.xml
index 9a44d97..6526787 100644
--- a/packages/DynamicSystemInstallationService/res/values-uk/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-uk/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-ur/strings.xml b/packages/DynamicSystemInstallationService/res/values-ur/strings.xml
index 48dddbe..f5e2b74 100644
--- a/packages/DynamicSystemInstallationService/res/values-ur/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-ur/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,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-uz/strings.xml b/packages/DynamicSystemInstallationService/res/values-uz/strings.xml
index 3f0227c..3c347e2 100644
--- a/packages/DynamicSystemInstallationService/res/values-uz/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-uz/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-vi/strings.xml b/packages/DynamicSystemInstallationService/res/values-vi/strings.xml
index 18c051c..a93d29e 100644
--- a/packages/DynamicSystemInstallationService/res/values-vi/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-vi/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml b/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml
index b41d4e2..c27718e 100644
--- a/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-zh-rCN/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml b/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml
index c830dae..656c2af 100644
--- a/packages/DynamicSystemInstallationService/res/values-zh-rHK/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-zh-rHK/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,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml b/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml
index e43c0f2..a6f9b56 100644
--- a/packages/DynamicSystemInstallationService/res/values-zh-rTW/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-zh-rTW/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,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values-zu/strings.xml b/packages/DynamicSystemInstallationService/res/values-zu/strings.xml
index 4a48444..0cf79ba 100644
--- a/packages/DynamicSystemInstallationService/res/values-zu/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values-zu/strings.xml
@@ -13,4 +13,6 @@
     <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 />
 </resources>
diff --git a/packages/DynamicSystemInstallationService/res/values/strings.xml b/packages/DynamicSystemInstallationService/res/values/strings.xml
index 719fc73..bfeef0a 100644
--- a/packages/DynamicSystemInstallationService/res/values/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values/strings.xml
@@ -37,6 +37,9 @@
     <string name="toast_dynsystem_discarded">Discarded dynamic system</string>
     <!-- Toast when we fail to launch into Dynamic System [CHAR LIMIT=128] -->
     <string name="toast_failed_to_reboot_to_dynsystem">Can\u2019t restart or load dynamic system</string>
+    <!-- Toast when we fail to disable Dynamic System [CHAR LIMIT=128] -->
+    <string name="toast_failed_to_disable_dynsystem">Failed to disable dynamic system</string>
+
 
     <!-- URL of Dynamic System Key Revocation List [DO NOT TRANSLATE] -->
     <string name="key_revocation_list_url" translatable="false">https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json</string>
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index 12505bc..ac27580 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -375,8 +375,17 @@
             return;
         }
 
-        // Per current design, we don't have disable() API. AOT is disabled on next reboot.
-        // TODO: Use better status query when b/125079548 is done.
+        if (!mDynSystem.setEnable(/* enable = */ false, /* oneShot = */ false)) {
+            Log.e(TAG, "Failed to disable DynamicSystem.");
+
+            // Dismiss status bar and show a toast.
+            sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+            Toast.makeText(this,
+                    getString(R.string.toast_failed_to_disable_dynsystem),
+                    Toast.LENGTH_LONG).show();
+            return;
+        }
+
         PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
 
         if (powerManager != null) {
diff --git a/packages/SettingsLib/HelpUtils/res/values-es/strings.xml b/packages/SettingsLib/HelpUtils/res/values-es/strings.xml
index 97ff5ef..97e3559 100644
--- a/packages/SettingsLib/HelpUtils/res/values-es/strings.xml
+++ b/packages/SettingsLib/HelpUtils/res/values-es/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="help_feedback_label" msgid="7106780063063027882">"Ayuda y sugerencias"</string>
+    <string name="help_feedback_label" msgid="7106780063063027882">"Ayuda y comentarios"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index dd1c12a..6a563f3 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -550,9 +550,9 @@
     <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>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 08a2b99..90d49e2 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>
diff --git a/packages/SettingsProvider/src/android/provider/settings/OWNERS b/packages/SettingsProvider/src/android/provider/settings/OWNERS
index 541dd878..7e7710b 100644
--- a/packages/SettingsProvider/src/android/provider/settings/OWNERS
+++ b/packages/SettingsProvider/src/android/provider/settings/OWNERS
@@ -1,5 +1,4 @@
-# Please reach out to Android B&R when making Settings backup changes
-alsutton@google.com
-nathch@google.com
-rthakohov@google.com
+# Bug component: 656484
+
+include platform/frameworks/base/services/backup:/OWNERS
 
diff --git a/packages/SettingsProvider/test/src/android/provider/OWNERS b/packages/SettingsProvider/test/src/android/provider/OWNERS
index f3241ea..7e7710b 100644
--- a/packages/SettingsProvider/test/src/android/provider/OWNERS
+++ b/packages/SettingsProvider/test/src/android/provider/OWNERS
@@ -1,4 +1,4 @@
-per-file * = *
+# Bug component: 656484
 
-# Please reach out to the Android B&R team for settings backup changes
-per-file SettingsBackupTest.java = alsutton@google.com, nathch@google.com, rthakohov@google.com
+include platform/frameworks/base/services/backup:/OWNERS
+
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index baa266a..2412a32 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -229,6 +229,7 @@
                     Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM,
                     Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR,
                     Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_SV,
+                    Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR,
                     Settings.Global.DEVICE_DEMO_MODE,
                     Settings.Global.BATTERY_SAVER_ADAPTIVE_CONSTANTS,
                     Settings.Global.BATTERY_SAVER_CONSTANTS,
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index 3714db3..939c5f9 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -73,7 +73,7 @@
             android:id="@+id/gradient_clock_view"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textSize="100dp"
+            android:textSize="80dp"
             android:letterSpacing="0.02"
             android:lineSpacingMultiplier=".8"
             android:includeFontPadding="false"
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 0a33d5e..b2c968c 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -24,7 +24,7 @@
     android:clipChildren="false"
     android:clipToPadding="true"
     android:orientation="vertical"
-    android:paddingStart="@*android:dimen/notification_content_margin_start">
+    android:paddingStart="@dimen/notification_shade_content_margin_horizontal">
 
     <!-- Package Info -->
     <LinearLayout
@@ -120,7 +120,7 @@
         android:id="@+id/inline_controls"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingEnd="@*android:dimen/notification_content_margin_end"
+        android:paddingEnd="@dimen/notification_shade_content_margin_horizontal"
         android:layout_marginTop="@dimen/notification_guts_option_vertical_padding"
         android:clipChildren="false"
         android:clipToPadding="false"
diff --git a/packages/SystemUI/res/layout/partial_conversation_info.xml b/packages/SystemUI/res/layout/partial_conversation_info.xml
index af66f8b..9ed3f92 100644
--- a/packages/SystemUI/res/layout/partial_conversation_info.xml
+++ b/packages/SystemUI/res/layout/partial_conversation_info.xml
@@ -24,7 +24,7 @@
     android:clipChildren="false"
     android:clipToPadding="true"
     android:orientation="vertical"
-    android:paddingStart="@*android:dimen/notification_content_margin_start">
+    android:paddingStart="@dimen/notification_shade_content_margin_horizontal">
 
     <!-- Package Info -->
     <LinearLayout
@@ -93,7 +93,7 @@
         android:id="@+id/inline_controls"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingEnd="@*android:dimen/notification_content_margin_end"
+        android:paddingEnd="@dimen/notification_shade_content_margin_horizontal"
         android:layout_marginTop="@dimen/notification_guts_option_vertical_padding"
         android:clipChildren="false"
         android:clipToPadding="false"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 220a773..4042ef9 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index b2a7c16..e8a8a0d 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 2cced23..83940bf 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -532,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>
@@ -556,6 +559,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 +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وتجدر الإشارة إلى أنك متصل أيضًا بشبكة افتراضية خاصة يمكن أن تراقب نشاط الشبكة."</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>
@@ -1113,4 +1118,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 4c43e4e..5444b53 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 4cefd84..f97b334 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <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..48e5b72 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -523,6 +525,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 +550,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 +574,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>
@@ -1095,4 +1100,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 6396cbe..ed57fb3 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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">"2 планкі тэлефона."</string>
@@ -526,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>
@@ -550,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>
@@ -573,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>
@@ -1101,4 +1106,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 26a313a..c968e6d 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index c4c6a0c..c225fd3 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,8 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"প্রোফাইল পর্যবেক্ষণ করা হতে পারে"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"নেটওয়ার্ক নিরীক্ষণ করা হতে পারে"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"নেটওয়ার্ক নিরীক্ষণ করা হতে পারে"</string>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 75a2d1c..344bb63 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -523,6 +525,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 +550,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 +574,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>
@@ -1095,4 +1100,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 2b6dfd5..0ed3ac1 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -446,7 +448,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 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index f00c279..156b65d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -526,6 +528,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 +553,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 +577,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>
@@ -1101,4 +1106,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 9d365c3..d4761d5 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 55e7d17..3aff4c8 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,8 @@
     <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>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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 +548,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 3bb15ff..1a6998e 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index a743bbe..fe1d841 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -182,6 +182,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>
@@ -520,6 +521,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 +546,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 +570,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>
@@ -1089,4 +1093,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.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 3fe7a6a..a2307e7 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -182,6 +182,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>
@@ -520,6 +521,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 +546,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 +570,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>
@@ -1089,4 +1093,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.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index a743bbe..50288b2 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index a743bbe..50288b2 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 78006fd..fe7f4e0 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -182,6 +182,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>
@@ -520,6 +521,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 +546,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 +570,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>
@@ -1089,4 +1093,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-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index d30a395..d6c5e15 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,8 @@
     <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>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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 +548,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 875c310..9726134 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f9940a3..d8ec8be 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index cb86a16..8aa247f 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index afa0759..d4f6252 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 11c7e19..0ed1509 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index b8ea6ac..c7e827f 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 votre 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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 289ce40..781a43ce 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index e3d3755..80fb402 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,8 @@
     <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>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 02c72db..85a084d 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -331,10 +333,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 +522,8 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"પ્રોફાઇલ મૉનિટર કરી શકાય છે"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"નેટવર્ક મૉનિટર કરી શકાય છે"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"નેટવર્ક મૉનિટર કરવામાં આવી શકે છે"</string>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -585,7 +593,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>
@@ -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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 3f497e7..9eeba17 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -522,6 +524,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 +549,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 +573,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>
@@ -1091,4 +1096,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 9958a2c..86523ec 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -523,6 +525,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 vaš 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 +550,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 +574,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 vaš roditelj. Vaš roditelj može vidjeti podatke, kao što su aplikacije koje koristite, lokacija 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>
@@ -1095,4 +1100,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 0159ec6..32ca37d 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 1d80192..15fbf70 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 9aaf270..cf6a20d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index bf49e97..ca40b6f 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 8e665ec..f3436e9 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 052b721..fc915a1 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -526,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>
@@ -550,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>
@@ -573,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>
@@ -1101,4 +1106,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 7e64155f..74fd16a 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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">"電波状態:レベル1"</string>
     <string name="accessibility_phone_two_bars" msgid="3316909612598670674">"電波状態:レベル2"</string>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 97aea29..b32937e 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index a6376e3..c01af11 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index b8d2fa8..652bf25 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>
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -498,9 +500,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 +522,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 +547,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 +571,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>
@@ -774,7 +779,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 +967,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 5c502ac..aa6c34e 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,8 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ಪ್ರೊಫೈಲ್ ಅನ್ನು ಪರಿವೀಕ್ಷಿಸಬಹುದಾಗಿದೆ"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ವೀಕ್ಷಿಸಬಹುದಾಗಿ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ವೀಕ್ಷಿಸಬಹುದಾಗಿರುತ್ತದೆ"</string>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index cef5158..38648d0 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 572c3e7..2a4e077 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 1cc1b4e..93ecff09 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -182,6 +182,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>
@@ -520,6 +521,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 +546,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 +570,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>
@@ -1089,4 +1093,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-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 152a532..ec102b7 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -526,6 +528,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 +553,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 +577,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>
@@ -1101,4 +1106,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index ae67d0f..9c12665 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -523,6 +525,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 +550,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 +574,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>
@@ -1095,4 +1100,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index fca688d..a67e3b5 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index cd75761..3b6c616 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 4eb2fb1..ef110e9 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 57c1e07..9b3ee71 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,8 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"प्रोफाईलचे परीक्षण केले जाऊ शकते"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"नेटवर्कचे परीक्षण केले जाऊ शकते"</string>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 058055f..55f1e32 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 5249efa..18e804b 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index b676e91..8becc3b 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index c3c8903..eac89c2 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,8 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"प्रोफाइल अनुगमन हुन सक्छ"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"सञ्जाल अनुगमित हुन सक्छ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"नेटवर्कको अनुगमन गरिने सम्भावना छ"</string>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 691bfcb..d1134d3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index de48527..264076f 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,8 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ପ୍ରୋଫାଇଲ୍ ନିରୀକ୍ଷଣ କରାଯାଇପାରେ।"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ନେଟ୍‌ୱର୍କ ନୀରିକ୍ଷଣ କରାଯାଇପାରେ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ନେଟ୍‌ୱର୍କକୁ ନିରୀକ୍ଷଣ କରାଯାଇପାରେ"</string>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 13f4506..d05f80d 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,8 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"ਪ੍ਰੋਫਾਈਲ ਦਾ ਨਿਰੀਖਣ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"ਨੈੱਟਵਰਕ ਦਾ ਨਿਰੀਖਣ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"ਹੋ ਸਕਦਾ ਹੈ ਨੈੱਟਵਰਕ ਦੀ ਨਿਗਰਾਨੀ ਹੋ ਰਹੀ ਹੋਵੇ"</string>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 6da167d..7343b26 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -526,6 +528,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 +553,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 +577,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>
@@ -1101,4 +1106,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 0db05d8..344671d 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 147ed1d..709f532 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 0db05d8..344671d 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 24e71fb..6c54460 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -523,6 +525,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 +550,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 +574,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>
@@ -1095,4 +1100,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 1ca1c80..53773cf 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -526,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>
@@ -550,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>
@@ -573,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>
@@ -1101,4 +1106,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index eb789c1..afd556a 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 9ec0771..4c518dc 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -526,6 +528,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 +553,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 +577,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>
@@ -1101,4 +1106,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 14f6553..f459bc8 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -526,6 +528,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 +553,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 +577,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>
@@ -1101,4 +1106,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 87ca508..73408ce 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 1ad7a91..d173f00 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -523,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>
@@ -547,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\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 +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>
@@ -1095,4 +1100,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index d34c814..b79fb40 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index eab7f69..2e4c91d 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index a72ebef..97240d9 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 0d23f25..7100c33 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 094cb76..8db84b8 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 8ef1869..09f8a71 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index c17c8f7..89d7374 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7dcfc3b..f196293 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -526,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>
@@ -550,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\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 +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>
@@ -1101,4 +1106,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 4c0ebaa..6973c5e 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,8 @@
     <string name="profile_owned_footer" msgid="2756770645766113964">"پروفائل کو مانیٹر کیا جا سکتا ہے"</string>
     <string name="vpn_footer" msgid="3457155078010607471">"نیٹ ورک کو مانیٹر کیا جا سکتا ہے"</string>
     <string name="branded_vpn_footer" msgid="816930186313188514">"نیٹ ورک کو شاید مانیٹر کیا جائے"</string>
+    <!-- no translation found for quick_settings_disclosure_parental_controls (2114102871438223600) -->
+    <skip />
     <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,8 @@
     <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>
+    <!-- no translation found for monitoring_button_view_controls (8316440345340701117) -->
+    <skip />
     <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 +573,8 @@
     <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>
+    <!-- no translation found for monitoring_description_parental_controls (8184693528917051626) -->
+    <skip />
     <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>
@@ -1089,4 +1097,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 33d4f4c..a97f1e4 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 179f7c2..4a69cc7 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index e1f483c..9c34b31 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index f986ef33..2e22b07 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index b442b79..0cc17ef 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- 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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 764f0b7..9e85eed 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -182,6 +182,8 @@
     <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>
+    <!-- no translation found for accessibility_battery_unknown (1807789554617976440) -->
+    <skip />
     <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>
@@ -520,6 +522,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 +547,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 +571,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>
@@ -1089,4 +1094,8 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhanqa 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>
+    <!-- no translation found for battery_state_unknown_notification_title (8464703640483773454) -->
+    <skip />
+    <!-- no translation found for battery_state_unknown_notification_text (13720937839460899) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1ab776b..17dc400 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -623,6 +623,9 @@
         @dimen/notification_divider_height
     </dimen>
 
+    <!-- The horizontal margin of the content in the notification shade -->
+    <dimen name="notification_shade_content_margin_horizontal">16dp</dimen>
+
     <!-- The top margin for the notification children container in its non-expanded form. -->
     <dimen name="notification_children_container_margin_top">
         @*android:dimen/notification_content_margin_top
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 2e845fb..0e6bc24 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -94,6 +94,7 @@
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
+import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -235,6 +236,7 @@
     private final Context mContext;
     private final boolean mIsPrimaryUser;
     private final boolean mIsAutomotive;
+    private final AuthController mAuthController;
     private final StatusBarStateController mStatusBarStateController;
     HashMap<Integer, SimData> mSimDatas = new HashMap<>();
     HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
@@ -1581,7 +1583,8 @@
             RingerModeTracker ringerModeTracker,
             @Background Executor backgroundExecutor,
             StatusBarStateController statusBarStateController,
-            LockPatternUtils lockPatternUtils) {
+            LockPatternUtils lockPatternUtils,
+            AuthController authController) {
         mContext = context;
         mSubscriptionManager = SubscriptionManager.from(context);
         mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
@@ -1591,6 +1594,7 @@
         mRingerModeTracker = ringerModeTracker;
         mStatusBarStateController = statusBarStateController;
         mLockPatternUtils = lockPatternUtils;
+        mAuthController = authController;
         dumpManager.registerDumpable(getClass().getName(), this);
 
         mHandler = new Handler(mainLooper) {
@@ -1853,7 +1857,7 @@
 
     private void updateLockScreenMode() {
         mLockScreenMode = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.SHOW_NEW_LOCKSCREEN, 0);
+                Settings.Global.SHOW_NEW_LOCKSCREEN, mAuthController.isUdfpsEnrolled() ? 1 : 0);
     }
 
     private final UserSwitchObserver mUserSwitchObserver = new UserSwitchObserver() {
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index d8e94bb..b30103e 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -188,7 +188,7 @@
      * This method is overridden in vendor specific implementation of Sys UI.
      */
     public BackGestureTfClassifierProvider createBackGestureTfClassifierProvider(
-            AssetManager am) {
+            AssetManager am, String modelName) {
         return new BackGestureTfClassifierProvider();
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index 64a2aca..e40185c 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -32,6 +32,7 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
@@ -67,7 +68,7 @@
     private final int mTapTimeout = ViewConfiguration.getTapTimeout();
     private final int mTouchSlop;
     private int mMagnificationMode = Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
-    private final WindowManager.LayoutParams mParams;
+    private final LayoutParams mParams;
     private boolean mIsVisible = false;
 
     MagnificationModeSwitch(Context context) {
@@ -80,7 +81,7 @@
         mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
         mWindowManager = (WindowManager) mContext.getSystemService(
                 Context.WINDOW_SERVICE);
-        mParams = createLayoutParams();
+        mParams = createLayoutParams(context);
         mImageView = imageView;
         mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
         applyResourcesValues();
@@ -221,11 +222,22 @@
     }
 
     void onConfigurationChanged(int configDiff) {
-        if ((configDiff & ActivityInfo.CONFIG_DENSITY) == 0) {
+        if ((configDiff & ActivityInfo.CONFIG_DENSITY) != 0) {
+            applyResourcesValues();
+            mImageView.setImageResource(getIconResId(mMagnificationMode));
             return;
         }
-        applyResourcesValues();
-        mImageView.setImageResource(getIconResId(mMagnificationMode));
+        if ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0) {
+            updateAccessibilityWindowTitle();
+            return;
+        }
+    }
+
+    private void updateAccessibilityWindowTitle() {
+        mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
+        if (mIsVisible) {
+            mWindowManager.updateViewLayout(mImageView, mParams);
+        }
     }
 
     private void toggleMagnificationMode() {
@@ -261,14 +273,19 @@
                 : R.drawable.ic_open_in_new_fullscreen;
     }
 
-    private static WindowManager.LayoutParams createLayoutParams() {
-        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
-                WindowManager.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+    private static LayoutParams createLayoutParams(Context context) {
+        final LayoutParams params = new LayoutParams(
+                LayoutParams.WRAP_CONTENT,
+                LayoutParams.WRAP_CONTENT,
+                LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
+                LayoutParams.FLAG_NOT_FOCUSABLE,
                 PixelFormat.TRANSPARENT);
         params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
+        params.accessibilityTitle = getAccessibilityWindowTitle(context);
         return params;
     }
+
+    private static String getAccessibilityWindowTitle(Context context) {
+        return context.getString(com.android.internal.R.string.android_system_label);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index e9e453b..98424be 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -53,7 +53,8 @@
         CommandQueue.Callbacks {
     private static final String TAG = "WindowMagnification";
     private static final int CONFIG_MASK =
-            ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_ORIENTATION;
+            ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_ORIENTATION
+                    | ActivityInfo.CONFIG_LOCALE;
 
     @VisibleForTesting
     protected WindowMagnificationAnimationController mWindowMagnificationAnimationController;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 340ca04..fd89baa 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.accessibility;
 
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+import static android.view.WindowManager.LayoutParams;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 
@@ -254,9 +254,18 @@
             }
         } else if ((configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
             onRotate();
+        } else if ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0) {
+            updateAccessibilityWindowTitleIfNeeded();
         }
     }
 
+    private void updateAccessibilityWindowTitleIfNeeded() {
+        if (!isWindowVisible()) return;
+        LayoutParams params = (LayoutParams) mMirrorView.getLayoutParams();
+        params.accessibilityTitle = getAccessibilityWindowTitle();
+        mWm.updateViewLayout(mMirrorView, params);
+    }
+
     /** Handles MirrorWindow position when the navigation bar mode changed. */
     public void onNavigationModeChanged(int mode) {
         mNavBarMode = mode;
@@ -290,8 +299,8 @@
             return;
         }
         // The rect of MirrorView is going to be transformed.
-        WindowManager.LayoutParams params =
-                (WindowManager.LayoutParams) mMirrorView.getLayoutParams();
+        LayoutParams params =
+                (LayoutParams) mMirrorView.getLayoutParams();
         mTmpRect.set(params.x, params.y, params.x + params.width, params.y + params.height);
         final RectF transformedRect = new RectF(mTmpRect);
         matrix.mapRect(transformedRect);
@@ -313,17 +322,18 @@
         int windowWidth = mMagnificationFrame.width() + 2 * mMirrorSurfaceMargin;
         int windowHeight = mMagnificationFrame.height() + 2 * mMirrorSurfaceMargin;
 
-        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+        LayoutParams params = new LayoutParams(
                 windowWidth, windowHeight,
-                WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
-                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
+                LayoutParams.FLAG_NOT_TOUCH_MODAL
+                        | LayoutParams.FLAG_NOT_FOCUSABLE,
                 PixelFormat.TRANSPARENT);
         params.gravity = Gravity.TOP | Gravity.LEFT;
         params.x = mMagnificationFrame.left - mMirrorSurfaceMargin;
         params.y = mMagnificationFrame.top - mMirrorSurfaceMargin;
-        params.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+        params.layoutInDisplayCutoutMode = LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
         params.setTitle(mContext.getString(R.string.magnification_window_title));
+        params.accessibilityTitle = getAccessibilityWindowTitle();
 
         mMirrorView = LayoutInflater.from(mContext).inflate(R.layout.window_magnifier_view, null);
         mMirrorSurfaceView = mMirrorView.findViewById(R.id.surface_view);
@@ -369,6 +379,10 @@
         return regionInsideDragBorder;
     }
 
+    private String getAccessibilityWindowTitle() {
+        return mResources.getString(com.android.internal.R.string.android_system_label);
+    }
+
     private void showControls() {
         if (mMirrorWindowControl != null) {
             mMirrorWindowControl.showControl();
@@ -432,8 +446,8 @@
         }
         final int maxMirrorViewX = mDisplaySize.x - mMirrorView.getWidth();
         final int maxMirrorViewY = mDisplaySize.y - mMirrorView.getHeight() - mNavGestureHeight;
-        WindowManager.LayoutParams params =
-                (WindowManager.LayoutParams) mMirrorView.getLayoutParams();
+        LayoutParams params =
+                (LayoutParams) mMirrorView.getLayoutParams();
         params.x = mMagnificationFrame.left - mMirrorSurfaceMargin;
         params.y = mMagnificationFrame.top - mMirrorSurfaceMargin;
         // If nav bar mode supports swipe-up gesture, the Y position of mirror view should not
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 874c73b..c72bc25 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -29,6 +29,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.Configuration;
+import android.graphics.RectF;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.IBiometricSysuiReceiver;
@@ -42,6 +43,7 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.util.Log;
+import android.view.MotionEvent;
 import android.view.WindowManager;
 
 import com.android.internal.R;
@@ -243,16 +245,25 @@
     }
 
     /**
+     * @return where the UDFPS exists on the screen in pixels.
+     */
+    public RectF getUdfpsRegion() {
+        return mUdfpsController == null ? null : mUdfpsController.getSensorLocation();
+    }
+
+    /**
      * Requests fingerprint scan.
      *
      * @param screenX X position of long press
      * @param screenY Y position of long press
+     * @param major length of the major axis. See {@link MotionEvent#AXIS_TOOL_MAJOR}.
+     * @param minor length of the minor axis. See {@link MotionEvent#AXIS_TOOL_MINOR}.
      */
-    public void onAodInterrupt(int screenX, int screenY) {
+    public void onAodInterrupt(int screenX, int screenY, float major, float minor) {
         if (mUdfpsController == null) {
             return;
         }
-        mUdfpsController.onAodInterrupt(screenX, screenY);
+        mUdfpsController.onAodInterrupt(screenX, screenY, major, minor);
     }
 
     /**
@@ -475,7 +486,7 @@
    /**
      * Whether the current user has a UDFP enrolled.
      */
-    public boolean hasUdfpsEnrolled() {
+    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;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 3c2e008..a4b407d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -25,6 +25,7 @@
 import android.content.res.TypedArray;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
+import android.graphics.RectF;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.hardware.fingerprint.IUdfpsOverlayController;
@@ -244,6 +245,13 @@
         mView.dozeTimeTick();
     }
 
+    /**
+     * @return where the UDFPS exists on the screen in pixels.
+     */
+    public RectF getSensorLocation() {
+        return mView.getSensorRect();
+    }
+
     private void setShowOverlay(boolean show) {
         if (show == mIsOverlayRequested) {
             return;
@@ -337,7 +345,7 @@
      * This is intented to be called in response to a sensor that triggers an AOD interrupt for the
      * fingerprint sensor.
      */
-    void onAodInterrupt(int screenX, int screenY) {
+    void onAodInterrupt(int screenX, int screenY, float major, float minor) {
         if (mIsAodInterruptActive) {
             return;
         }
@@ -348,7 +356,7 @@
         mCancelAodTimeoutAction = mFgExecutor.executeDelayed(this::onCancelAodInterrupt,
                 AOD_INTERRUPT_TIMEOUT_MILLIS);
         // using a hard-coded value for major and minor until it is available from the sensor
-        onFingerDown(screenX, screenY, 13.0f, 13.0f);
+        onFingerDown(screenX, screenY, minor, major);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
index 0ed3bda..7edcf66 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
@@ -196,6 +196,10 @@
         canvas.restore();
     }
 
+    RectF getSensorRect() {
+        return new RectF(mSensorRect);
+    }
+
     void setHbmSupported(boolean hbmSupported) {
         mHbmSupported = hbmSupported;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 8220835..f07e5af 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -156,7 +156,7 @@
                         findSensorWithType(config.udfpsLongPressSensorType()),
                         "doze_pulse_on_auth",
                         true /* settingDef */,
-                        authController.hasUdfpsEnrolled() /* configured */,
+                        authController.isUdfpsEnrolled() /* configured */,
                         DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS,
                         true /* reports touch coordinates */,
                         true /* touchscreen */,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index c581e85..58e49f8 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -131,7 +131,10 @@
         DOZING_UPDATE_SENSOR_WAKE_LOCKSCREEN(440),
 
         @UiEvent(doc = "Dozing updated because sensor was tapped.")
-        DOZING_UPDATE_SENSOR_TAP(441);
+        DOZING_UPDATE_SENSOR_TAP(441),
+
+        @UiEvent(doc = "Dozing updated because on display auth was triggered from AOD.")
+        DOZING_UPDATE_AUTH_TRIGGERED(442);
 
         private final int mId;
 
@@ -155,6 +158,7 @@
                 case 7: return DOZING_UPDATE_SENSOR_WAKEUP;
                 case 8: return DOZING_UPDATE_SENSOR_WAKE_LOCKSCREEN;
                 case 9: return DOZING_UPDATE_SENSOR_TAP;
+                case 10: return DOZING_UPDATE_AUTH_TRIGGERED;
                 default: return null;
             }
         }
@@ -289,7 +293,8 @@
                     requestPulse(DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS, true, null);
                     // Since the gesture won't be received by the UDFPS view, manually inject an
                     // event.
-                    mAuthController.onAodInterrupt((int) screenX, (int) screenY);
+                    mAuthController.onAodInterrupt((int) screenX, (int) screenY,
+                            rawValues[2] /* major */, rawValues[3] /* minor */);
                 } else {
                     mDozeHost.extendPulse(pulseReason);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 1beb875..5eb6687 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -143,6 +143,11 @@
             if (newConfig == null) return
             isRtl = newConfig.layoutDirection == View.LAYOUT_DIRECTION_RTL
         }
+
+        override fun onUiModeChanged() {
+            // Only settings button needs to update for dark theme
+            inflateSettingsButton()
+        }
     }
 
     init {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 6f6ee4c..c6ed9c0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -641,7 +641,8 @@
             // Move to resume key (aka package name) if that key doesn't already exist.
             val resumeAction = getResumeMediaAction(removed.resumeAction!!)
             val updated = removed.copy(token = null, actions = listOf(resumeAction),
-                    actionsToShowInCompact = listOf(0), active = false, resumption = true)
+                    actionsToShowInCompact = listOf(0), active = false, resumption = true,
+                    isClearable = true)
             val pkg = removed.packageName
             val migrate = mediaEntries.put(pkg, updated) == null
             // Notify listeners of "new" controls when migrating or removed and update when not
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index d26f7ab..0d5faff 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -22,6 +22,7 @@
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.Drawable;
 import android.text.SpannableString;
+import android.text.TextUtils;
 import android.text.style.ForegroundColorSpan;
 import android.util.Log;
 import android.view.View;
@@ -45,6 +46,7 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private ViewGroup mConnectedItem;
+    private boolean mInclueDynamicGroup;
 
     public MediaOutputAdapter(MediaOutputController controller) {
         super(controller);
@@ -61,9 +63,21 @@
     @Override
     public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {
         final int size = mController.getMediaDevices().size();
-        if (mController.isZeroMode() && position == size) {
+        if (position == size && mController.isZeroMode()) {
             viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */,
                     true /* bottomMargin */);
+        } else if (mInclueDynamicGroup) {
+            if (position == 0) {
+                viewHolder.onBind(CUSTOMIZED_ITEM_DYNAMIC_GROUP, true /* topMargin */,
+                        false /* bottomMargin */);
+            } else {
+                // When group item is added at the first(position == 0), devices will be added from
+                // the second item(position == 1). It means that the index of device list starts
+                // from "position - 1".
+                viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices()))
+                                .get(position - 1),
+                        false /* topMargin */, position == size /* bottomMargin */);
+            }
         } else if (position < size) {
             viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())).get(position),
                     position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */);
@@ -74,8 +88,9 @@
 
     @Override
     public int getItemCount() {
-        if (mController.isZeroMode()) {
-            // Add extra one for "pair new"
+        mInclueDynamicGroup = mController.getSelectedMediaDevice().size() > 1;
+        if (mController.isZeroMode() || mInclueDynamicGroup) {
+            // Add extra one for "pair new" or dynamic group
             return mController.getMediaDevices().size() + 1;
         }
         return mController.getMediaDevices().size();
@@ -107,7 +122,7 @@
         @Override
         void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) {
             super.onBind(device, topMargin, bottomMargin);
-            final boolean currentlyConnected = isCurrentlyConnected(device);
+            final boolean currentlyConnected = !mInclueDynamicGroup && isCurrentlyConnected(device);
             if (currentlyConnected) {
                 mConnectedItem = mContainerLayout;
             }
@@ -167,6 +182,22 @@
                         Utils.getColorAccentDefaultColor(mContext), PorterDuff.Mode.SRC_IN));
                 mTitleIcon.setImageDrawable(d);
                 mContainerLayout.setOnClickListener(v -> onItemClick(CUSTOMIZED_ITEM_PAIR_NEW));
+            } else if (customizedItem == CUSTOMIZED_ITEM_DYNAMIC_GROUP) {
+                mConnectedItem = mContainerLayout;
+                mBottomDivider.setVisibility(View.GONE);
+                mCheckBox.setVisibility(View.GONE);
+                mDivider.setVisibility(View.VISIBLE);
+                mDivider.setTransitionAlpha(1);
+                mAddIcon.setVisibility(View.VISIBLE);
+                mAddIcon.setTransitionAlpha(1);
+                mAddIcon.setOnClickListener(v -> onEndItemClick());
+                mTitleIcon.setImageDrawable(getSpeakerDrawable());
+                final CharSequence sessionName = mController.getSessionName();
+                final CharSequence title = TextUtils.isEmpty(sessionName)
+                        ? mContext.getString(R.string.media_output_dialog_group) : sessionName;
+                setTwoLineLayout(title, true /* bFocused */, true /* showSeekBar */,
+                        false /* showProgressBar */, false /* showSubtitle */);
+                initSessionSeekbar();
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index 536b759..f1d4804 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -19,7 +19,11 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -35,6 +39,7 @@
 import androidx.annotation.NonNull;
 import androidx.recyclerview.widget.RecyclerView;
 
+import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.media.MediaDevice;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -47,6 +52,7 @@
 
     static final int CUSTOMIZED_ITEM_PAIR_NEW = 1;
     static final int CUSTOMIZED_ITEM_GROUP = 2;
+    static final int CUSTOMIZED_ITEM_DYNAMIC_GROUP = 3;
 
     final MediaOutputController mController;
 
@@ -223,6 +229,34 @@
             });
         }
 
+        void initSessionSeekbar() {
+            mSeekBar.setMax(mController.getSessionVolumeMax());
+            mSeekBar.setMin(0);
+            final int currentVolume = mController.getSessionVolume();
+            if (mSeekBar.getProgress() != currentVolume) {
+                mSeekBar.setProgress(currentVolume);
+            }
+            mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+                @Override
+                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                    if (!fromUser) {
+                        return;
+                    }
+                    mController.adjustSessionVolume(progress);
+                }
+
+                @Override
+                public void onStartTrackingTouch(SeekBar seekBar) {
+                    mIsDragging = true;
+                }
+
+                @Override
+                public void onStopTrackingTouch(SeekBar seekBar) {
+                    mIsDragging = false;
+                }
+            });
+        }
+
         void playSwitchingAnim(@NonNull View from, @NonNull View to) {
             final float delta = (float) (mContext.getResources().getDimensionPixelSize(
                     R.dimen.media_output_dialog_title_anim_y_delta));
@@ -274,5 +308,15 @@
                         }
                     });
         }
+
+        Drawable getSpeakerDrawable() {
+            final Drawable drawable = mContext.getDrawable(R.drawable.ic_speaker_group_black_24dp)
+                    .mutate();
+            final ColorStateList list = mContext.getResources().getColorStateList(
+                    R.color.advanced_icon_color, mContext.getTheme());
+            drawable.setColorFilter(new PorterDuffColorFilter(list.getDefaultColor(),
+                    PorterDuff.Mode.SRC_IN));
+            return BluetoothUtils.buildAdvancedDrawable(mContext, drawable);
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java
index ceb4495..24e076b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java
@@ -16,22 +16,17 @@
 
 package com.android.systemui.media.dialog;
 
-import android.content.res.ColorStateList;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.SeekBar;
 
 import androidx.annotation.NonNull;
 
-import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.media.MediaDevice;
 import com.android.systemui.R;
 
@@ -155,34 +150,6 @@
             }
         }
 
-        private void initSessionSeekbar() {
-            mSeekBar.setMax(mController.getSessionVolumeMax());
-            mSeekBar.setMin(0);
-            final int currentVolume = mController.getSessionVolume();
-            if (mSeekBar.getProgress() != currentVolume) {
-                mSeekBar.setProgress(currentVolume);
-            }
-            mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
-                @Override
-                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-                    if (!fromUser) {
-                        return;
-                    }
-                    mController.adjustSessionVolume(progress);
-                }
-
-                @Override
-                public void onStartTrackingTouch(SeekBar seekBar) {
-                    mIsDragging = true;
-                }
-
-                @Override
-                public void onStopTrackingTouch(SeekBar seekBar) {
-                    mIsDragging = false;
-                }
-            });
-        }
-
         private Drawable getDisabledCheckboxDrawable() {
             final Drawable drawable = mContext.getDrawable(R.drawable.ic_check_box_blue_24dp)
                     .mutate();
@@ -198,16 +165,6 @@
             return drawable;
         }
 
-        private Drawable getSpeakerDrawable() {
-            final Drawable drawable = mContext.getDrawable(R.drawable.ic_speaker_group_black_24dp)
-                    .mutate();
-            final ColorStateList list = mContext.getResources().getColorStateList(
-                            R.color.advanced_icon_color, mContext.getTheme());
-            drawable.setColorFilter(new PorterDuffColorFilter(list.getDefaultColor(),
-                    PorterDuff.Mode.SRC_IN));
-            return BluetoothUtils.buildAdvancedDrawable(mContext, drawable);
-        }
-
         private boolean isDeviceIncluded(List<MediaDevice> deviceList, MediaDevice targetDevice) {
             for (MediaDevice device : deviceList) {
                 if (TextUtils.equals(device.getId(), targetDevice.getId())) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 18cc746..f9982d0 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -137,7 +137,9 @@
                             && (properties.getKeyset().contains(
                                     SystemUiDeviceConfigFlags.BACK_GESTURE_ML_MODEL_THRESHOLD)
                             || properties.getKeyset().contains(
-                                    SystemUiDeviceConfigFlags.USE_BACK_GESTURE_ML_MODEL))) {
+                                    SystemUiDeviceConfigFlags.USE_BACK_GESTURE_ML_MODEL)
+                            || properties.getKeyset().contains(
+                                    SystemUiDeviceConfigFlags.BACK_GESTURE_ML_MODEL_NAME))) {
                         updateMLModelState();
                     }
                 }
@@ -483,14 +485,15 @@
     private void updateMLModelState() {
         boolean newState = mIsEnabled && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
                 SystemUiDeviceConfigFlags.USE_BACK_GESTURE_ML_MODEL, false);
-
         if (newState == mUseMLModel) {
             return;
         }
 
         if (newState) {
+            String mlModelName = DeviceConfig.getString(DeviceConfig.NAMESPACE_SYSTEMUI,
+                    SystemUiDeviceConfigFlags.BACK_GESTURE_ML_MODEL_NAME, "backgesture");
             mBackGestureTfClassifierProvider = SystemUIFactory.getInstance()
-                    .createBackGestureTfClassifierProvider(mContext.getAssets());
+                    .createBackGestureTfClassifierProvider(mContext.getAssets(), mlModelName);
             mMLModelThreshold = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_SYSTEMUI,
                     SystemUiDeviceConfigFlags.BACK_GESTURE_ML_MODEL_THRESHOLD, 0.9f);
             if (mBackGestureTfClassifierProvider.isActive()) {
@@ -540,21 +543,22 @@
         boolean withinRange = false;
         float results = -1;
 
+         // Disallow if we are in the bottom gesture area
+        if (y >= (mDisplaySize.y - mBottomGestureHeight)) {
+            return false;
+        }
+        // If the point is way too far (twice the margin), it is
+        // not interesting to us for logging purposes, nor we
+        // should process it.  Simply return false and keep
+        // mLogGesture = false.
+        if (x > 2 * (mEdgeWidthLeft + mLeftInset)
+                && x < (mDisplaySize.x - 2 * (mEdgeWidthRight + mRightInset))) {
+            return false;
+        }
+
         if (mUseMLModel &&  (results = getBackGesturePredictionsCategory(x, y)) != -1) {
             withinRange = results == 1 ? true : false;
         } else {
-            // Disallow if we are in the bottom gesture area
-            if (y >= (mDisplaySize.y - mBottomGestureHeight)) {
-                return false;
-            }
-            // If the point is way too far (twice the margin), it is
-            // not interesting to us for logging purposes, nor we
-            // should process it.  Simply return false and keep
-            // mLogGesture = false.
-            if (x > 2 * (mEdgeWidthLeft + mLeftInset)
-                    && x < (mDisplaySize.x - 2 * (mEdgeWidthRight + mRightInset))) {
-                return false;
-            }
             // Denotes whether we should proceed with the gesture.
             // Even if it is false, we may want to log it assuming
             // it is not invalid due to exclusion.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 8e0e4ac..a351510 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -71,8 +71,7 @@
 
     private int mSideMargins;
     private boolean mQsDisabled;
-    private int mContentPaddingStart = -1;
-    private int mContentPaddingEnd = -1;
+    private int mContentPadding = -1;
     private boolean mAnimateBottomOnNextLayout;
 
     public QSContainerImpl(Context context, AttributeSet attrs) {
@@ -206,10 +205,9 @@
 
         mSideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
         int padding = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_shade_content_margin_horizontal);
-        boolean marginsChanged = padding != mContentPaddingStart || padding != mContentPaddingEnd;
-        mContentPaddingStart = padding;
-        mContentPaddingEnd = padding;
+                R.dimen.notification_shade_content_margin_horizontal);
+        boolean marginsChanged = padding != mContentPadding;
+        mContentPadding = padding;
         if (marginsChanged) {
             updatePaddingsAndMargins();
         }
@@ -290,19 +288,19 @@
             lp.leftMargin = mSideMargins;
             if (view == mQSPanelContainer) {
                 // QS panel lays out some of its content full width
-                mQSPanel.setContentMargins(mContentPaddingStart, mContentPaddingEnd);
+                mQSPanel.setContentMargins(mContentPadding, mContentPadding);
                 Pair<Integer, Integer> margins = mQSPanel.getVisualSideMargins();
                 // Apply paddings based on QSPanel
                 mQSCustomizer.setContentPaddings(margins.first, margins.second);
             } else if (view == mHeader) {
                 // The header contains the QQS panel which needs to have special padding, to
                 // visually align them.
-                mHeader.setContentMargins(mContentPaddingStart, mContentPaddingEnd);
+                mHeader.setContentMargins(mContentPadding, mContentPadding);
             } else {
                 view.setPaddingRelative(
-                        mContentPaddingStart,
+                        mContentPadding,
                         view.getPaddingTop(),
-                        mContentPaddingEnd,
+                        mContentPadding,
                         view.getPaddingBottom());
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
index e6f43c1..45564b0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
@@ -30,6 +30,8 @@
 import android.hardware.display.DisplayManager;
 import android.hardware.display.VirtualDisplay;
 import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
 import android.media.MediaMuxer;
 import android.media.MediaRecorder;
 import android.media.ThumbnailUtils;
@@ -124,17 +126,19 @@
         DisplayMetrics metrics = new DisplayMetrics();
         WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         wm.getDefaultDisplay().getRealMetrics(metrics);
-        int screenWidth = metrics.widthPixels;
-        int screenHeight = metrics.heightPixels;
-        int refereshRate = (int) wm.getDefaultDisplay().getRefreshRate();
-        int vidBitRate = screenHeight * screenWidth * refereshRate / VIDEO_FRAME_RATE
+        int refreshRate = (int) wm.getDefaultDisplay().getRefreshRate();
+        int[] dimens = getSupportedSize(metrics.widthPixels, metrics.heightPixels, refreshRate);
+        int width = dimens[0];
+        int height = dimens[1];
+        refreshRate = dimens[2];
+        int vidBitRate = width * height * refreshRate / VIDEO_FRAME_RATE
                 * VIDEO_FRAME_RATE_TO_RESOLUTION_RATIO;
         mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
         mMediaRecorder.setVideoEncodingProfileLevel(
                 MediaCodecInfo.CodecProfileLevel.AVCProfileHigh,
                 MediaCodecInfo.CodecProfileLevel.AVCLevel3);
-        mMediaRecorder.setVideoSize(screenWidth, screenHeight);
-        mMediaRecorder.setVideoFrameRate(refereshRate);
+        mMediaRecorder.setVideoSize(width, height);
+        mMediaRecorder.setVideoFrameRate(refreshRate);
         mMediaRecorder.setVideoEncodingBitRate(vidBitRate);
         mMediaRecorder.setMaxDuration(MAX_DURATION_MS);
         mMediaRecorder.setMaxFileSize(MAX_FILESIZE_BYTES);
@@ -153,8 +157,8 @@
         mInputSurface = mMediaRecorder.getSurface();
         mVirtualDisplay = mMediaProjection.createVirtualDisplay(
                 "Recording Display",
-                screenWidth,
-                screenHeight,
+                width,
+                height,
                 metrics.densityDpi,
                 DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                 mInputSurface,
@@ -173,6 +177,84 @@
     }
 
     /**
+     * Find the highest supported screen resolution and refresh rate for the given dimensions on
+     * this device, up to actual size and given rate.
+     * If possible this will return the same values as given, but values may be smaller on some
+     * devices.
+     *
+     * @param screenWidth Actual pixel width of screen
+     * @param screenHeight Actual pixel height of screen
+     * @param refreshRate Desired refresh rate
+     * @return array with supported width, height, and refresh rate
+     */
+    private int[] getSupportedSize(int screenWidth, int screenHeight, int refreshRate) {
+        double maxScale = 0;
+
+        MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        MediaCodecInfo.VideoCapabilities maxInfo = null;
+        for (MediaCodecInfo codec : codecList.getCodecInfos()) {
+            String videoType = MediaFormat.MIMETYPE_VIDEO_AVC;
+            String[] types = codec.getSupportedTypes();
+            for (String t : types) {
+                if (!t.equalsIgnoreCase(videoType)) {
+                    continue;
+                }
+                MediaCodecInfo.CodecCapabilities capabilities =
+                        codec.getCapabilitiesForType(videoType);
+                if (capabilities != null && capabilities.getVideoCapabilities() != null) {
+                    MediaCodecInfo.VideoCapabilities vc = capabilities.getVideoCapabilities();
+
+                    int width = vc.getSupportedWidths().getUpper();
+                    int height = vc.getSupportedHeights().getUpper();
+
+                    if (width >= screenWidth && height >= screenHeight
+                            && vc.isSizeSupported(screenWidth, screenHeight)) {
+
+                        // Desired size is supported, now get the rate
+                        int maxRate = vc.getSupportedFrameRatesFor(screenWidth, screenHeight)
+                                .getUpper().intValue();
+
+                        if (maxRate < refreshRate) {
+                            refreshRate = maxRate;
+                        }
+                        Log.d(TAG, "Screen size supported at rate " + refreshRate);
+                        return new int[]{screenWidth, screenHeight, refreshRate};
+                    }
+
+                    // Otherwise, continue searching
+                    double scale = Math.min(((double) width / screenWidth),
+                            ((double) height / screenHeight));
+                    if (scale > maxScale) {
+                        maxScale = scale;
+                        maxInfo = vc;
+                    }
+                }
+            }
+        }
+
+        // Resize for max supported size
+        int scaledWidth = (int) (screenWidth * maxScale);
+        int scaledHeight = (int) (screenHeight * maxScale);
+        if (scaledWidth % maxInfo.getWidthAlignment() != 0) {
+            scaledWidth -= (scaledWidth % maxInfo.getWidthAlignment());
+        }
+        if (scaledHeight % maxInfo.getHeightAlignment() != 0) {
+            scaledHeight -= (scaledHeight % maxInfo.getHeightAlignment());
+        }
+
+        // Find max supported rate for size
+        int maxRate = maxInfo.getSupportedFrameRatesFor(scaledWidth, scaledHeight)
+                .getUpper().intValue();
+        if (maxRate < refreshRate) {
+            refreshRate = maxRate;
+        }
+
+        Log.d(TAG, "Resized by " + maxScale + ": " + scaledWidth + ", " + scaledHeight
+                + ", " + refreshRate);
+        return new int[]{scaledWidth, scaledHeight, refreshRate};
+    }
+
+    /**
     * Start screen recording
     */
     void start() throws IOException, RemoteException, IllegalStateException {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 5cee5bd..2a2a0b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -835,7 +835,13 @@
         if (!mShouldDrawNotificationBackground) {
             return;
         }
-
+        final boolean clearUndershelf = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.SHOW_NEW_NOTIF_DISMISS, 0 /* show background by default */) == 1;
+        if (clearUndershelf) {
+            mBackgroundPaint.setColor(Color.TRANSPARENT);
+            invalidate();
+            return;
+        }
         // Interpolate between semi-transparent notification panel background color
         // and white AOD separator.
         float colorInterpolation = MathUtils.smoothStep(0.4f /* start */, 1f /* end */,
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 ef4108b..bd22893 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -86,9 +86,14 @@
     private int mMaxShadeBottom;
 
     /**
-     * Minimum distance from the status bar.
+     * Recommended distance from the status bar without the lock icon.
      */
-    private int mContainerTopPadding;
+    private int mContainerTopPaddingWithoutLockIcon;
+
+    /**
+     * Recommended distance from the status bar with the lock icon.
+     */
+    private int mContainerTopPaddingWithLockIcon;
 
     /**
      * @see NotificationPanelViewController#getExpandedFraction()
@@ -131,24 +136,31 @@
     public void loadDimens(Resources res) {
         mClockNotificationsMargin = res.getDimensionPixelSize(
                 R.dimen.keyguard_clock_notifications_margin);
+
+        mContainerTopPaddingWithoutLockIcon =
+                res.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) / 2;
         // Consider the lock icon when determining the minimum top padding between the status bar
         // and top of the clock.
-        mContainerTopPadding = Math.max(res.getDimensionPixelSize(
-                R.dimen.keyguard_clock_top_margin),
-                res.getDimensionPixelSize(R.dimen.keyguard_lock_height)
-                        + res.getDimensionPixelSize(R.dimen.keyguard_lock_padding)
-                        + res.getDimensionPixelSize(R.dimen.keyguard_clock_lock_margin));
+        mContainerTopPaddingWithLockIcon =
+                Math.max(res.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin),
+                        res.getDimensionPixelSize(R.dimen.keyguard_lock_height)
+                                + res.getDimensionPixelSize(R.dimen.keyguard_lock_padding)
+                                + res.getDimensionPixelSize(R.dimen.keyguard_clock_lock_margin));
         mBurnInPreventionOffsetX = res.getDimensionPixelSize(
                 R.dimen.burn_in_prevention_offset_x);
         mBurnInPreventionOffsetY = res.getDimensionPixelSize(
                 R.dimen.burn_in_prevention_offset_y);
     }
 
-    public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
+    /**
+     * Sets up algorithm values.
+     */
+    public void setup(int statusBarMinHeight, int maxShadeBottom, int notificationStackHeight,
             float panelExpansion, int parentHeight, int keyguardStatusHeight, int clockPreferredY,
             boolean hasCustomClock, boolean hasVisibleNotifs, float dark, float emptyDragAmount,
-            boolean bypassEnabled, int unlockedStackScrollerPadding) {
-        mMinTopMargin = minTopMargin + mContainerTopPadding;
+            boolean bypassEnabled, int unlockedStackScrollerPadding, boolean udfpsEnrolled) {
+        mMinTopMargin = statusBarMinHeight + (udfpsEnrolled ? mContainerTopPaddingWithoutLockIcon :
+                mContainerTopPaddingWithLockIcon);
         mMaxShadeBottom = maxShadeBottom;
         mNotificationStackHeight = notificationStackHeight;
         mPanelExpansion = panelExpansion;
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 77ae059..5e883be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.view.View.GONE;
+
 import static com.android.systemui.statusbar.phone.LockIcon.STATE_BIOMETRICS_ERROR;
 import static com.android.systemui.statusbar.phone.LockIcon.STATE_LOCKED;
 import static com.android.systemui.statusbar.phone.LockIcon.STATE_LOCK_OPEN;
@@ -37,6 +39,7 @@
 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;
@@ -74,6 +77,7 @@
     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;
@@ -322,7 +326,8 @@
             @Nullable DockManager dockManager,
             KeyguardStateController keyguardStateController,
             @Main Resources resources,
-            HeadsUpManagerPhone headsUpManagerPhone) {
+            HeadsUpManagerPhone headsUpManagerPhone,
+            AuthController authController) {
         mLockscreenGestureLogger = lockscreenGestureLogger;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mLockPatternUtils = lockPatternUtils;
@@ -337,6 +342,7 @@
         mKeyguardStateController = keyguardStateController;
         mResources = resources;
         mHeadsUpManagerPhone = headsUpManagerPhone;
+        mAuthController = authController;
 
         mKeyguardIndicationController.setLockIconController(this);
     }
@@ -502,6 +508,11 @@
      * @return true if the visibility changed
      */
     private boolean updateIconVisibility() {
+        if (mAuthController.isUdfpsEnrolled()) {
+            boolean changed = mLockIcon.getVisibility() == GONE;
+            mLockIcon.setVisibility(GONE);
+            return changed;
+        }
         boolean onAodOrDocked = mStatusBarStateController.isDozing() || mDocked;
         boolean invisible = onAodOrDocked || mWakeAndUnlockRunning || mShowingLaunchAffordance;
         boolean fingerprintOrBypass = mFingerprintUnlock
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 b185f48..e9a7132 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -77,6 +77,7 @@
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.classifier.Classifier;
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -263,6 +264,7 @@
     private final KeyguardBypassController mKeyguardBypassController;
     private final KeyguardUpdateMonitor mUpdateMonitor;
     private final ConversationNotificationManager mConversationNotificationManager;
+    private final AuthController mAuthController;
     private final MediaHierarchyManager mMediaHierarchyManager;
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
@@ -516,7 +518,8 @@
             NotificationStackScrollLayoutController notificationStackScrollLayoutController,
             KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
             NotificationGroupManagerLegacy groupManager,
-            NotificationIconAreaController notificationIconAreaController) {
+            NotificationIconAreaController notificationIconAreaController,
+            AuthController authController) {
         super(view, falsingManager, dozeLog, keyguardStateController,
                 (SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
                 latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager);
@@ -581,6 +584,7 @@
         mLockscreenUserManager = notificationLockscreenUserManager;
         mEntryManager = notificationEntryManager;
         mConversationNotificationManager = conversationNotificationManager;
+        mAuthController = authController;
 
         mView.setBackgroundColor(Color.TRANSPARENT);
         OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener();
@@ -868,7 +872,8 @@
                             - mShelfHeight / 2.0f - mDarkIconSize / 2.0f),
                     clockPreferredY, hasCustomClock(),
                     hasVisibleNotifications, mInterpolatedDarkAmount, mEmptyDragAmount,
-                    bypassEnabled, getUnlockedStackScrollerPadding());
+                    bypassEnabled, getUnlockedStackScrollerPadding(),
+                    mAuthController.isUdfpsEnrolled());
             mClockPositionAlgorithm.run(mClockPositionResult);
             mKeyguardStatusViewController.updatePosition(
                     mClockPositionResult.clockX, mClockPositionResult.clockY, animateClock);
@@ -908,6 +913,13 @@
                 mNotificationStackScrollLayoutController.getHeight() - minPadding - shelfSize
                         - Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding)
                         - mKeyguardStatusViewController.getLogoutButtonHeight();
+
+        if (mAuthController.isUdfpsEnrolled()) {
+            availableSpace = mNotificationStackScrollLayoutController.getHeight()
+                    - minPadding - shelfSize
+                    - (mStatusBar.getDisplayHeight() - mAuthController.getUdfpsRegion().top);
+        }
+
         int count = 0;
         ExpandableView previousView = null;
         for (int i = 0; i < mNotificationStackScrollLayoutController.getChildCount(); i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java
index bbabaf42..a59c876 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java
@@ -22,7 +22,6 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.pip.PipBoundsHandler;
 import com.android.wm.shell.pip.PipBoundsState;
@@ -107,10 +106,9 @@
             PipBoundsHandler pipBoundsHandler,
             PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
             Optional<SplitScreen> splitScreenOptional, DisplayController displayController,
-            PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
-            SystemWindows systemWindows) {
+            PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer) {
         return new PipTaskOrganizer(context, pipBoundsState, pipBoundsHandler,
                 null /* menuActivityController */, pipSurfaceTransactionHelper, splitScreenOptional,
-                displayController, pipUiEventLogger, shellTaskOrganizer, systemWindows);
+                displayController, pipUiEventLogger, shellTaskOrganizer);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
index 1ca04af..0f8fb7b 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
@@ -131,10 +131,9 @@
             PipMenuActivityController menuActivityController,
             PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
             Optional<SplitScreen> splitScreenOptional, DisplayController displayController,
-            PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer,
-            SystemWindows systemWindows) {
+            PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer) {
         return new PipTaskOrganizer(context, pipBoundsState, pipBoundsHandler,
                 menuActivityController, pipSurfaceTransactionHelper, splitScreenOptional,
-                displayController, pipUiEventLogger, shellTaskOrganizer, systemWindows);
+                displayController, pipUiEventLogger, shellTaskOrganizer);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index e6479dd..caab2ab 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -79,6 +79,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor.BiometricAuthenticated;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -156,6 +157,8 @@
     private LiveData<Integer> mRingerModeLiveData;
     @Mock
     private StatusBarStateController mStatusBarStateController;
+    @Mock
+    private AuthController mAuthController;
     // Direct executor
     private Executor mBackgroundExecutor = Runnable::run;
     private TestableLooper mTestableLooper;
@@ -198,6 +201,7 @@
         when(mTelephonyManager.getServiceStateForSubscriber(anyInt()))
                 .thenReturn(new ServiceState());
         when(mLockPatternUtils.getLockSettings()).thenReturn(mLockSettings);
+        when(mAuthController.isUdfpsEnrolled()).thenReturn(false);
         mSpiedContext.addMockSystemService(TrustManager.class, mTrustManager);
         mSpiedContext.addMockSystemService(FingerprintManager.class, mFingerprintManager);
         mSpiedContext.addMockSystemService(BiometricManager.class, mBiometricManager);
@@ -796,7 +800,8 @@
                     TestableLooper.get(KeyguardUpdateMonitorTest.this).getLooper(),
                     mBroadcastDispatcher, mDumpManager,
                     mRingerModeTracker, mBackgroundExecutor,
-                    mStatusBarStateController, mLockPatternUtils);
+                    mStatusBarStateController, mLockPatternUtils,
+                    mAuthController);
             setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index c923515..a0ae35f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -287,6 +287,33 @@
         assertShowFadingAnimation(FADE_OUT_ALPHA);
     }
 
+    @Test
+    public void showButton_hasAccessibilityWindowTitle() {
+        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+        ArgumentCaptor<WindowManager.LayoutParams> paramsArgumentCaptor = ArgumentCaptor.forClass(
+                WindowManager.LayoutParams.class);
+        verify(mWindowManager).addView(eq(mSpyImageView), paramsArgumentCaptor.capture());
+        assertEquals(getContext().getResources().getString(
+                com.android.internal.R.string.android_system_label),
+                paramsArgumentCaptor.getValue().accessibilityTitle);
+    }
+
+    @Test
+    public void onLocaleChanged_buttonIsShowing_updateA11yWindowTitle() {
+        final String newA11yWindowTitle = "new a11y window title";
+        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+
+        getContext().getOrCreateTestableResources().addOverride(
+                com.android.internal.R.string.android_system_label, newA11yWindowTitle);
+        mMagnificationModeSwitch.onConfigurationChanged(ActivityInfo.CONFIG_LOCALE);
+
+        ArgumentCaptor<WindowManager.LayoutParams> paramsArgumentCaptor = ArgumentCaptor.forClass(
+                WindowManager.LayoutParams.class);
+        verify(mWindowManager).updateViewLayout(eq(mSpyImageView), paramsArgumentCaptor.capture());
+        assertEquals(newA11yWindowTitle, paramsArgumentCaptor.getValue().accessibilityTitle);
+    }
+
     private void assertModeUnchanged(int expectedMode) {
         final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index 33b1d94..6978ef4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -92,7 +92,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mWaitingAnimationPeriod = ANIMATION_DURATION_MS + 50;
+        mWaitingAnimationPeriod = 2 * ANIMATION_DURATION_MS;
         mWaitIntermediateAnimationPeriod = ANIMATION_DURATION_MS / 2;
         mController = new SpyWindowMagnificationController(mContext, mHandler,
                 mSfVsyncFrameProvider, null, new SurfaceControl.Transaction(),
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 f1606c5..a39bc70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -41,6 +41,7 @@
 import android.content.res.Resources;
 import android.os.Handler;
 import android.testing.AndroidTestingRunner;
+import android.testing.TestableResources;
 import android.view.Display;
 import android.view.Surface;
 import android.view.SurfaceControl;
@@ -114,8 +115,7 @@
         when(mTransaction.remove(any())).thenReturn(mTransaction);
         when(mTransaction.setGeometry(any(), any(), any(),
                 anyInt())).thenReturn(mTransaction);
-        mResources = Mockito.spy(mContext.getResources());
-        when(mContext.getResources()).thenReturn(mResources);
+        mResources = getContext().getOrCreateTestableResources().getResources();
         mWindowMagnificationController = new WindowMagnificationController(mContext,
                 mHandler, mSfVsyncFrameProvider,
                 mMirrorWindowControl, mTransaction, mWindowMagnifierCallback);
@@ -222,7 +222,6 @@
         assertEquals(Surface.ROTATION_90, mWindowMagnificationController.mRotation);
     }
 
-
     @Test
     public void onDensityChanged_enabled_updateDimensionsAndResetWindowMagnification() {
         mInstrumentation.runOnMainSync(() -> {
@@ -310,4 +309,41 @@
 
         verify(mWindowManager).updateViewLayout(eq(mMirrorView), any());
     }
+
+    @Test
+    public void enableWindowMagnification_hasA11yWindowTitle() {
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
+                    Float.NaN);
+        });
+
+        ArgumentCaptor<WindowManager.LayoutParams> paramsArgumentCaptor = ArgumentCaptor.forClass(
+                WindowManager.LayoutParams.class);
+        verify(mWindowManager).addView(eq(mMirrorView), paramsArgumentCaptor.capture());
+        assertEquals(getContext().getResources().getString(
+                com.android.internal.R.string.android_system_label),
+                paramsArgumentCaptor.getValue().accessibilityTitle);
+    }
+
+    @Test
+    public void onLocaleChanged_enabled_updateA11yWindowTitle() {
+        final String newA11yWindowTitle = "new a11y window title";
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
+                    Float.NaN);
+        });
+        final TestableResources testableResources = getContext().getOrCreateTestableResources();
+        testableResources.addOverride(com.android.internal.R.string.android_system_label,
+                newA11yWindowTitle);
+        when(mContext.getResources()).thenReturn(testableResources.getResources());
+
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_LOCALE);
+        });
+
+        ArgumentCaptor<WindowManager.LayoutParams> paramsArgumentCaptor = ArgumentCaptor.forClass(
+                WindowManager.LayoutParams.class);
+        verify(mWindowManager).updateViewLayout(eq(mMirrorView), paramsArgumentCaptor.capture());
+        assertEquals(newA11yWindowTitle, paramsArgumentCaptor.getValue().accessibilityTitle);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 0186d73..42bb005 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -494,8 +494,9 @@
     @Test
     public void testOnAodInterrupt() {
         final int pos = 10;
-        mAuthController.onAodInterrupt(pos, pos);
-        verify(mUdfpsController).onAodInterrupt(eq(pos), eq(pos));
+        final float majorMinor = 5f;
+        mAuthController.onAodInterrupt(pos, pos, majorMinor, majorMinor);
+        verify(mUdfpsController).onAodInterrupt(eq(pos), eq(pos), eq(majorMinor), eq(majorMinor));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index a95396c..82ffd46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -234,10 +234,10 @@
         mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
         mFgExecutor.runAllReady();
         // WHEN fingerprint is requested because of AOD interrupt
-        mUdfpsController.onAodInterrupt(0, 0);
+        mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
         // THEN the event is passed to the FingerprintManager
         verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mSensorProps.sensorId), eq(0),
-                eq(0), anyFloat(), anyFloat());
+                eq(0), eq(3f) /* minor */, eq(2f) /* major */);
         // AND the scrim and dot is shown
         verify(mUdfpsView).showScrimAndDot();
     }
@@ -247,7 +247,7 @@
         // GIVEN AOD interrupt
         mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
         mFgExecutor.runAllReady();
-        mUdfpsController.onAodInterrupt(0, 0);
+        mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
         // WHEN it is cancelled
         mUdfpsController.onCancelAodInterrupt();
         // THEN the scrim and dot is hidden
@@ -259,7 +259,7 @@
         // GIVEN AOD interrupt
         mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID);
         mFgExecutor.runAllReady();
-        mUdfpsController.onAodInterrupt(0, 0);
+        mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
         // WHEN it times out
         mFgExecutor.advanceClockToNext();
         mFgExecutor.runAllReady();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 6d87cc3..4bbba56 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -194,10 +194,13 @@
     public void testOnSensor_Fingerprint() {
         final int screenX = 100;
         final int screenY = 100;
+        final float minor = 2f;
+        final float major = 3f;
         final int reason = DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS;
-        mTriggers.onSensor(reason, screenX, screenY, null);
+        float[] rawValues = new float[]{screenX, screenY, minor, major};
+        mTriggers.onSensor(reason, screenX, screenY, rawValues);
         verify(mHost).extendPulse(reason);
-        verify(mAuthController).onAodInterrupt(eq(screenX), eq(screenY));
+        verify(mAuthController).onAodInterrupt(eq(screenX), eq(screenY), eq(minor), eq(major));
     }
 
     private void waitForSensorManager() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index 5218886..6e21642 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -50,6 +50,7 @@
     private static final String TEST_DEVICE_NAME_2 = "test_device_name_2";
     private static final String TEST_DEVICE_ID_1 = "test_device_id_1";
     private static final String TEST_DEVICE_ID_2 = "test_device_id_2";
+    private static final String TEST_SESSION_NAME = "test_session_name";
 
     // Mock
     private MediaOutputController mMediaOutputController = mock(MediaOutputController.class);
@@ -102,6 +103,14 @@
     }
 
     @Test
+    public void getItemCount_withDynamicGroup_containExtraOneForGroup() {
+        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
+        when(mMediaOutputController.isZeroMode()).thenReturn(false);
+
+        assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1);
+    }
+
+    @Test
     public void onBindViewHolder_zeroMode_bindPairNew_verifyView() {
         when(mMediaOutputController.isZeroMode()).thenReturn(true);
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
@@ -118,6 +127,45 @@
     }
 
     @Test
+    public void onBindViewHolder_bindGroup_withSessionName_verifyView() {
+        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
+        when(mMediaOutputController.isZeroMode()).thenReturn(false);
+        when(mMediaOutputController.getSessionName()).thenReturn(TEST_SESSION_NAME);
+        mMediaOutputAdapter.getItemCount();
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_SESSION_NAME);
+    }
+
+    @Test
+    public void onBindViewHolder_bindGroup_noSessionName_verifyView() {
+        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
+        when(mMediaOutputController.isZeroMode()).thenReturn(false);
+        when(mMediaOutputController.getSessionName()).thenReturn(null);
+        mMediaOutputAdapter.getItemCount();
+        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
+        assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE);
+        assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(mContext.getString(
+                R.string.media_output_dialog_group));
+    }
+
+    @Test
     public void onBindViewHolder_bindConnectedDevice_verifyView() {
         mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index 2042fab..83ef87a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -384,7 +384,7 @@
         mClockPositionAlgorithm.setup(EMPTY_MARGIN, SCREEN_HEIGHT, mNotificationStackHeight,
                 mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight, mPreferredClockY,
                 mHasCustomClock, mHasVisibleNotifs, mDark, ZERO_DRAG, false /* bypassEnabled */,
-                0 /* unlockedStackScrollerPadding */);
+                0 /* unlockedStackScrollerPadding */, false /* udfpsEnrolled */);
         mClockPositionAlgorithm.run(mClockPosition);
     }
 }
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 06d0331..72a0258 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,6 +32,7 @@
 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;
@@ -80,6 +81,8 @@
     private Resources mResources;
     @Mock
     private HeadsUpManagerPhone mHeadsUpManagerPhone;
+    @Mock
+    private AuthController mAuthController;
 
     private LockscreenLockIconController mLockIconController;
     private OnAttachStateChangeListener mOnAttachStateChangeListener;
@@ -89,13 +92,14 @@
     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);
+                mHeadsUpManagerPhone, mAuthController);
 
         ArgumentCaptor<OnAttachStateChangeListener> onAttachStateChangeListenerArgumentCaptor =
                 ArgumentCaptor.forClass(OnAttachStateChangeListener.class);
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 cb56f1f..3b123f6 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
@@ -58,6 +58,7 @@
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.media.MediaHierarchyManager;
@@ -194,6 +195,8 @@
     private KeyguardStatusViewController mKeyguardStatusViewController;
     @Mock
     private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
+    @Mock
+    private AuthController mAuthController;
 
     private NotificationPanelViewController mNotificationPanelViewController;
     private View.AccessibilityDelegate mAccessibiltyDelegate;
@@ -201,6 +204,7 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        when(mAuthController.isUdfpsEnrolled()).thenReturn(false);
         when(mHeadsUpCallback.getContext()).thenReturn(mContext);
         when(mView.getResources()).thenReturn(mResources);
         when(mResources.getConfiguration()).thenReturn(mConfiguration);
@@ -267,7 +271,8 @@
                 mNotificationStackScrollLayoutController,
                 mKeyguardStatusViewComponentFactory,
                 mGroupManager,
-                mNotificationAreaController);
+                mNotificationAreaController,
+                mAuthController);
         mNotificationPanelViewController.initDependencies(
                 mStatusBar,
                 mNotificationShelfController);
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/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-bn/strings.xml b/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-bn/strings.xml
new file mode 100644
index 0000000..3e9c962
--- /dev/null
+++ b/packages/overlays/DisplayCutoutEmulationHoleOverlay/res/values-bn/strings.xml
@@ -0,0 +1,21 @@
+<?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.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="display_cutout_emulation_overlay" msgid="7305489596221077240">"পাঞ্চ হোল কাট-আউট"</string>
+</resources>
diff --git a/services/backup/OWNERS b/services/backup/OWNERS
index 7c7e742..3c5268c 100644
--- a/services/backup/OWNERS
+++ b/services/backup/OWNERS
@@ -1,7 +1,6 @@
 # Bug component: 656484
 
 aabhinav@google.com
-alsutton@google.com
 bryanmawhinney@google.com
 jstemmer@google.com
 nathch@google.com
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index da2a3de..22423fe 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -65,7 +65,6 @@
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
-import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -1146,12 +1145,7 @@
         dataConnectionStats.startMonitoring();
 
         mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
-        mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager,
-                // Pass a NotificationManager obtained from a context with UserHandle.ALL, then
-                // NetworkNotificationManager can put up a notification to all users.
-                // TODO: Create NotificationManager in NetworkNotificationManager directly.
-                (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */)
-                        .getSystemService(Context.NOTIFICATION_SERVICE));
+        mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager);
 
         final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT,
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 8ea71b3..770e8de 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -340,7 +340,8 @@
                     | PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED
                     | PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES
                     | PhoneStateListener.LISTEN_REGISTRATION_FAILURE
-                    | PhoneStateListener.LISTEN_BARRING_INFO;
+                    | PhoneStateListener.LISTEN_BARRING_INFO
+                    | PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION;
 
     static final long READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK =
             PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 60e59e3..28afcbb 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -85,6 +85,7 @@
         DeviceConfig.NAMESPACE_INTELLIGENCE_CONTENT_SUGGESTIONS,
         DeviceConfig.NAMESPACE_MEDIA_NATIVE,
         DeviceConfig.NAMESPACE_NETD_NATIVE,
+        DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_RUNTIME_NATIVE,
         DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
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/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index cfc58a5..52fc93f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4306,7 +4306,7 @@
     /** @see AudioManager#playSoundEffect(int, float) */
     public void playSoundEffectVolume(int effectType, float volume) {
         // do not try to play the sound effect if the system stream is muted
-        if (isStreamMutedByRingerOrZenMode(STREAM_SYSTEM)) {
+        if (isStreamMute(STREAM_SYSTEM)) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
index f7998ee..15f8c53 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
@@ -46,6 +46,7 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -81,14 +82,14 @@
  * Supports a single instance of the {@link android.hardware.biometrics.face.V1_0} or
  * its extended minor versions.
  */
-class Face10 implements IHwBinder.DeathRecipient {
+class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
 
     private static final String TAG = "Face10";
     private static final int ENROLL_TIMEOUT_SEC = 75;
     static final String NOTIFICATION_TAG = "FaceService";
     static final int NOTIFICATION_ID = 1;
 
-    @NonNull private final FaceSensorPropertiesInternal mFaceSensorProperties;
+    @NonNull private final FaceSensorPropertiesInternal mSensorProperties;
     @NonNull private final Context mContext;
     @NonNull private final BiometricScheduler mScheduler;
     @NonNull private final Handler mHandler;
@@ -96,23 +97,22 @@
     @NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
     @NonNull private final LockoutHalImpl mLockoutTracker;
     @NonNull private final UsageStats mUsageStats;
-    @NonNull private NotificationManager mNotificationManager;
-    private final int mSensorId;
+    @NonNull private final NotificationManager mNotificationManager;
     @NonNull private final Map<Integer, Long> mAuthenticatorIds;
-
     @Nullable private IBiometricsFace mDaemon;
-    private int mCurrentUserId = UserHandle.USER_NULL;
     // If a challenge is generated, keep track of its owner. Since IBiometricsFace@1.0 only
     // supports a single in-flight challenge, we must notify the interrupted owner that its
     // challenge is no longer valid. The interrupted owner will be notified when the interrupter
     // has finished.
     @Nullable private FaceGenerateChallengeClient mCurrentChallengeOwner;
+    private int mCurrentUserId = UserHandle.USER_NULL;
+    private final int mSensorId;
 
     private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
         @Override
         public void onUserSwitching(int newUserId) {
             scheduleInternalCleanup(newUserId);
-            scheduleGetFeature(new Binder(), newUserId,
+            scheduleGetFeature(mSensorId, new Binder(), newUserId,
                     BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION,
                     null, mContext.getOpPackageName());
         }
@@ -283,7 +283,7 @@
             @BiometricManager.Authenticators.Types int strength,
             @NonNull LockoutResetDispatcher lockoutResetDispatcher,
             boolean supportsSelfIllumination, int maxTemplatesAllowed) {
-        mFaceSensorProperties = new FaceSensorPropertiesInternal(sensorId,
+        mSensorProperties = new FaceSensorPropertiesInternal(sensorId,
                 Utils.authenticatorStrengthToPropertyStrength(strength),
                 maxTemplatesAllowed, false /* supportsFaceDetect */, supportsSelfIllumination);
         mContext = context;
@@ -375,9 +375,10 @@
         if (halId != 0) {
             scheduleLoadAuthenticatorIds();
             scheduleInternalCleanup(ActivityManager.getCurrentUser());
-            scheduleGetFeature(new Binder(), ActivityManager.getCurrentUser(),
-                    BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION,
-                    null, mContext.getOpPackageName());
+            scheduleGetFeature(mSensorId, new Binder(),
+                    ActivityManager.getCurrentUser(),
+                    BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION, null,
+                    mContext.getOpPackageName());
         } else {
             Slog.e(TAG, "Unable to set callback");
             mDaemon = null;
@@ -386,116 +387,39 @@
         return mDaemon;
     }
 
-    @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) {
+    @Override
+    public boolean containsSensor(int sensorId) {
+        return mSensorId == sensorId;
+    }
+
+    @Override
+    @NonNull
+    public List<FaceSensorPropertiesInternal> getSensorProperties() {
+        final List<FaceSensorPropertiesInternal> properties = new ArrayList<>();
+        properties.add(mSensorProperties);
+        return properties;
+    }
+
+    @Override
+    @NonNull
+    public List<Face> getEnrolledFaces(int sensorId, int userId) {
+        return FaceUtils.getInstance().getBiometricsForUser(mContext, userId);
+    }
+
+    @Override
+    @LockoutTracker.LockoutMode
+    public int getLockoutModeForUser(int sensorId, int userId) {
         return mLockoutTracker.getLockoutModeForUser(userId);
     }
 
-    private void scheduleLoadAuthenticatorIds() {
-        // Note that this can be performed on the scheduler (as opposed to being done immediately
-        // when the HAL is (re)loaded, since
-        // 1) If this is truly the first time it's being performed (e.g. system has just started),
-        //    this will be run very early and way before any applications need to generate keys.
-        // 2) If this is being performed to refresh the authenticatorIds (e.g. HAL crashed and has
-        //    just been reloaded), the framework already has a cache of the authenticatorIds. This
-        //    is safe because authenticatorIds only change when A) new template has been enrolled,
-        //    or B) all templates are removed.
-        mHandler.post(() -> {
-            for (UserInfo user : UserManager.get(mContext).getAliveUsers()) {
-                final int targetUserId = user.id;
-                if (!mAuthenticatorIds.containsKey(targetUserId)) {
-                    scheduleUpdateActiveUserWithoutHandler(targetUserId);
-                }
-            }
-        });
+    @Override
+    public long getAuthenticatorId(int sensorId, int userId) {
+        return mAuthenticatorIds.get(userId);
     }
 
-    /**
-     * Schedules the {@link FaceUpdateActiveUserClient} without posting the work onto the
-     * handler. Many/most APIs are user-specific. However, the HAL requires explicit "setActiveUser"
-     * invocation prior to authenticate/enroll/etc. Thus, internally we usually want to schedule
-     * this operation on the same lambda/runnable as those operations so that the ordering is
-     * correct.
-     */
-    private void scheduleUpdateActiveUserWithoutHandler(int targetUserId) {
-        final boolean hasEnrolled = !getEnrolledFaces(targetUserId).isEmpty();
-        final FaceUpdateActiveUserClient client = new FaceUpdateActiveUserClient(mContext,
-                mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId, mCurrentUserId,
-                hasEnrolled, mAuthenticatorIds);
-        mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
-            @Override
-            public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) {
-                if (success) {
-                    mCurrentUserId = targetUserId;
-                }
-            }
-        });
-    }
-
-    void scheduleResetLockout(int userId, @NonNull byte[] hardwareAuthToken) {
-        mHandler.post(() -> {
-            if (getEnrolledFaces(userId).isEmpty()) {
-                Slog.w(TAG, "Ignoring lockout reset, no templates enrolled for user: " + userId);
-                return;
-            }
-
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            final FaceResetLockoutClient client = new FaceResetLockoutClient(mContext,
-                    mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId,
-                    hardwareAuthToken);
-            mScheduler.scheduleClientMonitor(client);
-        });
-    }
-
-    void scheduleSetFeature(@NonNull IBinder token, int userId, int feature, boolean enabled,
-            @NonNull byte[] hardwareAuthToken, @NonNull IFaceServiceReceiver receiver,
-            @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            final List<Face> faces = getEnrolledFaces(userId);
-            if (faces.isEmpty()) {
-                Slog.w(TAG, "Ignoring setFeature, no templates enrolled for user: " + userId);
-                return;
-            }
-
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            final int faceId = faces.get(0).getBiometricId();
-            final FaceSetFeatureClient client = new FaceSetFeatureClient(mContext,
-                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
-                    opPackageName, mSensorId, feature, enabled, hardwareAuthToken, faceId);
-            mScheduler.scheduleClientMonitor(client);
-        });
-    }
-
-    void scheduleGetFeature(@NonNull IBinder token, int userId, int feature,
-            @Nullable ClientMonitorCallbackConverter listener, @NonNull String opPackageName) {
-        mHandler.post(() -> {
-            final List<Face> faces = getEnrolledFaces(userId);
-            if (faces.isEmpty()) {
-                Slog.w(TAG, "Ignoring getFeature, no templates enrolled for user: " + userId);
-                return;
-            }
-
-            scheduleUpdateActiveUserWithoutHandler(userId);
-
-            final int faceId = faces.get(0).getBiometricId();
-            final FaceGetFeatureClient client = new FaceGetFeatureClient(mContext, mLazyDaemon,
-                    token, listener, userId, opPackageName, mSensorId, feature, faceId);
-            mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
-                @Override
-                public void onClientFinished(
-                        @NonNull ClientMonitor<?> clientMonitor, boolean success) {
-                    if (success && feature == BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION) {
-                        final int settingsValue = client.getValue() ? 1 : 0;
-                        Slog.d(TAG, "Updating attention value for user: " + userId
-                                + " to value: " + settingsValue);
-                        Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                                Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED,
-                                settingsValue, userId);
-                    }
-                }
-            });
-        });
+    @Override
+    public boolean isHardwareDetected(int sensorId) {
+        return getDaemon() != null;
     }
 
     /**
@@ -514,8 +438,9 @@
      * The only case of conflicting challenges is currently resetLockout --> enroll. So, the second
      * option seems better as it prioritizes the new operation, which is user-facing.
      */
-    void scheduleGenerateChallenge(@NonNull IBinder token, @NonNull IFaceServiceReceiver receiver,
-            @NonNull String opPackageName) {
+    @Override
+    public void scheduleGenerateChallenge(int sensorId, int userId, @NonNull IBinder token,
+            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
         mHandler.post(() -> {
             if (mCurrentChallengeOwner != null) {
                 final ClientMonitorCallbackConverter listener =
@@ -550,18 +475,20 @@
         });
     }
 
-    void scheduleRevokeChallenge(@NonNull IBinder token, @NonNull String owner) {
+    @Override
+    public void scheduleRevokeChallenge(int sensorId, int userId, @NonNull IBinder token,
+            @NonNull String opPackageName, long challenge) {
         mHandler.post(() -> {
             if (mCurrentChallengeOwner != null &&
-                    !mCurrentChallengeOwner.getOwnerString().contentEquals(owner)) {
-                Slog.e(TAG, "scheduleRevokeChallenge, package: " + owner
+                    !mCurrentChallengeOwner.getOwnerString().contentEquals(opPackageName)) {
+                Slog.e(TAG, "scheduleRevokeChallenge, package: " + opPackageName
                         + " attempting to revoke challenge owned by: "
                         + mCurrentChallengeOwner.getOwnerString());
                 return;
             }
 
             final FaceRevokeChallengeClient client = new FaceRevokeChallengeClient(mContext,
-                    mLazyDaemon, token, owner, mSensorId);
+                    mLazyDaemon, token, opPackageName, mSensorId);
             mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
                 @Override
                 public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor,
@@ -582,13 +509,19 @@
                     final FaceGenerateChallengeClient previousChallengeOwner =
                             mCurrentChallengeOwner.getInterruptedClient();
                     mCurrentChallengeOwner = null;
+
                     Slog.d(TAG, "Previous challenge owner: " + previousChallengeOwner);
                     if (previousChallengeOwner != null) {
-                        try {
-                            previousChallengeOwner.getListener()
-                                    .onChallengeInterruptFinished(mSensorId);
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Unable to notify interrupt finished", e);
+                        final ClientMonitorCallbackConverter listener =
+                                previousChallengeOwner.getListener();
+                        if (listener == null) {
+                            Slog.w(TAG, "Listener is null");
+                        } else {
+                            try {
+                                listener.onChallengeInterruptFinished(mSensorId);
+                            } catch (RemoteException e) {
+                                Slog.e(TAG, "Unable to notify interrupt finished", e);
+                            }
                         }
                     }
                 }
@@ -596,9 +529,11 @@
         });
     }
 
-    void scheduleEnroll(@NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId,
-            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName,
-            @NonNull int[] disabledFeatures, @Nullable NativeHandle surfaceHandle) {
+    @Override
+    public void scheduleEnroll(int sensorId, @NonNull IBinder token,
+            @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFaceServiceReceiver receiver,
+            @NonNull String opPackageName, @NonNull int[] disabledFeatures,
+            @Nullable NativeHandle surfaceHandle) {
         mHandler.post(() -> {
             scheduleUpdateActiveUserWithoutHandler(userId);
 
@@ -623,15 +558,18 @@
         });
     }
 
-    void cancelEnrollment(@NonNull IBinder token) {
+    @Override
+    public void cancelEnrollment(int sensorId, @NonNull IBinder token) {
         mHandler.post(() -> {
             mScheduler.cancelEnrollment(token);
         });
     }
 
-    void scheduleAuthenticate(@NonNull IBinder token, long operationId, int userId, int cookie,
-            @NonNull ClientMonitorCallbackConverter receiver, @NonNull String opPackageName,
-            boolean restricted, int statsClient) {
+    @Override
+    public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
+            int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver,
+            @NonNull String opPackageName, boolean restricted, int statsClient,
+            boolean isKeyguard) {
         mHandler.post(() -> {
             scheduleUpdateActiveUserWithoutHandler(userId);
 
@@ -644,19 +582,15 @@
         });
     }
 
-    void startPreparedClient(int cookie) {
-        mHandler.post(() -> {
-            mScheduler.startPreparedClient(cookie);
-        });
-    }
-
-    void cancelAuthentication(@NonNull IBinder token) {
+    @Override
+    public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
         mHandler.post(() -> {
             mScheduler.cancelAuthentication(token);
         });
     }
 
-    void scheduleRemove(@NonNull IBinder token, int faceId, int userId,
+    @Override
+    public void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId,
             @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
         mHandler.post(() -> {
             scheduleUpdateActiveUserWithoutHandler(userId);
@@ -668,11 +602,82 @@
         });
     }
 
+
+    @Override
+    public void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken) {
+        mHandler.post(() -> {
+            if (getEnrolledFaces(sensorId, userId).isEmpty()) {
+                Slog.w(TAG, "Ignoring lockout reset, no templates enrolled for user: " + userId);
+                return;
+            }
+
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final FaceResetLockoutClient client = new FaceResetLockoutClient(mContext,
+                    mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId,
+                    hardwareAuthToken);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    @Override
+    public void scheduleSetFeature(int sensorId, @NonNull IBinder token, int userId, int feature,
+            boolean enabled, @NonNull byte[] hardwareAuthToken,
+            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
+        mHandler.post(() -> {
+            final List<Face> faces = getEnrolledFaces(sensorId, userId);
+            if (faces.isEmpty()) {
+                Slog.w(TAG, "Ignoring setFeature, no templates enrolled for user: " + userId);
+                return;
+            }
+
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final int faceId = faces.get(0).getBiometricId();
+            final FaceSetFeatureClient client = new FaceSetFeatureClient(mContext,
+                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
+                    opPackageName, mSensorId, feature, enabled, hardwareAuthToken, faceId);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    @Override
+    public void scheduleGetFeature(int sensorId, @NonNull IBinder token, int userId, int feature,
+            @Nullable ClientMonitorCallbackConverter listener, @NonNull String opPackageName) {
+        mHandler.post(() -> {
+            final List<Face> faces = getEnrolledFaces(sensorId, userId);
+            if (faces.isEmpty()) {
+                Slog.w(TAG, "Ignoring getFeature, no templates enrolled for user: " + userId);
+                return;
+            }
+
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final int faceId = faces.get(0).getBiometricId();
+            final FaceGetFeatureClient client = new FaceGetFeatureClient(mContext, mLazyDaemon,
+                    token, listener, userId, opPackageName, mSensorId, feature, faceId);
+            mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
+                @Override
+                public void onClientFinished(
+                        @NonNull ClientMonitor<?> clientMonitor, boolean success) {
+                    if (success && feature == BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION) {
+                        final int settingsValue = client.getValue() ? 1 : 0;
+                        Slog.d(TAG, "Updating attention value for user: " + userId
+                                + " to value: " + settingsValue);
+                        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                                Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED,
+                                settingsValue, userId);
+                    }
+                }
+            });
+        });
+    }
+
     private void scheduleInternalCleanup(int userId) {
         mHandler.post(() -> {
             scheduleUpdateActiveUserWithoutHandler(userId);
 
-            final List<Face> enrolledList = getEnrolledFaces(userId);
+            final List<Face> enrolledList = getEnrolledFaces(mSensorId, userId);
             final FaceInternalCleanupClient client = new FaceInternalCleanupClient(mContext,
                     mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId, enrolledList,
                     FaceUtils.getInstance(), mAuthenticatorIds);
@@ -680,25 +685,28 @@
         });
     }
 
-    boolean isHardwareDetected() {
-        final IBiometricsFace daemon = getDaemon();
-        return daemon != null;
+    @Override
+    public void scheduleInternalCleanup(int sensorId, int userId) {
+        scheduleInternalCleanup(userId);
     }
 
-    @NonNull
-    FaceSensorPropertiesInternal getFaceSensorProperties() {
-        return mFaceSensorProperties;
+    @Override
+    public void startPreparedClient(int sensorId, int cookie) {
+        mHandler.post(() -> {
+            mScheduler.startPreparedClient(cookie);
+        });
     }
 
-    List<Face> getEnrolledFaces(int userId) {
-        return FaceUtils.getInstance().getBiometricsForUser(mContext, userId);
+    @Override
+    public void dumpProtoState(int sensorId, ProtoOutputStream proto) {
     }
 
-    long getAuthenticatorId(int userId) {
-        return mAuthenticatorIds.get(userId);
+    @Override
+    public void dumpProtoMetrics(int sensorId, FileDescriptor fd) {
     }
 
-    public void dump(@NonNull PrintWriter pw) {
+    @Override
+    public void dumpInternal(int sensorId, PrintWriter pw) {
         PerformanceTracker performanceTracker =
                 PerformanceTracker.getInstanceForSensorId(mSensorId);
 
@@ -733,9 +741,51 @@
         pw.println(dump);
         pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount());
 
+        mScheduler.dump(pw);
         mUsageStats.print(pw);
     }
 
+    private void scheduleLoadAuthenticatorIds() {
+        // Note that this can be performed on the scheduler (as opposed to being done immediately
+        // when the HAL is (re)loaded, since
+        // 1) If this is truly the first time it's being performed (e.g. system has just started),
+        //    this will be run very early and way before any applications need to generate keys.
+        // 2) If this is being performed to refresh the authenticatorIds (e.g. HAL crashed and has
+        //    just been reloaded), the framework already has a cache of the authenticatorIds. This
+        //    is safe because authenticatorIds only change when A) new template has been enrolled,
+        //    or B) all templates are removed.
+        mHandler.post(() -> {
+            for (UserInfo user : UserManager.get(mContext).getAliveUsers()) {
+                final int targetUserId = user.id;
+                if (!mAuthenticatorIds.containsKey(targetUserId)) {
+                    scheduleUpdateActiveUserWithoutHandler(targetUserId);
+                }
+            }
+        });
+    }
+
+    /**
+     * Schedules the {@link FaceUpdateActiveUserClient} without posting the work onto the
+     * handler. Many/most APIs are user-specific. However, the HAL requires explicit "setActiveUser"
+     * invocation prior to authenticate/enroll/etc. Thus, internally we usually want to schedule
+     * this operation on the same lambda/runnable as those operations so that the ordering is
+     * correct.
+     */
+    private void scheduleUpdateActiveUserWithoutHandler(int targetUserId) {
+        final boolean hasEnrolled = !getEnrolledFaces(mSensorId, targetUserId).isEmpty();
+        final FaceUpdateActiveUserClient client = new FaceUpdateActiveUserClient(mContext,
+                mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId, mCurrentUserId,
+                hasEnrolled, mAuthenticatorIds);
+        mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
+            @Override
+            public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) {
+                if (success) {
+                    mCurrentUserId = targetUserId;
+                }
+            }
+        });
+    }
+
     public void dumpHal(@NonNull FileDescriptor fd, @NonNull String[] args) {
         // WARNING: CDD restricts image data from leaving TEE unencrypted on
         //          production devices:
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 83f10c8..a298e19 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
@@ -16,10 +16,12 @@
 
 package com.android.server.biometrics.sensors.face;
 
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.MANAGE_BIOMETRIC;
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricsProtoEnums;
@@ -32,7 +34,10 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.NativeHandle;
+import android.os.UserHandle;
+import android.util.Pair;
 import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
 import android.view.Surface;
 
 import com.android.internal.util.DumpUtils;
@@ -46,7 +51,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -58,9 +63,65 @@
 
     protected static final String TAG = "FaceService";
 
-    private Face10 mFace10;
     private final LockoutResetDispatcher mLockoutResetDispatcher;
     private final LockPatternUtils mLockPatternUtils;
+    @NonNull
+    private List<ServiceProvider> mServiceProviders;
+
+    @Nullable
+    private ServiceProvider getProviderForSensor(int sensorId) {
+        for (ServiceProvider provider : mServiceProviders) {
+            if (provider.containsSensor(sensorId)) {
+                return provider;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * For devices with only a single provider, returns that provider. If no providers, or multiple
+     * providers exist, returns null.
+     */
+    @Nullable
+    private Pair<Integer, ServiceProvider> getSingleProvider() {
+        final List<FaceSensorPropertiesInternal> properties = getSensorProperties();
+        if (properties.size() != 1) {
+            Slog.e(TAG, "Multiple sensors found: " + properties.size());
+            return null;
+        }
+
+        // Theoretically we can just return the first provider, but maybe this is easier to
+        // understand.
+        final int sensorId = properties.get(0).sensorId;
+        for (ServiceProvider provider : mServiceProviders) {
+            if (provider.containsSensor(sensorId)) {
+                return new Pair<>(sensorId, provider);
+            }
+        }
+
+        Slog.e(TAG, "Single sensor, but provider not found");
+        return null;
+    }
+
+    @NonNull
+    private List<FaceSensorPropertiesInternal> getSensorProperties() {
+        final List<FaceSensorPropertiesInternal> properties = new ArrayList<>();
+        for (ServiceProvider provider : mServiceProviders) {
+            properties.addAll(provider.getSensorProperties());
+        }
+        return properties;
+    }
+
+    @NonNull
+    private List<Face> getEnrolledFaces(int userId, String opPackageName) {
+        final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+        if (provider == null) {
+            Slog.w(TAG, "Null provider for getEnrolledFaces, caller: " + opPackageName);
+            return Collections.emptyList();
+        }
+
+        return provider.second.getEnrolledFaces(provider.first, userId);
+    }
 
     /**
      * Receives the incoming binder calls from FaceManager.
@@ -69,13 +130,10 @@
         @Override // Binder call
         public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(
                 String opPackageName) {
-            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
-            final List<FaceSensorPropertiesInternal> properties = new ArrayList<>();
-
-            if (mFace10 != null) {
-                properties.add(mFace10.getFaceSensorProperties());
-            }
+            final List<FaceSensorPropertiesInternal> properties =
+                    FaceService.this.getSensorProperties();
 
             Slog.d(TAG, "Retrieved sensor properties for: " + opPackageName
                     + ", sensors: " + properties.size());
@@ -83,27 +141,31 @@
         }
 
         @Override // Binder call
-        public void generateChallenge(IBinder token, int sensorId, IFaceServiceReceiver receiver,
-                String opPackageName) {
+        public void generateChallenge(IBinder token, int sensorId, int userId,
+                IFaceServiceReceiver receiver, String opPackageName) {
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
-            if (sensorId == mFace10.getFaceSensorProperties().sensorId) {
-                mFace10.scheduleGenerateChallenge(token, receiver, opPackageName);
+
+            final ServiceProvider provider = getProviderForSensor(sensorId);
+            if (provider == null) {
+                Slog.w(TAG, "No matching sensor for generateChallenge, sensorId: " + sensorId);
                 return;
             }
 
-            Slog.w(TAG, "No matching sensor for generateChallenge, sensorId: " + sensorId);
+            provider.scheduleGenerateChallenge(sensorId, userId, token, receiver, opPackageName);
         }
 
         @Override // Binder call
-        public void revokeChallenge(IBinder token, int sensorId, String owner) {
+        public void revokeChallenge(IBinder token, int sensorId, int userId, String opPackageName,
+                long challenge) {
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
-            if (sensorId == mFace10.getFaceSensorProperties().sensorId) {
-                mFace10.scheduleRevokeChallenge(token, owner);
+            final ServiceProvider provider = getProviderForSensor(sensorId);
+            if (provider == null) {
+                Slog.w(TAG, "No matching sensor for revokeChallenge, sensorId: " + sensorId);
                 return;
             }
 
-            Slog.w(TAG, "No matching sensor for revokeChallenge, sensorId: " + sensorId);
+            provider.scheduleRevokeChallenge(sensorId, userId, token, opPackageName, challenge);
         }
 
         @Override // Binder call
@@ -111,8 +173,16 @@
                 final IFaceServiceReceiver receiver, final String opPackageName,
                 final int[] disabledFeatures, Surface surface) {
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
-            mFace10.scheduleEnroll(token, hardwareAuthToken, userId, receiver, opPackageName,
-                    disabledFeatures, convertSurfaceToNativeHandle(surface));
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for enroll");
+                return;
+            }
+
+            provider.second.scheduleEnroll(provider.first, token, hardwareAuthToken, userId,
+                    receiver, opPackageName, disabledFeatures,
+                    convertSurfaceToNativeHandle(surface));
         }
 
         @Override // Binder call
@@ -126,7 +196,14 @@
         @Override // Binder call
         public void cancelEnrollment(final IBinder token) {
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
-            mFace10.cancelEnrollment(token);
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for cancelEnrollment");
+                return;
+            }
+
+            provider.second.cancelEnrollment(provider.first, token);
         }
 
         @Override // Binder call
@@ -141,9 +218,21 @@
             final int statsClient = Utils.isKeyguard(getContext(), opPackageName)
                     ? BiometricsProtoEnums.CLIENT_KEYGUARD
                     : BiometricsProtoEnums.CLIENT_UNKNOWN;
-            mFace10.scheduleAuthenticate(token, operationId, userId, 0 /* cookie */,
+
+            // Keyguard check must be done on the caller's binder identity, since it also checks
+            // permission.
+            final boolean isKeyguard = Utils.isKeyguard(getContext(), opPackageName);
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for authenticate");
+                return;
+            }
+
+            provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
+                    0 /* cookie */,
                     new ClientMonitorCallbackConverter(receiver), opPackageName, restricted,
-                    statsClient);
+                    statsClient, isKeyguard);
         }
 
         @Override // Binder call
@@ -172,22 +261,42 @@
                 int callingUserId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for prepareForAuthentication");
+                return;
+            }
+
             final boolean restricted = true; // BiometricPrompt is always restricted
-            mFace10.scheduleAuthenticate(token, operationId, userId, cookie,
-                    new ClientMonitorCallbackConverter(sensorReceiver), opPackageName,
-                    restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT);
+            provider.second.scheduleAuthenticate(provider.first, token, operationId, userId, cookie,
+                    new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted,
+                    BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, false /* isKeyguard */);
         }
 
         @Override // Binder call
         public void startPreparedClient(int cookie) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            mFace10.startPreparedClient(cookie);
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for startPreparedClient");
+                return;
+            }
+
+            provider.second.startPreparedClient(provider.first, cookie);
         }
 
         @Override // Binder call
         public void cancelAuthentication(final IBinder token, final String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            mFace10.cancelAuthentication(token);
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for cancelAuthentication");
+                return;
+            }
+
+            provider.second.cancelAuthentication(provider.first, token);
         }
 
         @Override // Binder call
@@ -206,14 +315,29 @@
         public void cancelAuthenticationFromService(final IBinder token, final String opPackageName,
                 int callingUid, int callingPid, int callingUserId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            mFace10.cancelAuthentication(token);
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for cancelAuthenticationFromService");
+                return;
+            }
+
+            provider.second.cancelAuthentication(provider.first, token);
         }
 
         @Override // Binder call
         public void remove(final IBinder token, final int faceId, final int userId,
                 final IFaceServiceReceiver receiver, final String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            mFace10.scheduleRemove(token, faceId, userId, receiver, opPackageName);
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for remove");
+                return;
+            }
+
+            provider.second.scheduleRemove(provider.first, token, faceId, userId, receiver,
+                    opPackageName);
         }
 
         @Override
@@ -231,10 +355,28 @@
 
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (args.length > 1 && "--hal".equals(args[0])) {
-                    mFace10.dumpHal(fd, Arrays.copyOfRange(args, 1, args.length, args.getClass()));
+                if (args.length > 1 && "--proto".equals(args[0]) && "--state".equals(args[1])) {
+                    final ProtoOutputStream proto = new ProtoOutputStream(fd);
+                    for (ServiceProvider provider : mServiceProviders) {
+                        for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
+                            provider.dumpProtoState(props.sensorId, proto);
+                        }
+                    }
+                    proto.flush();
+                } else if (args.length > 0 && "--proto".equals(args[0])) {
+                    for (ServiceProvider provider : mServiceProviders) {
+                        for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
+                            provider.dumpProtoMetrics(props.sensorId, fd);
+                        }
+                    }
                 } else {
-                    mFace10.dump(pw);
+                    for (ServiceProvider provider : mServiceProviders) {
+                        for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
+                            pw.println("Dumping for sensorId: " + props.sensorId
+                                    + ", provider: " + provider.getClass().getSimpleName());
+                            provider.dumpInternal(props.sensorId, pw);
+                        }
+                    }
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -244,13 +386,15 @@
         @Override // Binder call
         public boolean isHardwareDetected(String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            if (mFace10 == null) {
-                Slog.wtf(TAG, "No HAL, caller: " + opPackageName);
-                return false;
-            }
+
             final long token = Binder.clearCallingIdentity();
             try {
-                return mFace10.isHardwareDetected();
+                final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+                if (provider == null) {
+                    Slog.w(TAG, "Null provider for isHardwareDetected, caller: " + opPackageName);
+                    return false;
+                }
+                return provider.second.isHardwareDetected(provider.first);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -259,25 +403,50 @@
         @Override // Binder call
         public List<Face> getEnrolledFaces(int userId, String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            return mFace10.getEnrolledFaces(userId);
+
+            if (userId != UserHandle.getCallingUserId()) {
+                Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
+            }
+
+            return FaceService.this.getEnrolledFaces(userId, opPackageName);
         }
 
         @Override // Binder call
         public boolean hasEnrolledFaces(int userId, String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            return !mFace10.getEnrolledFaces(userId).isEmpty();
+
+            if (userId != UserHandle.getCallingUserId()) {
+                Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
+            }
+
+            return !FaceService.this.getEnrolledFaces(userId, opPackageName).isEmpty();
         }
 
-        @Override
-        public @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) {
+        @Override // Binder call
+        @LockoutTracker.LockoutMode
+        public int getLockoutModeForUser(int userId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            return mFace10.getLockoutModeForUser(userId);
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for getLockoutModeForUser");
+                return LockoutTracker.LOCKOUT_NONE;
+            }
+
+            return provider.second.getLockoutModeForUser(provider.first, userId);
         }
 
         @Override // Binder call
         public long getAuthenticatorId(int userId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            return mFace10.getAuthenticatorId(userId);
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for getAuthenticatorId");
+                return 0;
+            }
+
+            return provider.second.getAuthenticatorId(provider.first, userId);
         }
 
         @Override // Binder call
@@ -285,12 +454,13 @@
                 String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            if (sensorId == mFace10.getFaceSensorProperties().sensorId) {
-                mFace10.scheduleResetLockout(userId, hardwareAuthToken);
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for resetLockout, caller: " + opPackageName);
                 return;
             }
 
-            Slog.w(TAG, "No matching sensor for resetLockout, sensorId: " + sensorId);
+            provider.second.scheduleResetLockout(provider.first, userId, hardwareAuthToken);
         }
 
         @Override
@@ -298,15 +468,29 @@
                 final byte[] hardwareAuthToken, IFaceServiceReceiver receiver,
                 final String opPackageName) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            mFace10.scheduleSetFeature(token, userId, feature, enabled, hardwareAuthToken, receiver,
-                    opPackageName);
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for setFeature");
+                return;
+            }
+
+            provider.second.scheduleSetFeature(provider.first, token, userId, feature, enabled,
+                    hardwareAuthToken, receiver, opPackageName);
         }
 
         @Override
         public void getFeature(final IBinder token, int userId, int feature,
                 IFaceServiceReceiver receiver, final String opPackageName) {
             Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
-            mFace10.scheduleGetFeature(token, userId, feature,
+
+            final Pair<Integer, ServiceProvider> provider = getSingleProvider();
+            if (provider == null) {
+                Slog.w(TAG, "Null provider for getFeature");
+                return;
+            }
+
+            provider.second.scheduleGetFeature(provider.first, token, userId, feature,
                     new ClientMonitorCallbackConverter(receiver), opPackageName);
         }
 
@@ -314,7 +498,8 @@
         public void initializeConfiguration(int sensorId,
                 @BiometricManager.Authenticators.Types int strength) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
-            mFace10 = new Face10(getContext(), sensorId, strength, mLockoutResetDispatcher);
+            mServiceProviders.add(
+                    new Face10(getContext(), sensorId, strength, mLockoutResetDispatcher));
         }
     }
 
@@ -322,6 +507,7 @@
         super(context);
         mLockoutResetDispatcher = new LockoutResetDispatcher(context);
         mLockPatternUtils = new LockPatternUtils(context);
+        mServiceProviders = new ArrayList<>();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
new file mode 100644
index 0000000..e3fb750
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
@@ -0,0 +1,113 @@
+/*
+ * 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.biometrics.sensors.face;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.hardware.face.Face;
+import android.hardware.face.FaceSensorPropertiesInternal;
+import android.hardware.face.IFaceServiceReceiver;
+import android.os.IBinder;
+import android.os.NativeHandle;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
+import com.android.server.biometrics.sensors.LockoutTracker;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * Superset of features across all the face HAL interfaces that are available to the framework. This
+ * is more or less mapped to the public and private APIs that {@link FaceManager} provides, and
+ * is used at the system server layer to provide easy mapping between requests and providers.
+ *
+ * Note that providers support both single-sensor and multi-sensor HALs. In either case,
+ * {@link FaceService} must ensure that providers are only requested to perform operations
+ * on sensors that they own.
+ *
+ * For methods other than {@link #containsSensor(int)}, the caller must ensure that the sensorId
+ * is supported by the provider. For example:
+ * if (serviceProvider.containsSensor(sensorId)) {
+ * serviceProvider.operation(sensorId, ...);
+ * }
+ *
+ * For operations that are supported by some providers but not others, clients are required
+ * to check (e.g. via {@link FaceManager#getSensorPropertiesInternal()}) that the code path isn't
+ * taken. ServiceProviders will provide a no-op for unsupported operations to fail safely.
+ */
+public interface ServiceProvider {
+    /**
+     * Checks if the specified sensor is owned by this provider.
+     */
+    boolean containsSensor(int sensorId);
+
+    @NonNull
+    List<FaceSensorPropertiesInternal> getSensorProperties();
+
+    @NonNull
+    List<Face> getEnrolledFaces(int sensorId, int userId);
+
+    @LockoutTracker.LockoutMode
+    int getLockoutModeForUser(int sensorId, int userId);
+
+    long getAuthenticatorId(int sensorId, int userId);
+
+    boolean isHardwareDetected(int sensorId);
+
+    void scheduleGenerateChallenge(int sensorId, int userId, @NonNull IBinder token,
+            @NonNull IFaceServiceReceiver receiver, String opPackageName);
+
+    void scheduleRevokeChallenge(int sensorId, int userId, @NonNull IBinder token,
+            @NonNull String opPackageName, long challenge);
+
+    void scheduleEnroll(int sensorId, @NonNull IBinder token, @NonNull byte[] hardwareAuthToken,
+            int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName,
+            @NonNull int[] disabledFeatures, @Nullable NativeHandle surfaceHandle);
+
+    void cancelEnrollment(int sensorId, @NonNull IBinder token);
+
+    void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
+            int cookie, @NonNull ClientMonitorCallbackConverter callback,
+            @NonNull String opPackageName, boolean restricted, int statsClient, boolean isKeyguard);
+
+
+    void cancelAuthentication(int sensorId, @NonNull IBinder token);
+
+    void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId,
+            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName);
+
+    void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken);
+
+    void scheduleSetFeature(int sensorId, @NonNull IBinder token, int userId, int feature,
+            boolean enabled, @NonNull byte[] hardwareAuthToken,
+            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName);
+
+    void scheduleGetFeature(int sensorId, @NonNull IBinder token, int userId, int feature,
+            @NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName);
+
+    void startPreparedClient(int sensorId, int cookie);
+
+    void scheduleInternalCleanup(int sensorId, int userId);
+
+    void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto);
+
+    void dumpProtoMetrics(int sensorId, @NonNull FileDescriptor fd);
+
+    void dumpInternal(int sensorId, @NonNull PrintWriter pw);
+}
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 c88247f..265ba05 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
@@ -469,6 +469,27 @@
         }
 
         @Override // Binder call
+        public boolean hasEnrolledTemplatesForAnySensor(int userId,
+                @NonNull List<FingerprintSensorPropertiesInternal> sensors,
+                @NonNull String opPackageName) {
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+
+            for (FingerprintSensorPropertiesInternal prop : sensors) {
+                final ServiceProvider provider = getProviderForSensor(prop.sensorId);
+                if (provider == null) {
+                    Slog.w(TAG, "Null provider for sensorId: " + prop.sensorId
+                            + ", caller: " + opPackageName);
+                    continue;
+                }
+
+                if (!provider.getEnrolledFingerprints(prop.sensorId, userId).isEmpty()) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override // Binder call
         public @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) {
             Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index a806e3f..8c766d6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -646,8 +646,7 @@
 
     @Override
     public boolean isHardwareDetected(int sensorId) {
-        final IBiometricsFingerprint daemon = getDaemon();
-        return daemon != null;
+        return getDaemon() != null;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 88867fc..a4ae9c8 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.camera;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
@@ -39,6 +40,7 @@
 import android.util.ArraySet;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.FrameworkStatsLog;
@@ -48,6 +50,8 @@
 import com.android.server.SystemService.TargetUser;
 import com.android.server.wm.WindowManagerInternal;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -79,10 +83,19 @@
 
     // Handler message codes
     private static final int MSG_SWITCH_USER = 1;
+    private static final int MSG_NOTIFY_DEVICE_STATE = 2;
 
     private static final int RETRY_DELAY_TIME = 20; //ms
     private static final int RETRY_TIMES = 60;
 
+    @IntDef(flag = true, prefix = { "DEVICE_STATE_" }, value = {
+            ICameraService.DEVICE_STATE_BACK_COVERED,
+            ICameraService.DEVICE_STATE_FRONT_COVERED,
+            ICameraService.DEVICE_STATE_FOLDED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DeviceStateFlags {}
+
     // Maximum entries to keep in usage history before dumping out
     private static final int MAX_USAGE_HISTORY = 100;
 
@@ -94,6 +107,15 @@
     private final Object mLock = new Object();
     private Set<Integer> mEnabledCameraUsers;
     private int mLastUser;
+    // The current set of device state flags. May be different from mLastReportedDeviceState if the
+    // native camera service has not been notified of the change.
+    @GuardedBy("mLock")
+    @DeviceStateFlags
+    private int mDeviceState;
+    // The most recent device state flags reported to the native camera server.
+    @GuardedBy("mLock")
+    @DeviceStateFlags
+    private int mLastReportedDeviceState;
 
     private ICameraService mCameraServiceRaw;
 
@@ -185,6 +207,7 @@
                 return;
             }
             notifySwitchWithRetries(RETRY_TIMES);
+            notifyDeviceStateWithRetries(RETRY_TIMES);
         }
 
         @Override
@@ -218,12 +241,55 @@
         mLogWriterService.allowCoreThreadTimeOut(true);
     }
 
+    /**
+     * Sets the device state bits set within {@code deviceStateFlags} leaving all other bits the
+     * same.
+     * <p>
+     * Calling requires permission {@link android.Manifest.permission#CAMERA_SEND_SYSTEM_EVENTS}.
+     *
+     * @param deviceStateFlags a bitmask of the device state bits that should be set.
+     *
+     * @see #clearDeviceStateFlags(int)
+     */
+    public void setDeviceStateFlags(@DeviceStateFlags int deviceStateFlags) {
+        synchronized (mLock) {
+            mHandler.removeMessages(MSG_NOTIFY_DEVICE_STATE);
+            mDeviceState |= deviceStateFlags;
+            if (mDeviceState != mLastReportedDeviceState) {
+                notifyDeviceStateWithRetriesLocked(RETRY_TIMES);
+            }
+        }
+    }
+
+    /**
+     * Clears the device state bits set within {@code deviceStateFlags} leaving all other bits the
+     * same.
+     * <p>
+     * Calling requires permission {@link android.Manifest.permission#CAMERA_SEND_SYSTEM_EVENTS}.
+     *
+     * @param deviceStateFlags a bitmask of the device state bits that should be cleared.
+     *
+     * @see #setDeviceStateFlags(int)
+     */
+    public void clearDeviceStateFlags(@DeviceStateFlags int deviceStateFlags) {
+        synchronized (mLock) {
+            mHandler.removeMessages(MSG_NOTIFY_DEVICE_STATE);
+            mDeviceState &= ~deviceStateFlags;
+            if (mDeviceState != mLastReportedDeviceState) {
+                notifyDeviceStateWithRetriesLocked(RETRY_TIMES);
+            }
+        }
+    }
+
     @Override
     public boolean handleMessage(Message msg) {
         switch(msg.what) {
             case MSG_SWITCH_USER: {
                 notifySwitchWithRetries(msg.arg1);
             } break;
+            case MSG_NOTIFY_DEVICE_STATE: {
+                notifyDeviceStateWithRetries(msg.arg1);
+            } break;
             default: {
                 Slog.e(TAG, "CameraServiceProxy error, invalid message: " + msg.what);
             } break;
@@ -386,6 +452,25 @@
         }
     }
 
+    @Nullable
+    private ICameraService getCameraServiceRawLocked() {
+        if (mCameraServiceRaw == null) {
+            IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
+            if (cameraServiceBinder == null) {
+                return null;
+            }
+            try {
+                cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Could not link to death of native camera service");
+                return null;
+            }
+
+            mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
+        }
+        return mCameraServiceRaw;
+    }
+
     private void switchUserLocked(int userHandle) {
         Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
         mLastUser = userHandle;
@@ -431,20 +516,10 @@
     private boolean notifyCameraserverLocked(int eventType, Set<Integer> updatedUserHandles) {
         // Forward the user switch event to the native camera service running in the cameraserver
         // process.
-        if (mCameraServiceRaw == null) {
-            IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
-            if (cameraServiceBinder == null) {
-                Slog.w(TAG, "Could not notify cameraserver, camera service not available.");
-                return false; // Camera service not active, cannot evict user clients.
-            }
-            try {
-                cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Could not link to death of native camera service");
-                return false;
-            }
-
-            mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
+        ICameraService cameraService = getCameraServiceRawLocked();
+        if (cameraService == null) {
+            Slog.w(TAG, "Could not notify cameraserver, camera service not available.");
+            return false;
         }
 
         try {
@@ -457,6 +532,43 @@
         return true;
     }
 
+    private void notifyDeviceStateWithRetries(int retries) {
+        synchronized (mLock) {
+            notifyDeviceStateWithRetriesLocked(retries);
+        }
+    }
+
+    private void notifyDeviceStateWithRetriesLocked(int retries) {
+        if (notifyDeviceStateChangeLocked(mDeviceState)) {
+            return;
+        }
+        if (retries <= 0) {
+            return;
+        }
+        Slog.i(TAG, "Could not notify camera service of device state change, retrying...");
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_NOTIFY_DEVICE_STATE, retries - 1,
+                0, null), RETRY_DELAY_TIME);
+    }
+
+    private boolean notifyDeviceStateChangeLocked(@DeviceStateFlags int deviceState) {
+        // Forward the state to the native camera service running in the cameraserver process.
+        ICameraService cameraService = getCameraServiceRawLocked();
+        if (cameraService == null) {
+            Slog.w(TAG, "Could not notify cameraserver, camera service not available.");
+            return false;
+        }
+
+        try {
+            mCameraServiceRaw.notifyDeviceStateChange(deviceState);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Could not notify cameraserver, remote exception: " + e);
+            // Not much we can do if camera service is dead.
+            return false;
+        }
+        mLastReportedDeviceState = deviceState;
+        return true;
+    }
+
     private void updateActivityCount(String cameraId, int newCameraState, int facing,
             String clientName, int apiLevel) {
         synchronized(mLock) {
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index bc3bff1..ff31931 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -18,7 +18,7 @@
 
 import android.annotation.Nullable;
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledAfter;
+import android.compat.annotation.EnabledSince;
 import android.content.pm.ApplicationInfo;
 
 import com.android.internal.compat.CompatibilityChangeInfo;
@@ -43,8 +43,8 @@
      * A change ID to be used only in the CTS test for this SystemApi
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = 1234) // Needs to be > test APK targetSdkVersion.
-    private static final long CTS_SYSTEM_API_CHANGEID = 149391281; // This is a bug id.
+    @EnabledSince(targetSdkVersion = 1235) // Needs to be > test APK targetSdkVersion.
+    static final long CTS_SYSTEM_API_CHANGEID = 149391281; // This is a bug id.
 
     /**
      * Callback listener for when compat changes are updated for a package.
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index e4f52f1..77d5411 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -381,6 +381,9 @@
         if (change.getLoggingOnly()) {
             return false;
         }
+        if (change.getId() == CompatChange.CTS_SYSTEM_API_CHANGEID) {
+            return false;
+        }
         if (change.getEnableSinceTargetSdk() > 0) {
             if (change.getEnableSinceTargetSdk() < sMinTargetSdk
                     || change.getEnableSinceTargetSdk() > sMaxTargetSdk) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 3d22d6d..3385393 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -21,6 +21,7 @@
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 
+import android.annotation.NonNull;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -30,6 +31,7 @@
 import android.net.NetworkSpecifier;
 import android.net.TelephonyNetworkSpecifier;
 import android.net.wifi.WifiInfo;
+import android.os.UserHandle;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -83,10 +85,12 @@
     // Tracks the types of notifications managed by this instance, from creation to cancellation.
     private final SparseIntArray mNotificationTypeMap;
 
-    public NetworkNotificationManager(Context c, TelephonyManager t, NotificationManager n) {
+    public NetworkNotificationManager(@NonNull final Context c, @NonNull final TelephonyManager t) {
         mContext = c;
         mTelephonyManager = t;
-        mNotificationManager = n;
+        mNotificationManager =
+                (NotificationManager) c.createContextAsUser(UserHandle.ALL, 0 /* flags */)
+                        .getSystemService(Context.NOTIFICATION_SERVICE);
         mNotificationTypeMap = new SparseIntArray();
     }
 
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 6a3e7b7..b10cd12 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -227,8 +227,35 @@
     private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
             new CopyOnWriteArrayList<DisplayTransactionListener>();
 
-    // Display power controller.
-    private DisplayPowerController mDisplayPowerController;
+    /** All {@link DisplayPowerController}s indexed by {@link LogicalDisplay} ID. */
+    private final SparseArray<DisplayPowerController> mDisplayPowerControllers =
+            new SparseArray<>();
+
+    /** {@link DisplayBlanker} used by all {@link DisplayPowerController}s. */
+    private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() {
+        @Override
+        public void requestDisplayState(int displayId, int state, float brightness) {
+            // The order of operations is important for legacy reasons.
+            if (state == Display.STATE_OFF) {
+                requestGlobalDisplayStateInternal(state, brightness);
+            }
+
+            mDisplayPowerCallbacks.onDisplayStateChange(state);
+
+            if (state != Display.STATE_OFF) {
+                requestGlobalDisplayStateInternal(state, brightness);
+            }
+        }
+    };
+
+    /**
+     * Used to inform {@link com.android.server.power.PowerManagerService} of changes to display
+     * state.
+     */
+    private DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks;
+
+    /** The {@link Handler} used by all {@link DisplayPowerController}s. */
+    private Handler mPowerHandler;
 
     // The overall display state, independent of changes that might influence one
     // display or another in particular.
@@ -419,14 +446,16 @@
         final int newUserId = to.getUserIdentifier();
         final int userSerial = getUserManager().getUserSerialNumber(newUserId);
         synchronized (mSyncRoot) {
+            final DisplayPowerController displayPowerController = mDisplayPowerControllers.get(
+                    Display.DEFAULT_DISPLAY);
             if (mCurrentUserId != newUserId) {
                 mCurrentUserId = newUserId;
                 BrightnessConfiguration config =
                         mPersistentDataStore.getBrightnessConfiguration(userSerial);
-                mDisplayPowerController.setBrightnessConfiguration(config);
+                displayPowerController.setBrightnessConfiguration(config);
                 handleSettingsChange();
             }
-            mDisplayPowerController.onSwitchUser(newUserId);
+            displayPowerController.onSwitchUser(newUserId);
         }
     }
 
@@ -957,6 +986,7 @@
             recordStableDisplayStatsIfNeededLocked(display);
             recordTopInsetLocked(display);
         }
+        addDisplayPowerControllerLocked(displayId);
 
         DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
 
@@ -990,6 +1020,7 @@
 
     private void handleLogicalDisplayRemovedLocked(@NonNull LogicalDisplay display) {
         final int displayId = display.getDisplayIdLocked();
+        mDisplayPowerControllers.delete(displayId);
         DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
         sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
         scheduleTraversalLocked(false);
@@ -1111,7 +1142,7 @@
                 mPersistentDataStore.saveIfNeeded();
             }
             if (userId == mCurrentUserId) {
-                mDisplayPowerController.setBrightnessConfiguration(c);
+                mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY).setBrightnessConfiguration(c);
             }
         }
     }
@@ -1143,7 +1174,8 @@
             final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId);
             BrightnessConfiguration config =
                     mPersistentDataStore.getBrightnessConfiguration(userSerial);
-            mDisplayPowerController.setBrightnessConfiguration(config);
+            mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY).setBrightnessConfiguration(
+                    config);
         }
     }
 
@@ -1350,25 +1382,31 @@
     }
 
     void setAutoBrightnessLoggingEnabled(boolean enabled) {
-        if (mDisplayPowerController != null) {
-            synchronized (mSyncRoot) {
-                mDisplayPowerController.setAutoBrightnessLoggingEnabled(enabled);
+        synchronized (mSyncRoot) {
+            final DisplayPowerController displayPowerController = mDisplayPowerControllers.get(
+                    Display.DEFAULT_DISPLAY);
+            if (displayPowerController != null) {
+                displayPowerController.setAutoBrightnessLoggingEnabled(enabled);
             }
         }
     }
 
     void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) {
-        if (mDisplayPowerController != null) {
-            synchronized (mSyncRoot) {
-                mDisplayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled);
+        synchronized (mSyncRoot) {
+            final DisplayPowerController displayPowerController = mDisplayPowerControllers.get(
+                    Display.DEFAULT_DISPLAY);
+            if (displayPowerController != null) {
+                displayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled);
             }
         }
     }
 
     void setAmbientColorTemperatureOverride(float cct) {
-        if (mDisplayPowerController != null) {
-            synchronized (mSyncRoot) {
-                mDisplayPowerController.setAmbientColorTemperatureOverride(cct);
+        synchronized (mSyncRoot) {
+            final DisplayPowerController displayPowerController = mDisplayPowerControllers.get(
+                    Display.DEFAULT_DISPLAY);
+            if (displayPowerController != null) {
+                displayPowerController.setAmbientColorTemperatureOverride(cct);
             }
         }
     }
@@ -1594,8 +1632,11 @@
                         + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested);
             }
 
-            if (mDisplayPowerController != null) {
-                mDisplayPowerController.dump(pw);
+            final int displayPowerControllerCount = mDisplayPowerControllers.size();
+            pw.println();
+            pw.println("Display Power Controllers: size=" + displayPowerControllerCount);
+            for (int i = 0; i < displayPowerControllerCount; i++) {
+                mDisplayPowerControllers.valueAt(i).dump(pw);
             }
 
             pw.println();
@@ -1668,6 +1709,22 @@
         }
     }
 
+    private void initializeDisplayPowerControllersLocked() {
+        mLogicalDisplayMapper.forEachLocked((logicalDisplay) -> addDisplayPowerControllerLocked(
+                logicalDisplay.getDisplayIdLocked()));
+    }
+
+    private void addDisplayPowerControllerLocked(int displayId) {
+        if (mPowerHandler == null) {
+            // initPowerManagement has not yet been called.
+            return;
+        }
+        final DisplayPowerController displayPowerController = new DisplayPowerController(
+                mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager,
+                mDisplayBlanker, displayId);
+        mDisplayPowerControllers.append(displayId, displayPowerController);
+    }
+
     private final class DisplayManagerHandler extends Handler {
         public DisplayManagerHandler(Looper looper) {
             super(looper, null, true /*async*/);
@@ -2187,7 +2244,8 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mSyncRoot) {
-                    return mDisplayPowerController.getBrightnessEvents(userId, hasUsageStats);
+                    return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                            .getBrightnessEvents(userId, hasUsageStats);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -2204,7 +2262,8 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mSyncRoot) {
-                    return mDisplayPowerController.getAmbientBrightnessStats(userId);
+                    return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                            .getAmbientBrightnessStats(userId);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -2252,7 +2311,8 @@
                     BrightnessConfiguration config =
                             mPersistentDataStore.getBrightnessConfiguration(userSerial);
                     if (config == null) {
-                        config = mDisplayPowerController.getDefaultBrightnessConfiguration();
+                        config = mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                                .getDefaultBrightnessConfiguration();
                     }
                     return config;
                 }
@@ -2269,7 +2329,8 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mSyncRoot) {
-                    return mDisplayPowerController.getDefaultBrightnessConfiguration();
+                    return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                            .getDefaultBrightnessConfiguration();
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -2292,7 +2353,8 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mSyncRoot) {
-                    mDisplayPowerController.setTemporaryBrightness(brightness);
+                    mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                            .setTemporaryBrightness(brightness);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -2307,7 +2369,8 @@
             final long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mSyncRoot) {
-                    mDisplayPowerController.setTemporaryAutoBrightnessAdjustment(adjustment);
+                    mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                            .setTemporaryAutoBrightnessAdjustment(adjustment);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -2428,25 +2491,10 @@
         public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
                 SensorManager sensorManager) {
             synchronized (mSyncRoot) {
-                DisplayBlanker blanker = new DisplayBlanker() {
-                    @Override
-                    public void requestDisplayState(int displayId, int state, float brightness) {
-                        // The order of operations is important for legacy reasons.
-                        if (state == Display.STATE_OFF) {
-                            requestGlobalDisplayStateInternal(state, brightness);
-                        }
-
-                        callbacks.onDisplayStateChange(state);
-
-                        if (state != Display.STATE_OFF) {
-                            requestGlobalDisplayStateInternal(state, brightness);
-                        }
-                    }
-                };
-                mDisplayPowerController = new DisplayPowerController(
-                        mContext, callbacks, handler, sensorManager, blanker,
-                        Display.DEFAULT_DISPLAY);
+                mDisplayPowerCallbacks = callbacks;
                 mSensorManager = sensorManager;
+                mPowerHandler = handler;
+                initializeDisplayPowerControllersLocked();
             }
 
             mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
@@ -2456,14 +2504,16 @@
         public boolean requestPowerState(DisplayPowerRequest request,
                 boolean waitForNegativeProximity) {
             synchronized (mSyncRoot) {
-                return mDisplayPowerController.requestPowerState(request, waitForNegativeProximity);
+                return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                        .requestPowerState(request, waitForNegativeProximity);
             }
         }
 
         @Override
         public boolean isProximitySensorAvailable() {
             synchronized (mSyncRoot) {
-                return mDisplayPowerController.isProximitySensorAvailable();
+                return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                        .isProximitySensorAvailable();
             }
         }
 
@@ -2552,7 +2602,8 @@
         @Override
         public void persistBrightnessTrackerState() {
             synchronized (mSyncRoot) {
-                mDisplayPowerController.persistBrightnessTrackerState();
+                mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                        .persistBrightnessTrackerState();
             }
         }
 
@@ -2584,7 +2635,8 @@
 
         @Override
         public void ignoreProximitySensorUntilChanged() {
-            mDisplayPowerController.ignoreProximitySensorUntilChanged();
+            mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY)
+                    .ignoreProximitySensorUntilChanged();
         }
     }
 
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 0211876..309271c 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1815,6 +1815,10 @@
     public void dump(final PrintWriter pw) {
         synchronized (mLock) {
             pw.println();
+            pw.println("Display Power Controller:");
+            pw.println("  mDisplayId=" + mDisplayId);
+
+            pw.println();
             pw.println("Display Power Controller Locked State:");
             pw.println("  mDisplayReadyLocked=" + mDisplayReadyLocked);
             pw.println("  mPendingRequestLocked=" + mPendingRequestLocked);
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 9437677..9245f55 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -351,10 +351,9 @@
             if (mDefaultModeId == NO_DISPLAY_MODE_ID) {
                 mDefaultModeId = activeRecord.mMode.getModeId();
                 mDefaultConfigGroup = configs[activeConfigId].configGroup;
-            } else if (modesAdded && mActiveModeId != activeRecord.mMode.getModeId()) {
+            } else if (modesAdded && activeModeChanged) {
                 Slog.d(TAG, "New display modes are added and the active mode has changed, "
                         + "use active mode as default mode.");
-                mActiveModeId = activeRecord.mMode.getModeId();
                 mDefaultModeId = activeRecord.mMode.getModeId();
                 mDefaultConfigGroup = configs[activeConfigId].configGroup;
             } else if (findDisplayConfigIdLocked(mDefaultModeId, mDefaultConfigGroup) < 0) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index 7d76628..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);
@@ -343,6 +361,277 @@
         return true;
     }
 
+    /**
+     * Check if the given value is a valid day of month. A valid value is one which falls within the
+     * range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value day of month
+     * @return true if the day of month is valid
+     */
+    private boolean isValidDayOfMonth(int value) {
+        return isWithinRange(value, 1, 31);
+    }
+
+    /**
+     * Check if the given value is a valid month of year. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value month of year
+     * @return true if the month of year is valid
+     */
+    private boolean isValidMonthOfYear(int value) {
+        return isWithinRange(value, 1, 12);
+    }
+
+    /**
+     * Check if the given value is a valid hour. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value hour
+     * @return true if the hour is valid
+     */
+    private boolean isValidHour(int value) {
+        return isWithinRange(value, 0, 23);
+    }
+
+    /**
+     * Check if the given value is a valid minute. A valid value is one which falls within the range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value minute
+     * @return true if the minute is valid
+     */
+    private boolean isValidMinute(int value) {
+        return isWithinRange(value, 0, 59);
+    }
+
+    /**
+     * Check if the given value is a valid duration hours. A valid value is one which falls within
+     * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value duration hours
+     * @return true if the duration hours is valid
+     */
+    private boolean isValidDurationHours(int value) {
+        return isWithinRange(value, 0, 99);
+    }
+
+    /**
+     * Check if the given value is a valid recording sequence. A valid value is adheres to range
+     * description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
+     *
+     * @param value recording sequence
+     * @return true if the given recording sequence is valid
+     */
+    private boolean isValidRecordingSequence(int value) {
+        value = value & 0xFF;
+        // Validate bit 7 is set to zero
+        if ((value & 0x80) != 0x00) {
+            return false;
+        }
+        // Validate than not more than one bit is set
+        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) {
@@ -472,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/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 16a4b72..9a60afb 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -234,7 +234,6 @@
     static final int MSG_SET_ACTIVE = 3020;
     static final int MSG_SET_INTERACTIVE = 3030;
     static final int MSG_REPORT_FULLSCREEN_MODE = 3045;
-    static final int MSG_REPORT_PRE_RENDERED = 3060;
     static final int MSG_APPLY_IME_VISIBILITY = 3070;
 
     static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
@@ -317,8 +316,6 @@
     private static final class DebugFlags {
         static final DebugFlag FLAG_OPTIMIZE_START_INPUT =
                 new DebugFlag("debug.optimize_startinput", false);
-        static final DebugFlag FLAG_PRE_RENDER_IME_VIEWS =
-                new DebugFlag("persist.pre_render_ime_views", false);
     }
 
     @UserIdInt
@@ -448,10 +445,6 @@
         final ClientDeathRecipient clientDeathRecipient;
 
         boolean sessionRequested;
-        // Determines if IMEs should be pre-rendered.
-        // DebugFlag can be flipped anytime. This flag is kept per-client to maintain behavior
-        // through the life of the current client.
-        boolean shouldPreRenderIme;
         SessionState curSession;
 
         @Override
@@ -3261,9 +3254,6 @@
 
     boolean hideCurrentInputLocked(IBinder windowToken, int flags, ResultReceiver resultReceiver,
             @SoftInputShowHideReason int reason) {
-        if (mCurClient == null || mCurClient.curSession == null) {
-            return false;
-        }
         if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
                 && (mShowExplicitlyRequested || mShowForced)) {
             if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide");
@@ -3440,14 +3430,6 @@
             return InputBindResult.USER_SWITCHING;
         }
 
-        // Main feature flag that overrides other conditions and forces IME preRendering.
-        if (DEBUG) {
-            Slog.v(TAG, "IME PreRendering main flag: "
-                    + DebugFlags.FLAG_PRE_RENDER_IME_VIEWS.value() + ", LowRam: " + mIsLowRam);
-        }
-        // pre-rendering not supported on low-ram devices.
-        cs.shouldPreRenderIme = DebugFlags.FLAG_PRE_RENDER_IME_VIEWS.value() && !mIsLowRam;
-
         final boolean sameWindowFocused = mCurFocusedWindow == windowToken;
         final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0;
         final boolean startInputByWinGainedFocus =
@@ -4141,19 +4123,6 @@
     }
 
     @BinderThread
-    private void reportPreRendered(IBinder token, EditorInfo info) {
-        synchronized (mMethodMap) {
-            if (!calledWithValidTokenLocked(token)) {
-                return;
-            }
-            if (mCurClient != null && mCurClient.client != null) {
-                executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO(
-                        MSG_REPORT_PRE_RENDERED, info, mCurClient));
-            }
-        }
-    }
-
-    @BinderThread
     private void applyImeVisibility(IBinder token, IBinder windowToken, boolean setVisible) {
         synchronized (mMethodMap) {
             if (!calledWithValidTokenLocked(token)) {
@@ -4430,7 +4399,7 @@
                 try {
                     setEnabledSessionInMainThread(session);
                     session.method.startInput(startInputToken, inputContext, missingMethods,
-                            editorInfo, restarting, session.client.shouldPreRenderIme);
+                            editorInfo, restarting);
                 } catch (RemoteException e) {
                 }
                 args.recycle();
@@ -4488,20 +4457,6 @@
                 }
                 return true;
             }
-            case MSG_REPORT_PRE_RENDERED: {
-                args = (SomeArgs) msg.obj;
-                final EditorInfo info = (EditorInfo) args.arg1;
-                final ClientState clientState = (ClientState) args.arg2;
-                try {
-                    clientState.client.reportPreRendered(info);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Got RemoteException sending "
-                            + "reportPreRendered(" + info + ") notification to pid="
-                            + clientState.pid + " uid=" + clientState.uid);
-                }
-                args.recycle();
-                return true;
-            }
             case MSG_APPLY_IME_VISIBILITY: {
                 final boolean setVisible = msg.arg1 != 0;
                 final ClientState clientState = (ClientState) msg.obj;
@@ -5347,7 +5302,6 @@
         @ShellCommandResult
         private int refreshDebugProperties() {
             DebugFlags.FLAG_OPTIMIZE_START_INPUT.refresh();
-            DebugFlags.FLAG_PRE_RENDER_IME_VIEWS.refresh();
             return ShellCommandResult.SUCCESS;
         }
 
@@ -5822,12 +5776,6 @@
 
         @BinderThread
         @Override
-        public void reportPreRendered(EditorInfo info) {
-            mImms.reportPreRendered(mToken, info);
-        }
-
-        @BinderThread
-        @Override
         public void applyImeVisibility(IBinder windowToken, boolean setVisible) {
             mImms.applyImeVisibility(mToken, windowToken, setVisible);
         }
diff --git a/services/core/java/com/android/server/location/ContextHubServiceUtil.java b/services/core/java/com/android/server/location/ContextHubServiceUtil.java
index 76cd9ce..9145eca 100644
--- a/services/core/java/com/android/server/location/ContextHubServiceUtil.java
+++ b/services/core/java/com/android/server/location/ContextHubServiceUtil.java
@@ -30,12 +30,16 @@
 import android.hardware.location.NanoAppBinary;
 import android.hardware.location.NanoAppMessage;
 import android.hardware.location.NanoAppState;
+import android.os.Binder;
+import android.os.Build;
 import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * A class encapsulating helper functions used by the ContextHubService class
@@ -45,6 +49,9 @@
     private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
     private static final String CONTEXT_HUB_PERMISSION = Manifest.permission.ACCESS_CONTEXT_HUB;
 
+    // A set of packages that have already been warned regarding the ACCESS_CONTEXT_HUB permission.
+    private static final Set<String> PERMISSION_WARNED_PACKAGES = new HashSet<String>();
+
     /**
      * Creates a ConcurrentHashMap of the Context Hub ID to the ContextHubInfo object given an
      * ArrayList of HIDL ContextHub objects.
@@ -95,6 +102,7 @@
 
     /**
      * Creates a primitive integer array given a Collection<Integer>.
+     *
      * @param collection the collection to iterate
      * @return the primitive integer array
      */
@@ -200,10 +208,25 @@
      */
     /* package */
     static void checkPermissions(Context context) {
-        if (context.checkCallingPermission(HARDWARE_PERMISSION) != PERMISSION_GRANTED
-                && context.checkCallingPermission(CONTEXT_HUB_PERMISSION) != PERMISSION_GRANTED) {
+        boolean hasLocationHardwarePermission = (context.checkCallingPermission(HARDWARE_PERMISSION)
+                == PERMISSION_GRANTED);
+        boolean hasAccessContextHubPermission = (context.checkCallingPermission(
+                CONTEXT_HUB_PERMISSION) == PERMISSION_GRANTED);
+
+        if (!hasLocationHardwarePermission && !hasAccessContextHubPermission) {
             throw new SecurityException(
-                "LOCATION_HARDWARE or ACCESS_CONTEXT_HUB permission required to use Context Hub");
+                    "LOCATION_HARDWARE or ACCESS_CONTEXT_HUB permission required to use Context "
+                            + "Hub");
+        }
+
+        if (!hasAccessContextHubPermission && !Build.IS_USER) {
+            String pkgName = context.getPackageManager().getNameForUid(Binder.getCallingUid());
+            if (!PERMISSION_WARNED_PACKAGES.contains(pkgName)) {
+                Log.w(TAG, pkgName
+                        + ": please use the ACCESS_CONTEXT_HUB permission rather than "
+                        + "LOCATION_HARDWARE (will be removed for Context Hub APIs in T)");
+                PERMISSION_WARNED_PACKAGES.add(pkgName);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/location/LocationProviderManager.java b/services/core/java/com/android/server/location/LocationProviderManager.java
index f25c651..f8d1195 100644
--- a/services/core/java/com/android/server/location/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/LocationProviderManager.java
@@ -38,6 +38,7 @@
 import static java.lang.Math.max;
 import static java.lang.Math.min;
 
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.app.AlarmManager.OnAlarmListener;
 import android.app.PendingIntent;
@@ -107,6 +108,8 @@
 import com.android.server.location.util.UserInfoHelper.UserListener;
 
 import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -142,6 +145,14 @@
     // will just be scheduled immediately
     private static final long MIN_REQUEST_DELAY_MS = 30 * 1000;
 
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({STATE_STARTED, STATE_STOPPING, STATE_STOPPED})
+    private @interface State {}
+
+    private static final int STATE_STARTED = 0;
+    private static final int STATE_STOPPING = 1;
+    private static final int STATE_STOPPED = 2;
+
     protected interface LocationTransport {
 
         void deliverOnLocationChanged(Location location, @Nullable Runnable onCompleteCallback)
@@ -1082,7 +1093,7 @@
     protected final Context mContext;
 
     @GuardedBy("mLock")
-    private boolean mStarted;
+    private @State int mState;
 
     // maps of user id to value
     @GuardedBy("mLock")
@@ -1148,7 +1159,7 @@
         mContext = context;
         mName = Objects.requireNonNull(name);
         mPassiveManager = passiveManager;
-        mStarted = false;
+        mState = STATE_STOPPED;
         mEnabled = new SparseBooleanArray(2);
         mLastLocations = new SparseArray<>(2);
 
@@ -1180,7 +1191,8 @@
 
     public void startManager() {
         synchronized (mLock) {
-            mStarted = true;
+            Preconditions.checkState(mState == STATE_STOPPED);
+            mState = STATE_STARTED;
 
             mUserHelper.addListener(mUserChangedListener);
             mSettingsHelper.addOnLocationEnabledChangedListener(mLocationEnabledChangedListener);
@@ -1197,6 +1209,9 @@
 
     public void stopManager() {
         synchronized (mLock) {
+            Preconditions.checkState(mState == STATE_STARTED);
+            mState = STATE_STOPPING;
+
             final long identity = Binder.clearCallingIdentity();
             try {
                 onEnabledChanged(UserHandle.USER_ALL);
@@ -1205,11 +1220,19 @@
                 Binder.restoreCallingIdentity(identity);
             }
 
+            setRealProvider(null);
+            setMockProvider(null);
+
             mUserHelper.removeListener(mUserChangedListener);
             mSettingsHelper.removeOnLocationEnabledChangedListener(mLocationEnabledChangedListener);
 
+            // if external entities are registering listeners it's their responsibility to
+            // unregister them before stopManager() is called
             Preconditions.checkState(mEnabledListeners.isEmpty());
-            mStarted = false;
+
+            mEnabled.clear();
+            mLastLocations.clear();
+            mState = STATE_STOPPED;
         }
     }
 
@@ -1252,21 +1275,21 @@
 
     public void addEnabledListener(ProviderEnabledListener listener) {
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
             mEnabledListeners.add(listener);
         }
     }
 
     public void removeEnabledListener(ProviderEnabledListener listener) {
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
             mEnabledListeners.remove(listener);
         }
     }
 
-    public void setRealProvider(AbstractLocationProvider provider) {
+    public void setRealProvider(@Nullable AbstractLocationProvider provider) {
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
 
             final long identity = Binder.clearCallingIdentity();
             try {
@@ -1279,7 +1302,7 @@
 
     public void setMockProvider(@Nullable MockProvider provider) {
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
 
             mLocationEventLog.logProviderMocked(mName, provider != null);
 
@@ -1408,7 +1431,7 @@
 
         Location location;
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
             LastLocation lastLocation = mLastLocations.get(userId);
             if (lastLocation == null) {
                 location = null;
@@ -1430,7 +1453,7 @@
 
     public void injectLastLocation(Location location, int userId) {
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
             if (getLastLocationUnsafe(userId, PERMISSION_FINE, false, Long.MAX_VALUE) == null) {
                 setLastLocation(location, userId);
             }
@@ -1478,7 +1501,7 @@
                         permissionLevel);
 
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
             final long ident = Binder.clearCallingIdentity();
             try {
                 putRegistration(callback.asBinder(), registration);
@@ -1520,7 +1543,7 @@
                 permissionLevel);
 
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
             final long ident = Binder.clearCallingIdentity();
             try {
                 putRegistration(listener.asBinder(), registration);
@@ -1539,7 +1562,7 @@
                 permissionLevel);
 
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
             final long identity = Binder.clearCallingIdentity();
             try {
                 putRegistration(pendingIntent, registration);
@@ -1551,7 +1574,7 @@
 
     public void unregisterLocationRequest(ILocationListener listener) {
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
             final long identity = Binder.clearCallingIdentity();
             try {
                 removeRegistration(listener.asBinder());
@@ -1563,7 +1586,7 @@
 
     public void unregisterLocationRequest(PendingIntent pendingIntent) {
         synchronized (mLock) {
-            Preconditions.checkState(mStarted);
+            Preconditions.checkState(mState != STATE_STOPPED);
             final long identity = Binder.clearCallingIdentity();
             try {
                 removeRegistration(pendingIntent);
@@ -1890,6 +1913,10 @@
 
     private void onUserChanged(int userId, int change) {
         synchronized (mLock) {
+            if (mState == STATE_STOPPED) {
+                return;
+            }
+
             switch (change) {
                 case UserListener.CURRENT_USER_CHANGED:
                     updateRegistrations(
@@ -1907,6 +1934,10 @@
 
     private void onLocationEnabledChanged(int userId) {
         synchronized (mLock) {
+            if (mState == STATE_STOPPED) {
+                return;
+            }
+
             onEnabledChanged(userId);
         }
     }
@@ -2105,7 +2136,7 @@
 
         Preconditions.checkArgument(userId >= 0);
 
-        boolean enabled = mStarted
+        boolean enabled = mState == STATE_STARTED
                 && mProvider.getState().allowed
                 && mSettingsHelper.isLocationEnabled(userId);
 
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index e25e605..0c1e91d 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -583,8 +583,10 @@
         mDownloadPsdsWakeLock.setReferenceCounted(true);
 
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
-        mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
+        mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP),
+                PendingIntent.FLAG_IMMUTABLE);
+        mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT),
+                PendingIntent.FLAG_IMMUTABLE);
 
         // App ops service to keep track of who is accessing the GPS
         mAppOps = mContext.getSystemService(AppOpsManager.class);
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index b679c0f..dd33865 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -1563,7 +1563,7 @@
                             continue;
                         }
                         try {
-                            listener.onPackageProgressChanged(mUser, mPackageName, progress);
+                            listener.onPackageLoadingProgressChanged(mUser, mPackageName, progress);
                         } catch (RemoteException re) {
                             Slog.d(TAG, "Callback failed ", re);
                         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4fdb9fb..925d3cc 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -545,6 +545,7 @@
     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,
@@ -804,11 +805,12 @@
     final SparseIntArray mIsolatedOwners = new SparseIntArray();
 
     /**
-     * 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.
+     * 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)
      */
-    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
+    private final ArrayMap<String, List<Pair<File, Long>>> mExpectingBetter = new ArrayMap<>();
 
     /**
      * Tracks existing packages prior to receiving an OTA. Keys are package name.
@@ -2737,7 +2739,7 @@
                 context, lock, installer, installLock, new PackageAbiHelperImpl(),
                 backgroundHandler,
                 (i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock),
-                (i, pm) -> PermissionManagerService.create(context, lock),
+                (i, pm) -> PermissionManagerService.create(context),
                 (i, pm) -> new UserManagerService(context, pm,
                         new UserDataPreparer(installer, installLock, context, onlyCore),
                         lock),
@@ -3349,7 +3351,7 @@
                                     + ", versionCode=" + ps.versionCode
                                     + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
                             removePackageLI(scannedPkg, true);
-                            mExpectingBetter.put(ps.name, ps.getPath());
+                            expectBetter(ps.name, ps.getPath(), ps.versionCode);
                         }
 
                         continue;
@@ -3379,7 +3381,8 @@
                             // 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.
-                            mExpectingBetter.put(disabledPs.name, disabledPs.getPath());
+                            expectBetter(disabledPs.name, disabledPs.getPath(),
+                                    disabledPs.versionCode);
                         }
                     }
                 }
@@ -3480,38 +3483,48 @@
                 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");
 
-                        @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);
+                        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;
 
-                        try {
-                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
-                        } catch (PackageManagerException e) {
-                            Slog.e(TAG, "Failed to parse original system package: "
-                                    + e.getMessage());
+                            @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
+                                break;
+                            } catch (PackageManagerException e) {
+                                Slog.e(TAG, "Failed to parse original system package: "
+                                        + e.getMessage());
+                            }
                         }
                     }
                 }
@@ -3901,6 +3914,33 @@
     }
 
     /**
+     * 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,
@@ -11271,7 +11311,23 @@
                 isUpdatedSystemApp = disabledPkgSetting != null;
             }
             applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp);
-            assertPackageIsValid(parsedPackage, parseFlags, scanFlags);
+            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;
+            }
 
             SharedUserSetting sharedUserSetting = null;
             if (parsedPackage.getSharedUserId() != null) {
@@ -12123,9 +12179,9 @@
      *
      * @throws PackageManagerException If the package fails any of the validation checks
      */
-    private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags,
-            final @ScanFlags int scanFlags)
-                    throws PackageManagerException {
+    private void assertPackageIsValid(AndroidPackage pkg,
+            @Nullable PackageSetting existingPkgSetting, final @ParseFlags int parseFlags,
+            final @ScanFlags int scanFlags) throws PackageManagerException {
         if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
             assertCodePolicy(pkg);
         }
@@ -12140,11 +12196,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(pkg.getPackageName())) {
+                && mApexManager.isApexPackage(pkgName)) {
             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
-                    pkg.getPackageName()
-                            + " is an APEX package and can't be installed as an APK.");
+                    pkgName + " is an APEX package and can't be installed as an APK.");
         }
 
         // Make sure we're not adding any bogus keyset info
@@ -12153,7 +12209,7 @@
 
         synchronized (mLock) {
             // The special "android" package can only be defined once
-            if (pkg.getPackageName().equals("android")) {
+            if (pkgName.equals("android")) {
                 if (mAndroidApplication != null) {
                     Slog.w(TAG, "*************************************************");
                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
@@ -12164,12 +12220,46 @@
                 }
             }
 
-            // 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.");
+            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.");
+                }
             }
 
             if (pkg.isStaticSharedLibrary()) {
@@ -12289,8 +12379,8 @@
                         }
                     }
                 }
-                if (pkg.getLongVersionCode() < minVersionCode
-                        || pkg.getLongVersionCode() > maxVersionCode) {
+                if (newLongVersionCode < minVersionCode
+                        || newLongVersionCode > maxVersionCode) {
                     throw new PackageManagerException("Static shared"
                             + " lib version codes must be ordered as lib versions");
                 }
@@ -12305,11 +12395,10 @@
             // 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(pkg.getPackageName())) {
-                    Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package "
-                            + pkg.getPackageName());
+                if (mExpectingBetter.containsKey(pkgName)) {
+                    Slog.w(TAG, "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkgName);
                 } else {
-                    PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());
+                    PackageSetting known = mSettings.getPackageLPr(pkgName);
                     if (known != null) {
                         if (DEBUG_PACKAGE_SCANNING) {
                             Log.d(TAG, "Examining " + pkg.getPath()
@@ -12317,14 +12406,14 @@
                         }
                         if (!pkg.getPath().equals(known.getPathString())) {
                             throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
-                                    "Application package " + pkg.getPackageName()
+                                    "Application package " + pkgName
                                     + " found at " + pkg.getPath()
                                     + " but expected at " + known.getPathString()
                                     + "; ignoring.");
                         }
                     } else {
                         throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
-                                "Application package " + pkg.getPackageName()
+                                "Application package " + pkgName
                                 + " not found; ignoring.");
                     }
                 }
@@ -12347,7 +12436,7 @@
                             INSTALL_FAILED_PROCESS_NOT_DEFINED,
                             "Can't install because application tag's process attribute "
                                     + pkg.getProcessName()
-                                    + " (in package " + pkg.getPackageName()
+                                    + " (in package " + pkgName
                                     + ") is not included in the <processes> list");
                 }
                 assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity");
@@ -12371,7 +12460,7 @@
                             pkg.getSigningDetails().signatures)) {
                         throw new PackageManagerException("Apps that share a user with a " +
                                 "privileged app must themselves be marked as privileged. " +
-                                pkg.getPackageName() + " shares privileged user " +
+                                pkgName + " shares privileged user " +
                                 pkg.getSharedUserId() + ".");
                     }
                 }
@@ -12388,21 +12477,21 @@
                         // upgraded.
                         Objects.requireNonNull(mOverlayConfig,
                                 "Parsing non-system dir before overlay configs are initialized");
-                        if (!mOverlayConfig.isMutable(pkg.getPackageName())) {
+                        if (!mOverlayConfig.isMutable(pkgName)) {
                             throw new PackageManagerException("Overlay "
-                                    + pkg.getPackageName()
+                                    + pkgName
                                     + " is static and cannot be upgraded.");
                         }
                     } else {
                         if ((scanFlags & SCAN_AS_VENDOR) != 0) {
                             if (pkg.getTargetSdkVersion() < getVendorPartitionVersion()) {
-                                Slog.w(TAG, "System overlay " + pkg.getPackageName()
+                                Slog.w(TAG, "System overlay " + pkgName
                                         + " 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 " + pkg.getPackageName()
+                            Slog.w(TAG, "System overlay " + pkgName
                                     + " 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");
@@ -12418,7 +12507,7 @@
                         if (!comparePackageSignatures(platformPkgSetting,
                                 pkg.getSigningDetails().signatures)) {
                             throw new PackageManagerException("Overlay "
-                                    + pkg.getPackageName()
+                                    + pkgName
                                     + " must target Q or later, "
                                     + "or be signed with the platform certificate");
                         }
@@ -12440,7 +12529,7 @@
                                 // check reference signature
                                 if (mOverlayConfigSignaturePackage == null) {
                                     throw new PackageManagerException("Overlay "
-                                            + pkg.getPackageName() + " and target "
+                                            + pkgName + " and target "
                                             + pkg.getOverlayTarget() + " signed with"
                                             + " different certificates, and the overlay lacks"
                                             + " <overlay android:targetName>");
@@ -12450,7 +12539,7 @@
                                 if (!comparePackageSignatures(refPkgSetting,
                                         pkg.getSigningDetails().signatures)) {
                                     throw new PackageManagerException("Overlay "
-                                            + pkg.getPackageName() + " signed with a different "
+                                            + pkgName + " signed with a different "
                                             + "certificate than both the reference package and "
                                             + "target " + pkg.getOverlayTarget() + ", and the "
                                             + "overlay lacks <overlay android:targetName>");
@@ -12470,7 +12559,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 " + pkg.getPackageName());
+                                    + " or newer for package " + pkgName);
                 }
             }
         }
@@ -18713,6 +18802,19 @@
         final String packageName = versionedPackage.getPackageName();
         final long versionCode = versionedPackage.getLongVersionCode();
         final String internalPackageName;
+
+        try {
+            if (mInjector.getLocalService(ActivityTaskManagerInternal.class)
+                    .isBaseOfLockedTask(packageName)) {
+                observer.onPackageDeleted(
+                        packageName, PackageManager.DELETE_FAILED_APP_PINNED, null);
+                EventLog.writeEvent(0x534e4554, "127605586", -1, "");
+                return;
+            }
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
         synchronized (mLock) {
             // Normalize package name to handle renamed packages and static libs
             internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
@@ -19593,7 +19695,7 @@
                         ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, userId);
                     }
 
-                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
+                    writeRuntimePermissionsForUserLPrTEMP(userId, false);
                 }
                 // Regardless of writeSettings we need to ensure that this restriction
                 // state propagation is persisted
@@ -25739,7 +25841,7 @@
         public void writePermissionSettings(int[] userIds, boolean async) {
             synchronized (mLock) {
                 for (int userId : userIds) {
-                    mSettings.writeRuntimePermissionsForUserLPr(userId, !async);
+                    writeRuntimePermissionsForUserLPrTEMP(userId, !async);
                 }
             }
         }
@@ -26388,6 +26490,17 @@
         mSettings.writeLPr();
     }
 
+    /**
+     * Temporary method that wraps mSettings.writeRuntimePermissionsForUserLPr() and calls
+     * mPermissionManager.writeLegacyPermissionStateTEMP() beforehand.
+     *
+     * TODO(zhanghai): This should be removed once we finish migration of permission storage.
+     */
+    private void writeRuntimePermissionsForUserLPrTEMP(@UserIdInt int userId, boolean async) {
+        mPermissionManager.writeLegacyPermissionStateTEMP();
+        mSettings.writeRuntimePermissionsForUserLPr(userId, async);
+    }
+
     @Override
     public IBinder getHoldLockToken() {
         if (!Build.IS_DEBUGGABLE) {
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/parsing/PackageCacher.java b/services/core/java/com/android/server/pm/parsing/PackageCacher.java
index 74ec161..3463daf 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageCacher.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageCacher.java
@@ -57,7 +57,16 @@
      * Returns the cache key for a specified {@code packageFile} and {@code flags}.
      */
     private String getCacheKey(File packageFile, int flags) {
-        StringBuilder sb = new StringBuilder(packageFile.getName());
+        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());
         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 851ddd1..46d31d9 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/135203078): Document new package parsing
+     * TODO(b/155493909): 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/Permission.java b/services/core/java/com/android/server/pm/permission/Permission.java
index c121e6b..4e8ddac 100644
--- a/services/core/java/com/android/server/pm/permission/Permission.java
+++ b/services/core/java/com/android/server/pm/permission/Permission.java
@@ -378,28 +378,33 @@
         }
     }
 
+    public static boolean isOverridingSystemPermission(@Nullable Permission permission,
+            @NonNull PermissionInfo permissionInfo,
+            @NonNull PackageManagerInternal packageManagerInternal) {
+        if (permission == null || Objects.equals(permission.mPermissionInfo.packageName,
+                permissionInfo.packageName)) {
+            return false;
+        }
+        if (!permission.mReconciled) {
+            return false;
+        }
+        final AndroidPackage currentPackage = packageManagerInternal.getPackage(
+                permission.mPermissionInfo.packageName);
+        if (currentPackage == null) {
+            return false;
+        }
+        return currentPackage.isSystem();
+    }
+
     @NonNull
-    static Permission createOrUpdate(PackageManagerInternal packageManagerInternal,
-            @Nullable Permission permission, @NonNull PermissionInfo permissionInfo,
-            @NonNull AndroidPackage pkg, @NonNull Collection<Permission> permissionTrees,
+    public static Permission createOrUpdate(@Nullable Permission permission,
+            @NonNull PermissionInfo permissionInfo, @NonNull AndroidPackage pkg,
+            @NonNull Collection<Permission> permissionTrees, boolean isOverridingSystemPermission,
             boolean chatty) {
         // Allow system apps to redefine non-system permissions
         boolean ownerChanged = false;
         if (permission != null && !Objects.equals(permission.mPermissionInfo.packageName,
                 permissionInfo.packageName)) {
-            final boolean currentOwnerIsSystem;
-            if (!permission.mReconciled) {
-                currentOwnerIsSystem = false;
-            } else {
-                AndroidPackage currentPackage = packageManagerInternal.getPackage(
-                        permission.mPermissionInfo.packageName);
-                if (currentPackage == null) {
-                    currentOwnerIsSystem = false;
-                } else {
-                    currentOwnerIsSystem = currentPackage.isSystem();
-                }
-            }
-
             if (pkg.isSystem()) {
                 if (permission.mType == Permission.TYPE_CONFIG && !permission.mReconciled) {
                     // It's a built-in permission and no owner, take ownership now
@@ -407,11 +412,10 @@
                     permission.mPermissionInfo = permissionInfo;
                     permission.mReconciled = true;
                     permission.mUid = pkg.getUid();
-                } else if (!currentOwnerIsSystem) {
-                    String msg = "New decl " + pkg + " of permission  "
+                } else if (!isOverridingSystemPermission) {
+                    Slog.w(TAG, "New decl " + pkg + " of permission  "
                             + permissionInfo.name + " is system; overriding "
-                            + permission.mPermissionInfo.packageName;
-                    PackageManagerService.reportSettingsProblem(Log.WARN, msg);
+                            + permission.mPermissionInfo.packageName);
                     ownerChanged = true;
                     permission = null;
                 }
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 6d987ae..84f9823 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -208,7 +208,7 @@
     }
 
     /** Lock to protect internal data access */
-    private final Object mLock;
+    private final Object mLock = new Object();
 
     /** Internal connection to the package manager */
     private final PackageManagerInternal mPackageManagerInt;
@@ -224,6 +224,8 @@
     private PermissionControllerManager mPermissionControllerManager;
 
     /** Map of OneTimePermissionUserManagers keyed by userId */
+    @GuardedBy("mLock")
+    @NonNull
     private final SparseArray<OneTimePermissionUserManager> mOneTimePermissionUserManagers =
             new SparseArray<>();
 
@@ -252,12 +254,14 @@
 
     /** Internal storage for permissions and related settings */
     @GuardedBy("mLock")
-    private final PermissionRegistry mRegistry;
+    @NonNull
+    private final PermissionRegistry mRegistry = new PermissionRegistry();
 
     /** Injector that can be used to facilitate testing. */
     private final Injector mInjector;
 
     @GuardedBy("mLock")
+    @Nullable
     private ArraySet<String> mPrivappPermissionsViolations;
 
     @GuardedBy("mLock")
@@ -267,13 +271,6 @@
     private PermissionPolicyInternal mPermissionPolicyInternal;
 
     /**
-     * For each foreground/background permission the mapping:
-     * Background permission -> foreground permissions
-     */
-    @GuardedBy("mLock")
-    private ArrayMap<String, List<String>> mBackgroundPermissions;
-
-    /**
      * A permission backup might contain apps that are not installed. In this case we delay the
      * restoration until the app is installed.
      *
@@ -291,7 +288,7 @@
     @GuardedBy("mLock")
     private CheckPermissionDelegate mCheckPermissionDelegate;
 
-    @GuardedBy("mLock")
+    @NonNull
     private final OnPermissionChangeListeners mOnPermissionChangeListeners;
 
     @GuardedBy("mLock")
@@ -309,7 +306,7 @@
     // purposes. It may make sense to keep as an abstraction, but, the methods
     // necessary to be overridden may be different than what was initially needed
     // for the split.
-    private PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
+    private final PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
         @Override
         public void onGidsChanged(int appId, int userId) {
             mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
@@ -368,14 +365,12 @@
         }
     };
 
-    PermissionManagerService(Context context,
-            @NonNull Object externalLock) {
-        this(context, externalLock, new Injector(context));
+    PermissionManagerService(@NonNull Context context) {
+        this(context, new Injector(context));
     }
 
     @VisibleForTesting
-    PermissionManagerService(Context context, @NonNull Object externalLock,
-            @NonNull Injector injector) {
+    PermissionManagerService(@NonNull Context context, @NonNull Injector injector) {
         mInjector = injector;
         // The package info cache is the cache for package and permission information.
         // Disable the package info and package permission caches locally but leave the
@@ -384,10 +379,8 @@
         mInjector.disablePackageNamePermissionCache();
 
         mContext = context;
-        mLock = externalLock;
         mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
         mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
-        mRegistry = new PermissionRegistry(mLock);
         mAppOpsManager = context.getSystemService(AppOpsManager.class);
 
         mHandlerThread = new ServiceThread(TAG,
@@ -409,10 +402,10 @@
         synchronized (mLock) {
             for (int i=0; i<permConfig.size(); i++) {
                 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
-                Permission bp = mRegistry.getPermissionLocked(perm.name);
+                Permission bp = mRegistry.getPermission(perm.name);
                 if (bp == null) {
                     bp = new Permission(perm.name, "android", Permission.TYPE_CONFIG);
-                    mRegistry.addPermissionLocked(bp);
+                    mRegistry.addPermission(bp);
                 }
                 if (perm.gids != null) {
                     bp.setGids(perm.gids, perm.perUser);
@@ -444,8 +437,8 @@
      * NOTE: The external lock is temporary and should be removed. This needs to be a
      * lock created by the permission manager itself.
      */
-    public static PermissionManagerServiceInternal create(Context context,
-            @NonNull Object externalLock) {
+    @NonNull
+    public static PermissionManagerServiceInternal create(@NonNull Context context) {
         final PermissionManagerServiceInternal permMgrInt =
                 LocalServices.getService(PermissionManagerServiceInternal.class);
         if (permMgrInt != null) {
@@ -454,8 +447,7 @@
         PermissionManagerService permissionService =
                 (PermissionManagerService) ServiceManager.getService("permissionmgr");
         if (permissionService == null) {
-            permissionService =
-                    new PermissionManagerService(context, externalLock);
+            permissionService = new PermissionManagerService(context);
             ServiceManager.addService("permissionmgr", permissionService);
         }
         return LocalServices.getService(PermissionManagerServiceInternal.class);
@@ -484,13 +476,6 @@
         }
     }
 
-    @Nullable
-    Permission getPermission(String permName) {
-        synchronized (mLock) {
-            return mRegistry.getPermissionLocked(permName);
-        }
-    }
-
     @Override
     public String[] getAppOpPermissionPackages(String permName) {
         return getAppOpPermissionPackagesInternal(permName, getCallingUid());
@@ -501,7 +486,7 @@
             return null;
         }
         synchronized (mLock) {
-            final ArraySet<String> pkgs = mRegistry.getAppOpPermissionPackagesLocked(permName);
+            final ArraySet<String> pkgs = mRegistry.getAppOpPermissionPackages(permName);
             if (pkgs == null) {
                 return null;
             }
@@ -519,7 +504,7 @@
         }
         synchronized (mLock) {
             final List<PermissionGroupInfo> out = new ArrayList<>();
-            for (ParsedPermissionGroup pg : mRegistry.getPermissionGroupsLocked()) {
+            for (ParsedPermissionGroup pg : mRegistry.getPermissionGroups()) {
                 out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags));
             }
             return new ParceledListSlice<>(out);
@@ -537,7 +522,7 @@
         }
         synchronized (mLock) {
             return PackageInfoUtils.generatePermissionGroupInfo(
-                    mRegistry.getPermissionGroupLocked(groupName), flags);
+                    mRegistry.getPermissionGroup(groupName), flags);
         }
     }
 
@@ -554,7 +539,7 @@
         final int targetSdkVersion = getPermissionInfoCallingTargetSdkVersion(opPackage,
                 callingUid);
         synchronized (mLock) {
-            final Permission bp = mRegistry.getPermissionLocked(permName);
+            final Permission bp = mRegistry.getPermission(permName);
             if (bp == null) {
                 return null;
             }
@@ -584,11 +569,11 @@
             return null;
         }
         synchronized (mLock) {
-            if (groupName != null && mRegistry.getPermissionGroupLocked(groupName) == null) {
+            if (groupName != null && mRegistry.getPermissionGroup(groupName) == null) {
                 return null;
             }
             final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
-            for (Permission bp : mRegistry.getPermissionsLocked()) {
+            for (Permission bp : mRegistry.getPermissions()) {
                 if (Objects.equals(bp.getGroup(), groupName)) {
                     out.add(bp.generatePermissionInfo(flags));
                 }
@@ -606,24 +591,23 @@
         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
             throw new SecurityException("Label must be specified in permission");
         }
-        final Permission tree = mRegistry.enforcePermissionTree(info.name, callingUid);
         final boolean added;
         final boolean changed;
         synchronized (mLock) {
-            Permission bp = mRegistry.getPermissionLocked(info.name);
+            final Permission tree = mRegistry.enforcePermissionTree(info.name, callingUid);
+            Permission bp = mRegistry.getPermission(info.name);
             added = bp == null;
             int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
             if (added) {
                 enforcePermissionCapLocked(info, tree);
-                bp = new Permission(info.name, tree.getPackageName(),
-                        Permission.TYPE_DYNAMIC);
+                bp = new Permission(info.name, tree.getPackageName(), Permission.TYPE_DYNAMIC);
             } else if (!bp.isDynamic()) {
                 throw new SecurityException("Not allowed to modify non-dynamic permission "
                         + info.name);
             }
             changed = bp.addToTree(fixedLevel, info, tree);
             if (added) {
-                mRegistry.addPermissionLocked(bp);
+                mRegistry.addPermission(bp);
             }
         }
         if (changed) {
@@ -638,9 +622,9 @@
         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
             throw new SecurityException("Instant applications don't have access to this method");
         }
-        final Permission tree = mRegistry.enforcePermissionTree(permName, callingUid);
         synchronized (mLock) {
-            final Permission bp = mRegistry.getPermissionLocked(permName);
+            mRegistry.enforcePermissionTree(permName, callingUid);
+            final Permission bp = mRegistry.getPermission(permName);
             if (bp == null) {
                 return;
             }
@@ -649,9 +633,9 @@
                 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
                         + permName);
             }
-            mRegistry.removePermissionLocked(permName);
-            mPackageManagerInt.writeSettings(false);
+            mRegistry.removePermission(permName);
         }
+        mPackageManagerInt.writeSettings(false);
     }
 
     @Override
@@ -682,7 +666,7 @@
         }
 
         synchronized (mLock) {
-            if (mRegistry.getPermissionLocked(permName) == null) {
+            if (mRegistry.getPermission(permName) == null) {
                 return 0;
             }
 
@@ -807,14 +791,16 @@
             }
         }
 
-        final Permission bp;
+        final boolean isRuntimePermission;
         final boolean permissionUpdated;
         synchronized (mLock) {
-            bp = mRegistry.getPermissionLocked(permName);
+            final Permission bp = mRegistry.getPermission(permName);
             if (bp == null) {
                 throw new IllegalArgumentException("Unknown permission: " + permName);
             }
 
+            isRuntimePermission = bp.isRuntime();
+
             if (bp.isInstallerExemptIgnored()) {
                 flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
             }
@@ -833,14 +819,14 @@
             permissionUpdated = uidState.updatePermissionFlags(bp, flagMask, flagValues);
         }
 
-        if (permissionUpdated && bp.isRuntime()) {
+        if (permissionUpdated && isRuntimePermission) {
             notifyRuntimePermissionStateChanged(packageName, userId);
         }
         if (permissionUpdated && callback != null) {
             // Install and runtime permissions are stored in different places,
             // so figure out what permission changed and persist the change.
-            if (!bp.isRuntime()) {
-                int userUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
+            if (!isRuntimePermission) {
+                int userUid = UserHandle.getUid(userId, pkg.getUid());
                 callback.onInstallPermissionUpdatedNotifyListener(userUid);
             } else {
                 callback.onPermissionUpdatedNotifyListener(new int[]{userId}, false, pkg.getUid());
@@ -962,6 +948,7 @@
         return PackageManager.PERMISSION_DENIED;
     }
 
+    @GuardedBy("mLock")
     private boolean checkSinglePermissionInternalLocked(@NonNull UidPermissionState uidState,
             @NonNull String permissionName, boolean isInstantApp) {
         if (!uidState.isPermissionGranted(permissionName)) {
@@ -969,7 +956,8 @@
         }
 
         if (isInstantApp) {
-            return mRegistry.isPermissionInstant(permissionName);
+            final Permission permission = mRegistry.getPermission(permissionName);
+            return permission != null && permission.isInstant();
         }
 
         return true;
@@ -1031,6 +1019,7 @@
         return PackageManager.PERMISSION_DENIED;
     }
 
+    @GuardedBy("mLock")
     private boolean checkSingleUidPermissionInternalLocked(int uid,
             @NonNull String permissionName) {
         ArraySet<String> permissions = mSystemPermissions.get(uid);
@@ -1096,9 +1085,7 @@
                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
                 "addOnPermissionsChangeListener");
 
-        synchronized (mLock) {
-            mOnPermissionChangeListeners.addListenerLocked(listener);
-        }
+        mOnPermissionChangeListeners.addListener(listener);
     }
 
     @Override
@@ -1106,9 +1093,7 @@
         if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
             throw new SecurityException("Instant applications don't have access to this method");
         }
-        synchronized (mLock) {
-            mOnPermissionChangeListeners.removeListenerLocked(listener);
-        }
+        mOnPermissionChangeListeners.removeListener(listener);
     }
 
     @Override
@@ -1230,21 +1215,23 @@
 
     private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
             @NonNull String permName) {
+        final boolean isImmutablyRestrictedPermission;
         synchronized (mLock) {
-            final Permission bp = mRegistry.getPermissionLocked(permName);
+            final Permission bp = mRegistry.getPermission(permName);
             if (bp == null) {
                 Slog.w(TAG, "No such permissions: " + permName);
                 return false;
             }
-            if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
-                    && mContext.checkCallingOrSelfPermission(
-                    Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("Cannot modify whitelisting of an immutably "
-                        + "restricted permission: " + permName);
-            }
-            return true;
+            isImmutablyRestrictedPermission = bp.isHardOrSoftRestricted()
+                    && bp.isImmutablyRestricted();
         }
+        if (isImmutablyRestrictedPermission && mContext.checkCallingOrSelfPermission(
+                Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Cannot modify whitelisting of an immutably "
+                    + "restricted permission: " + permName);
+        }
+        return true;
     }
 
     @Override
@@ -1472,36 +1459,33 @@
             throw new IllegalArgumentException("Unknown package: " + packageName);
         }
 
-        final Permission bp;
+        final boolean isSoftRestrictedPermission;
         synchronized (mLock) {
-            bp = mRegistry.getPermissionLocked(permName);
+            final Permission permission = mRegistry.getPermission(permName);
+            isSoftRestrictedPermission = permission != null && permission.isSoftRestricted();
         }
-        if (bp == null) {
-            throw new IllegalArgumentException("Unknown permission: " + permName);
-        }
+        final boolean mayGrantSoftRestrictedPermission = isSoftRestrictedPermission
+                && SoftRestrictedPermissionPolicy.forPermission(mContext,
+                        pkg.toAppInfoWithoutState(), pkg, UserHandle.of(userId), permName)
+                        .mayGrantPermission();
 
-        if (!(bp.isRuntime() || bp.isDevelopment())) {
-            throw new SecurityException("Permission " + permName + " requested by "
-                    + pkg.getPackageName() + " is not a changeable permission type");
-        }
-
-        // If a permission review is required for legacy apps we represent
-        // their permissions as always granted runtime ones since we need
-        // to keep the review required permission flag per user while an
-        // install permission's state is shared across all users.
-        if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
-            return;
-        }
-
-        if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
-                pkg.toAppInfoWithoutState(), pkg, UserHandle.of(userId), permName)
-                .mayGrantPermission()) {
-            Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
-                    + packageName);
-            return;
-        }
-
+        final boolean isRuntimePermission;
+        final boolean isDevelopmentPermission;
+        final boolean permissionHasGids;
         synchronized (mLock) {
+            final Permission bp = mRegistry.getPermission(permName);
+            if (bp == null) {
+                throw new IllegalArgumentException("Unknown permission: " + permName);
+            }
+
+            isRuntimePermission = bp.isRuntime();
+            isDevelopmentPermission = bp.isDevelopment();
+            permissionHasGids = bp.hasGids();
+            if (!(isRuntimePermission || isDevelopmentPermission)) {
+                throw new SecurityException("Permission " + permName + " requested by "
+                        + pkg.getPackageName() + " is not a changeable permission type");
+            }
+
             final UidPermissionState uidState = getUidStateLocked(pkg, userId);
             if (uidState == null) {
                 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
@@ -1515,6 +1499,14 @@
                         + " has not requested permission " + permName);
             }
 
+            // If a permission review is required for legacy apps we represent
+            // their permissions as always granted runtime ones since we need
+            // to keep the review required permission flag per user while an
+            // install permission's state is shared across all users.
+            if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M && bp.isRuntime()) {
+                return;
+            }
+
             final int flags = uidState.getPermissionFlags(permName);
             if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
                 Log.e(TAG, "Cannot grant system fixed permission "
@@ -1534,6 +1526,12 @@
                 return;
             }
 
+            if (bp.isSoftRestricted() && !mayGrantSoftRestrictedPermission) {
+                Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
+                        + packageName);
+                return;
+            }
+
             if (bp.isDevelopment()) {
                 // Development permissions must be handled specially, since they are not
                 // normal runtime permissions.  For now they apply to all users.
@@ -1559,23 +1557,23 @@
             }
         }
 
-        if (bp.isRuntime()) {
+        if (isRuntimePermission) {
             logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
         }
 
-        final int uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
+        final int uid = UserHandle.getUid(userId, pkg.getUid());
         if (callback != null) {
-            if (bp.isDevelopment()) {
+            if (isDevelopmentPermission) {
                 callback.onInstallPermissionGranted();
             } else {
                 callback.onPermissionGranted(uid, userId);
             }
-            if (bp.hasGids()) {
+            if (permissionHasGids) {
                 callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId);
             }
         }
 
-        if (bp.isRuntime()) {
+        if (isRuntimePermission) {
             notifyRuntimePermissionStateChanged(packageName, userId);
         }
     }
@@ -1626,17 +1624,22 @@
         if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
             throw new IllegalArgumentException("Unknown package: " + packageName);
         }
-        final Permission bp = mRegistry.getPermission(permName);
-        if (bp == null) {
-            throw new IllegalArgumentException("Unknown permission: " + permName);
-        }
 
-        if (!(bp.isRuntime() || bp.isDevelopment())) {
-            throw new SecurityException("Permission " + permName + " requested by "
-                    + pkg.getPackageName() + " is not a changeable permission type");
-        }
-
+        final boolean isRuntimePermission;
+        final boolean isDevelopmentPermission;
         synchronized (mLock) {
+            final Permission bp = mRegistry.getPermission(permName);
+            if (bp == null) {
+                throw new IllegalArgumentException("Unknown permission: " + permName);
+            }
+
+            isRuntimePermission = bp.isRuntime();
+            isDevelopmentPermission = bp.isDevelopment();
+            if (!(isRuntimePermission || isDevelopmentPermission)) {
+                throw new SecurityException("Permission " + permName + " requested by "
+                        + pkg.getPackageName() + " is not a changeable permission type");
+            }
+
             final UidPermissionState uidState = getUidStateLocked(pkg, userId);
             if (uidState == null) {
                 Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName() + " and user "
@@ -1679,20 +1682,20 @@
             }
         }
 
-        if (bp.isRuntime()) {
+        if (isRuntimePermission) {
             logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
         }
 
         if (callback != null) {
-            if (bp.isDevelopment()) {
+            if (isDevelopmentPermission) {
                 mDefaultPermissionCallback.onInstallPermissionRevoked();
             } else {
-                callback.onPermissionRevoked(UserHandle.getUid(userId,
-                        UserHandle.getAppId(pkg.getUid())), userId, reason);
+                callback.onPermissionRevoked(UserHandle.getUid(userId, pkg.getUid()), userId,
+                        reason);
             }
         }
 
-        if (bp.isRuntime()) {
+        if (isRuntimePermission) {
             notifyRuntimePermissionStateChanged(packageName, userId);
         }
     }
@@ -1807,16 +1810,18 @@
 
         for (int i = 0; i < permissionCount; i++) {
             final String permName = pkg.getRequestedPermissions().get(i);
-            final Permission bp;
-            synchronized (mLock) {
-                bp = mRegistry.getPermissionLocked(permName);
-            }
-            if (bp == null) {
-                continue;
-            }
 
-            if (bp.isRemoved()) {
-                continue;
+            final boolean isRuntimePermission;
+            synchronized (mLock) {
+                final Permission permission = mRegistry.getPermission(permName);
+                if (permission == null) {
+                    continue;
+                }
+
+                if (permission.isRemoved()) {
+                    continue;
+                }
+                isRuntimePermission = permission.isRuntime();
             }
 
             // If shared user we just reset the state to which only this app contributed.
@@ -1846,7 +1851,7 @@
             // permission as requiring a review as this is the initial state.
             final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
             final int targetSdk = mPackageManagerInt.getUidTargetSdkVersion(uid);
-            final int flags = (targetSdk < Build.VERSION_CODES.M && bp.isRuntime())
+            final int flags = (targetSdk < Build.VERSION_CODES.M && isRuntimePermission)
                     ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT
                     : 0;
 
@@ -1855,7 +1860,7 @@
                     false, delayingPermCallback);
 
             // Below is only runtime permission handling.
-            if (!bp.isRuntime()) {
+            if (!isRuntimePermission) {
                 continue;
             }
 
@@ -2092,13 +2097,15 @@
             return false;
         }
 
-        Permission permission = getPermission(permName);
-        if (permission == null) {
-            return false;
-        }
-        if (permission.isHardRestricted()
-                && (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
-            return false;
+        synchronized (mLock) {
+            final Permission permission = mRegistry.getPermission(permName);
+            if (permission == null) {
+                return false;
+            }
+            if (permission.isHardRestricted()
+                    && (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
+                return false;
+            }
         }
 
         final long token = Binder.clearCallingIdentity();
@@ -2177,8 +2184,8 @@
     private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
         synchronized (mLock) {
             mHasNoDelayedPermBackup.delete(user.getIdentifier());
-            mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup, user);
         }
+        mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup, user);
     }
 
     /**
@@ -2197,18 +2204,16 @@
             if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
                 return;
             }
-
-            mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName, user,
-                    mContext.getMainExecutor(), (hasMoreBackup) -> {
-                        if (hasMoreBackup) {
-                            return;
-                        }
-
-                        synchronized (mLock) {
-                            mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
-                        }
-                    });
         }
+        mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName, user,
+                mContext.getMainExecutor(), (hasMoreBackup) -> {
+                    if (hasMoreBackup) {
+                        return;
+                    }
+                    synchronized (mLock) {
+                        mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
+                    }
+                });
     }
 
     private void addOnRuntimePermissionStateChangedListener(@NonNull
@@ -2346,10 +2351,12 @@
         final int callingUid = Binder.getCallingUid();
 
         for (int permNum = 0; permNum < numPermissions; permNum++) {
-            String permName = permissionsToRevoke.get(permNum);
-            Permission bp = mRegistry.getPermission(permName);
-            if (bp == null || !bp.isRuntime()) {
-                continue;
+            final String permName = permissionsToRevoke.get(permNum);
+            synchronized (mLock) {
+                final Permission bp = mRegistry.getPermission(permName);
+                if (bp == null || !bp.isRuntime()) {
+                    continue;
+                }
             }
             for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
                 final int userId = userIds[userIdNum];
@@ -2387,7 +2394,6 @@
                     }
                 }
             }
-            bp.setDefinitionChanged(false);
         }
     }
 
@@ -2400,13 +2406,15 @@
             // Assume by default that we did not install this permission into the system.
             p.setFlags(p.getFlags() & ~PermissionInfo.FLAG_INSTALLED);
 
+            final PermissionInfo permissionInfo;
+            final Permission oldPermission;
             synchronized (mLock) {
                 // Now that permission groups have a special meaning, we ignore permission
                 // groups for legacy apps to prevent unexpected behavior. In particular,
                 // permissions for one app being granted to someone just because they happen
                 // to be in a group defined by another app (before this had no implications).
                 if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) {
-                    p.setParsedPermissionGroup(mRegistry.getPermissionGroupLocked(p.getGroup()));
+                    p.setParsedPermissionGroup(mRegistry.getPermissionGroup(p.getGroup()));
                     // Warn for a permission in an unknown group.
                     if (DEBUG_PERMISSIONS
                             && p.getGroup() != null && p.getParsedPermissionGroup() == null) {
@@ -2415,27 +2423,30 @@
                     }
                 }
 
-                final PermissionInfo permissionInfo = PackageInfoUtils.generatePermissionInfo(p,
+                permissionInfo = PackageInfoUtils.generatePermissionInfo(p,
                         PackageManager.GET_META_DATA);
-                final Permission bp;
+                oldPermission = p.isTree() ? mRegistry.getPermissionTree(p.getName())
+                        : mRegistry.getPermission(p.getName());
+            }
+            // TODO(zhanghai): Maybe we should store whether a permission is owned by system inside
+            //  itself.
+            final boolean isOverridingSystemPermission = Permission.isOverridingSystemPermission(
+                    oldPermission, permissionInfo, mPackageManagerInt);
+            synchronized (mLock) {
+                final Permission permission = Permission.createOrUpdate(oldPermission,
+                        permissionInfo, pkg, mRegistry.getPermissionTrees(),
+                        isOverridingSystemPermission, chatty);
                 if (p.isTree()) {
-                    bp = Permission.createOrUpdate(
-                            mPackageManagerInt,
-                            mRegistry.getPermissionTreeLocked(p.getName()), permissionInfo, pkg,
-                            mRegistry.getPermissionTreesLocked(), chatty);
-                    mRegistry.addPermissionTreeLocked(bp);
+                    mRegistry.addPermissionTree(permission);
                 } else {
-                    bp = Permission.createOrUpdate(
-                            mPackageManagerInt,
-                            mRegistry.getPermissionLocked(p.getName()),
-                            permissionInfo, pkg, mRegistry.getPermissionTreesLocked(), chatty);
-                    mRegistry.addPermissionLocked(bp);
+                    mRegistry.addPermission(permission);
                 }
-                if (bp.isInstalled()) {
+                if (permission.isInstalled()) {
                     p.setFlags(p.getFlags() | PermissionInfo.FLAG_INSTALLED);
                 }
-                if (bp.isDefinitionChanged()) {
+                if (permission.isDefinitionChanged()) {
                     definitionChangedPermissions.add(p.getName());
+                    permission.setDefinitionChanged(false);
                 }
             }
         }
@@ -2448,11 +2459,11 @@
             StringBuilder r = null;
             for (int i = 0; i < N; i++) {
                 final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i);
-                final ParsedPermissionGroup cur = mRegistry.getPermissionGroupLocked(pg.getName());
+                final ParsedPermissionGroup cur = mRegistry.getPermissionGroup(pg.getName());
                 final String curPackageName = (cur == null) ? null : cur.getPackageName();
                 final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName);
                 if (cur == null || isPackageUpdate) {
-                    mRegistry.addPermissionGroupLocked(pg);
+                    mRegistry.addPermissionGroup(pg);
                     if (chatty && DEBUG_PACKAGE_SCANNING) {
                         if (r == null) {
                             r = new StringBuilder(256);
@@ -2491,9 +2502,9 @@
             StringBuilder r = null;
             for (int i=0; i<N; i++) {
                 ParsedPermission p = pkg.getPermissions().get(i);
-                Permission bp = mRegistry.getPermissionLocked(p.getName());
+                Permission bp = mRegistry.getPermission(p.getName());
                 if (bp == null) {
-                    bp = mRegistry.getPermissionTreeLocked(p.getName());
+                    bp = mRegistry.getPermissionTree(p.getName());
                 }
                 if (bp != null && bp.isPermission(p)) {
                     bp.setPermissionInfo(null);
@@ -2508,7 +2519,7 @@
                 }
                 if (p.isAppOp()) {
                     // TODO(zhanghai): Should we just remove the entry for this permission directly?
-                    mRegistry.removeAppOpPermissionPackageLocked(p.getName(), pkg.getPackageName());
+                    mRegistry.removeAppOpPermissionPackage(p.getName(), pkg.getPackageName());
                 }
             }
             if (r != null) {
@@ -2518,9 +2529,11 @@
             N = pkg.getRequestedPermissions().size();
             r = null;
             for (int i=0; i<N; i++) {
-                String perm = pkg.getRequestedPermissions().get(i);
-                if (mRegistry.isPermissionAppOp(perm)) {
-                    mRegistry.removeAppOpPermissionPackageLocked(perm, pkg.getPackageName());
+                final String permissionName = pkg.getRequestedPermissions().get(i);
+                final Permission permission = mRegistry.getPermission(permissionName);
+                if (permission != null && permission.isAppOp()) {
+                    mRegistry.removeAppOpPermissionPackage(permissionName,
+                            pkg.getPackageName());
                 }
             }
             if (r != null) {
@@ -2576,11 +2589,13 @@
 
     @NonNull
     private int[] getPermissionGids(@NonNull String permissionName, @UserIdInt int userId) {
-        Permission permission = mRegistry.getPermission(permissionName);
-        if (permission == null) {
-            return EmptyArray.INT;
+        synchronized (mLock) {
+            Permission permission = mRegistry.getPermission(permissionName);
+            if (permission == null) {
+                return EmptyArray.INT;
+            }
+            return permission.computeGids(userId);
         }
-        return permission.computeGids(userId);
     }
 
     /**
@@ -2629,12 +2644,14 @@
         for (int i = 0; i < requestedPermissionsSize; i++) {
             final String permissionName = pkg.getRequestedPermissions().get(i);
 
-            final Permission permission = mRegistry.getPermission(permissionName);
+            final Permission permission;
+            synchronized (mLock) {
+                permission = mRegistry.getPermission(permissionName);
+            }
             if (permission == null) {
                 continue;
             }
-            if (permission.isSignature() && shouldGrantSignaturePermission(pkg, ps,
-                    permission)) {
+            if (permission.isSignature() && shouldGrantSignaturePermission(pkg, ps, permission)) {
                 shouldGrantSignaturePermission.add(permissionName);
             }
         }
@@ -2716,12 +2733,10 @@
                         // the runtime ones are written only if changed. The only cases of
                         // changed runtime permissions here are promotion of an install to
                         // runtime and revocation of a runtime from a shared user.
-                        synchronized (mLock) {
-                            if (revokeUnusedSharedUserPermissionsLocked(
-                                    ps.getSharedUser().getPackages(), uidState)) {
-                                updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
-                                runtimePermissionsRevoked = true;
-                            }
+                        if (revokeUnusedSharedUserPermissionsLocked(
+                                ps.getSharedUser().getPackages(), uidState)) {
+                            updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
+                            runtimePermissionsRevoked = true;
                         }
                     }
                 }
@@ -2825,7 +2840,7 @@
 
                     // Keep track of app op permissions.
                     if (bp.isAppOp()) {
-                        mRegistry.addAppOpPermissionPackageLocked(perm, pkg.getPackageName());
+                        mRegistry.addAppOpPermissionPackage(perm, pkg.getPackageName());
                     }
 
                     boolean shouldGrantNormalPermission = true;
@@ -3040,6 +3055,7 @@
      *
      * @return The updated value of the {@code updatedUserIds} parameter
      */
+    @GuardedBy("mLock")
     private @NonNull int[] revokePermissionsNoLongerImplicitLocked(@NonNull UidPermissionState ps,
             @NonNull AndroidPackage pkg, int userId, @NonNull int[] updatedUserIds) {
         String pkgName = pkg.getPackageName();
@@ -3048,7 +3064,7 @@
 
         for (String permission : ps.getGrantedPermissions()) {
             if (!pkg.getImplicitPermissions().contains(permission)) {
-                Permission bp = mRegistry.getPermissionLocked(permission);
+                Permission bp = mRegistry.getPermission(permission);
                 if (bp != null && bp.isRuntime()) {
                     int flags = ps.getPermissionFlags(permission);
 
@@ -3092,6 +3108,7 @@
      * @param ps The permission state of the package
      * @param pkg The package requesting the permissions
      */
+    @GuardedBy("mLock")
     private void inheritPermissionStateToNewImplicitPermissionLocked(
             @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
             @NonNull UidPermissionState ps, @NonNull AndroidPackage pkg) {
@@ -3122,7 +3139,7 @@
                         + " for " + pkgName);
             }
 
-            ps.grantPermission(mRegistry.getPermissionLocked(newPerm));
+            ps.grantPermission(mRegistry.getPermission(newPerm));
         }
 
         // Add permission flags
@@ -3163,6 +3180,7 @@
      *
      * @return  List of users for which the permission state has been changed
      */
+    @GuardedBy("mLock")
     private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
             @NonNull UidPermissionState origPs, @NonNull UidPermissionState ps,
             @NonNull AndroidPackage pkg, @NonNull ArraySet<String> newImplicitPermissions,
@@ -3197,7 +3215,7 @@
             ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
 
             if (sourcePerms != null) {
-                Permission bp = mRegistry.getPermissionLocked(newPerm);
+                Permission bp = mRegistry.getPermission(newPerm);
                 if (bp.isRuntime()) {
 
                     if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
@@ -3212,7 +3230,7 @@
                         for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
                                 sourcePermNum++) {
                             final String sourcePerm = sourcePerms.valueAt(sourcePermNum);
-                            Permission sourceBp = mRegistry.getPermissionLocked(sourcePerm);
+                            Permission sourceBp = mRegistry.getPermission(sourcePerm);
                             if (!sourceBp.isRuntime()) {
                                 inheritsFromInstallPerm = true;
                                 break;
@@ -3554,11 +3572,13 @@
                         + packageName + " (" + pkg.getPath()
                         + ") not in privapp-permissions whitelist");
                 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
-                    if (mPrivappPermissionsViolations == null) {
-                        mPrivappPermissionsViolations = new ArraySet<>();
+                    synchronized (mLock) {
+                        if (mPrivappPermissionsViolations == null) {
+                            mPrivappPermissionsViolations = new ArraySet<>();
+                        }
+                        mPrivappPermissionsViolations.add(packageName + " (" + pkg.getPath() + "): "
+                                + permissionName);
                     }
-                    mPrivappPermissionsViolations.add(packageName + " (" + pkg.getPath() + "): "
-                            + permissionName);
                 }
             }
         }
@@ -3662,15 +3682,16 @@
         final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId);
 
         for (String permission : pkg.getRequestedPermissions()) {
-            final Permission bp;
+            final boolean shouldGrantPermission;
             synchronized (mLock) {
-                bp = mRegistry.getPermissionLocked(permission);
+                final Permission bp = mRegistry.getPermission(permission);
+                shouldGrantPermission = bp != null && (bp.isRuntime() || bp.isDevelopment())
+                        && (!instantApp || bp.isInstant())
+                        && (supportsRuntimePermissions || !bp.isRuntimeOnly())
+                        && (grantedPermissions == null
+                                || ArrayUtils.contains(grantedPermissions, permission));
             }
-            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
-                    && (!instantApp || bp.isInstant())
-                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
-                    && (grantedPermissions == null
-                           || ArrayUtils.contains(grantedPermissions, permission))) {
+            if (shouldGrantPermission) {
                 final int flags = getPermissionFlagsInternal(permission, pkg.getPackageName(),
                         callingUid, userId);
                 if (supportsRuntimePermissions) {
@@ -3704,14 +3725,13 @@
             for (int j = 0; j < permissionCount; j++) {
                 final String permissionName = pkg.getRequestedPermissions().get(j);
 
-                final Permission bp = mRegistry.getPermissionLocked(permissionName);
-
-                if (bp == null || !bp.isHardOrSoftRestricted()) {
-                    continue;
-                }
-
                 final boolean isGranted;
                 synchronized (mLock) {
+                    final Permission bp = mRegistry.getPermission(permissionName);
+                    if (bp == null || !bp.isHardOrSoftRestricted()) {
+                        continue;
+                    }
+
                     final UidPermissionState uidState = getUidStateLocked(pkg, userId);
                     if (uidState == null) {
                         Slog.e(TAG, "Missing permissions state for " + pkg.getPackageName()
@@ -3865,11 +3885,6 @@
         int affectedUserId = UserHandle.USER_NULL;
         // Update permissions
         for (String eachPerm : deletedPs.pkg.getRequestedPermissions()) {
-            Permission bp = mRegistry.getPermission(eachPerm);
-            if (bp == null) {
-                continue;
-            }
-
             // Check if another package in the shared user needs the permission.
             boolean used = false;
             final List<AndroidPackage> pkgs = sus.getPackages();
@@ -3913,6 +3928,11 @@
                     continue;
                 }
 
+                Permission bp = mRegistry.getPermission(eachPerm);
+                if (bp == null) {
+                    continue;
+                }
+
                 // TODO(zhanghai): Why are we only killing the UID when GIDs changed, instead of any
                 //  permission change?
                 if (uidState.removePermissionState(bp.getName()) && bp.hasGids()) {
@@ -3939,7 +3959,7 @@
             final int requestedPermCount = pkg.getRequestedPermissions().size();
             for (int j = 0; j < requestedPermCount; j++) {
                 String permission = pkg.getRequestedPermissions().get(j);
-                Permission bp = mRegistry.getPermissionLocked(permission);
+                Permission bp = mRegistry.getPermission(permission);
                 if (bp != null) {
                     usedPermissions.add(permission);
                 }
@@ -3954,7 +3974,7 @@
         for (int i = permissionStatesSize - 1; i >= 0; i--) {
             PermissionState permissionState = permissionStates.get(i);
             if (!usedPermissions.contains(permissionState.getName())) {
-                Permission bp = mRegistry.getPermissionLocked(permissionState.getName());
+                Permission bp = mRegistry.getPermission(permissionState.getName());
                 if (bp != null) {
                     if (uidState.removePermissionState(bp.getName())
                             && permissionState.isRuntime()) {
@@ -4017,35 +4037,6 @@
     }
 
     /**
-     * Cache background->foreground permission mapping.
-     *
-     * <p>This is only run once.
-     */
-    private void cacheBackgroundToForegoundPermissionMapping() {
-        synchronized (mLock) {
-            if (mBackgroundPermissions == null) {
-                // Cache background -> foreground permission mapping.
-                // Only system declares background permissions, hence mapping does never change.
-                mBackgroundPermissions = new ArrayMap<>();
-                for (Permission bp : mRegistry.getPermissionsLocked()) {
-                    if (bp.getBackgroundPermission() != null) {
-                        String fgPerm = bp.getName();
-                        String bgPerm = bp.getBackgroundPermission();
-
-                        List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
-                        if (fgPerms == null) {
-                            fgPerms = new ArrayList<>();
-                            mBackgroundPermissions.put(bgPerm, fgPerms);
-                        }
-
-                        fgPerms.add(fgPerm);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
      * Update all packages on the volume, <u>beside</u> the changing package. If the changing
      * package is set too, all packages are updated.
      */
@@ -4118,8 +4109,6 @@
             flags |= UPDATE_PERMISSIONS_ALL;
         }
 
-        cacheBackgroundToForegoundPermissionMapping();
-
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
         // Now update the permissions for all packages.
         if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
@@ -4173,9 +4162,9 @@
         boolean changed = false;
         Set<Permission> needsUpdate = null;
         synchronized (mLock) {
-            for (final Permission bp : mRegistry.getPermissionsLocked()) {
+            for (final Permission bp : mRegistry.getPermissions()) {
                 if (bp.isDynamic()) {
-                    bp.updateDynamicPermission(mRegistry.getPermissionTreesLocked());
+                    bp.updateDynamicPermission(mRegistry.getPermissionTrees());
                 }
                 if (!packageName.equals(bp.getPackageName())) {
                     // Not checking sourcePackageSetting because it can be null when
@@ -4225,7 +4214,9 @@
                             }
                         });
                     }
-                    mRegistry.removePermissionLocked(bp.getName());
+                    synchronized (mLock) {
+                        mRegistry.removePermission(bp.getName());
+                    }
                     continue;
                 }
                 final AndroidPackage sourcePkg =
@@ -4239,7 +4230,7 @@
                     }
                     Slog.w(TAG, "Removing dangling permission: " + bp.getName()
                             + " from package " + bp.getPackageName());
-                    mRegistry.removePermissionLocked(bp.getName());
+                    mRegistry.removePermission(bp.getName());
                 }
             }
         }
@@ -4307,7 +4298,7 @@
 
         Set<Permission> needsUpdate = null;
         synchronized (mLock) {
-            final Iterator<Permission> it = mRegistry.getPermissionTreesLocked().iterator();
+            final Iterator<Permission> it = mRegistry.getPermissionTrees().iterator();
             while (it.hasNext()) {
                 final Permission bp = it.next();
                 if (!packageName.equals(bp.getPackageName())) {
@@ -4343,7 +4334,7 @@
                     }
                     Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
                             + " from package " + bp.getPackageName());
-                    mRegistry.removePermissionLocked(bp.getName());
+                    mRegistry.removePermission(bp.getName());
                 }
             }
         }
@@ -4524,16 +4515,16 @@
         return builder.toString();
     }
 
-    @GuardedBy({"mSettings.mLock", "mLock"})
+    @GuardedBy("mLock")
     private int calculateCurrentPermissionFootprintLocked(@NonNull Permission permissionTree) {
         int size = 0;
-        for (final Permission permission : mRegistry.getPermissionsLocked()) {
+        for (final Permission permission : mRegistry.getPermissions()) {
             size += permissionTree.calculateFootprint(permission);
         }
         return size;
     }
 
-    @GuardedBy({"mSettings.mLock", "mLock"})
+    @GuardedBy("mLock")
     private void enforcePermissionCapLocked(PermissionInfo info, Permission tree) {
         // We calculate the max size of permissions defined by this uid and throw
         // if that plus the size of 'info' would exceed our stated maximum.
@@ -4547,9 +4538,12 @@
 
     private void systemReady() {
         mSystemReady = true;
-        if (mPrivappPermissionsViolations != null) {
-            throw new IllegalStateException("Signature|privileged permissions not in "
-                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
+
+        synchronized (mLock) {
+            if (mPrivappPermissionsViolations != null) {
+                throw new IllegalStateException("Signature|privileged permissions not in "
+                        + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
+            }
         }
 
         mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
@@ -4617,29 +4611,21 @@
         mMetricsLogger.write(log);
     }
 
-    /**
-     * Get the mapping of background permissions to their foreground permissions.
-     *
-     * <p>Only initialized in the system server.
-     *
-     * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
-     */
-    public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
-        return mBackgroundPermissions;
-    }
-
+    @GuardedBy("mLock")
     @Nullable
     private UidPermissionState getUidStateLocked(@NonNull PackageSetting ps,
             @UserIdInt int userId) {
         return getUidStateLocked(ps.getAppId(), userId);
     }
 
+    @GuardedBy("mLock")
     @Nullable
     private UidPermissionState getUidStateLocked(@NonNull AndroidPackage pkg,
             @UserIdInt int userId) {
         return getUidStateLocked(pkg.getUid(), userId);
     }
 
+    @GuardedBy("mLock")
     @Nullable
     private UidPermissionState getUidStateLocked(@AppIdInt int appId, @UserIdInt int userId) {
         final UserPermissionState userState = mState.getUserState(userId);
@@ -4682,11 +4668,12 @@
         });
     }
 
+    @GuardedBy("mLock")
     private void readLegacyPermissionStatesLocked(@NonNull UidPermissionState uidState,
             @NonNull Collection<LegacyPermissionState.PermissionState> permissionStates) {
         for (final LegacyPermissionState.PermissionState permissionState : permissionStates) {
             final String permissionName = permissionState.getName();
-            final Permission permission = mRegistry.getPermissionLocked(permissionName);
+            final Permission permission = mRegistry.getPermission(permissionName);
             if (permission == null) {
                 Slog.w(TAG, "Unknown permission: " + permissionName);
                 continue;
@@ -4771,9 +4758,9 @@
                             permission.setGids(configPermission.getRawGids(),
                                     configPermission.areGidsPerUser());
                         }
-                        mRegistry.addPermissionLocked(permission);
+                        mRegistry.addPermission(permission);
                     } else {
-                        mRegistry.addPermissionTreeLocked(permission);
+                        mRegistry.addPermissionTree(permission);
                     }
                 }
             }
@@ -4787,7 +4774,7 @@
             final List<LegacyPermission> legacyPermissions = new ArrayList<>();
             synchronized (mLock) {
                 final Collection<Permission> permissions = writePermissionOrPermissionTree == 0
-                        ? mRegistry.getPermissionsLocked() : mRegistry.getPermissionTreesLocked();
+                        ? mRegistry.getPermissions() : mRegistry.getPermissionTrees();
                 for (final Permission permission : permissions) {
                     // We don't need to provide UID and GIDs, which are only retrieved when dumping.
                     final LegacyPermission legacyPermission = new LegacyPermission(
@@ -4807,7 +4794,7 @@
     private void transferPermissions(@NonNull String oldPackageName,
             @NonNull String newPackageName) {
         synchronized (mLock) {
-            mRegistry.transferPermissionsLocked(oldPackageName, newPackageName);
+            mRegistry.transferPermissions(oldPackageName, newPackageName);
         }
     }
 
@@ -4822,7 +4809,7 @@
     private List<LegacyPermission> getLegacyPermissions() {
         synchronized (mLock) {
             final List<LegacyPermission> legacyPermissions = new ArrayList<>();
-            for (final Permission permission : mRegistry.getPermissionsLocked()) {
+            for (final Permission permission : mRegistry.getPermissions()) {
                 final LegacyPermission legacyPermission = new LegacyPermission(
                         permission.getPermissionInfo(), permission.getType(), permission.getUid(),
                         permission.getRawGids());
@@ -4836,7 +4823,7 @@
     private Map<String, Set<String>> getAllAppOpPermissionPackages() {
         synchronized (mLock) {
             final ArrayMap<String, ArraySet<String>> appOpPermissionPackages =
-                    mRegistry.getAllAppOpPermissionPackagesLocked();
+                    mRegistry.getAllAppOpPermissionPackages();
             final Map<String, Set<String>> deepClone = new ArrayMap<>();
             final int appOpPermissionPackagesSize = appOpPermissionPackages.size();
             for (int i = 0; i < appOpPermissionPackagesSize; i++) {
@@ -5045,8 +5032,8 @@
 
         @Override
         public Permission getPermissionTEMP(String permName) {
-            synchronized (PermissionManagerService.this.mLock) {
-                return mRegistry.getPermissionLocked(permName);
+            synchronized (mLock) {
+                return mRegistry.getPermission(permName);
             }
         }
 
@@ -5056,7 +5043,7 @@
             ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
 
             synchronized (mLock) {
-                for (final Permission permission : mRegistry.getPermissionsLocked()) {
+                for (final Permission permission : mRegistry.getPermissions()) {
                     if (permission.getProtection() == protection) {
                         matchingPermissions.add(permission.generatePermissionInfo(0));
                     }
@@ -5072,7 +5059,7 @@
             ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
 
             synchronized (mLock) {
-                for (final Permission permission : mRegistry.getPermissionsLocked()) {
+                for (final Permission permission : mRegistry.getPermissions()) {
                     if ((permission.getProtectionFlags() & protectionFlags) == protectionFlags) {
                         matchingPermissions.add(permission.generatePermissionInfo(0));
                     }
@@ -5270,7 +5257,7 @@
                 Iterator<String> iterator = permissionNames.iterator();
                 while (iterator.hasNext()) {
                     final String permissionName = iterator.next();
-                    final Permission permission = mRegistry.getPermissionLocked(permissionName);
+                    final Permission permission = mRegistry.getPermission(permissionName);
                     if (permission == null || !permission.isHardOrSoftRestricted()) {
                         iterator.remove();
                     }
@@ -5346,12 +5333,11 @@
             }
         }
 
-        public void addListenerLocked(IOnPermissionsChangeListener listener) {
+        public void addListener(IOnPermissionsChangeListener listener) {
             mPermissionListeners.register(listener);
-
         }
 
-        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
+        public void removeListener(IOnPermissionsChangeListener listener) {
             mPermissionListeners.unregister(listener);
         }
 
diff --git a/services/core/java/com/android/server/pm/permission/PermissionRegistry.java b/services/core/java/com/android/server/pm/permission/PermissionRegistry.java
index 36719203..0e3fda7 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionRegistry.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionRegistry.java
@@ -22,8 +22,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
-import com.android.internal.annotations.GuardedBy;
-
 import java.util.Collection;
 
 /**
@@ -34,87 +32,62 @@
      * All of the permissions known to the system. The mapping is from permission
      * name to permission object.
      */
-    @GuardedBy("mLock")
     private final ArrayMap<String, Permission> mPermissions = new ArrayMap<>();
 
     /**
      * All permission trees known to the system. The mapping is from permission tree
      * name to permission object.
      */
-    @GuardedBy("mLock")
     private final ArrayMap<String, Permission> mPermissionTrees = new ArrayMap<>();
 
     /**
      * All permisson groups know to the system. The mapping is from permission group
      * name to permission group object.
      */
-    @GuardedBy("mLock")
     private final ArrayMap<String, ParsedPermissionGroup> mPermissionGroups = new ArrayMap<>();
 
     /**
      * Set of packages that request a particular app op. The mapping is from permission
      * name to package names.
      */
-    @GuardedBy("mLock")
     private final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
 
     @NonNull
-    private final Object mLock;
-
-    public PermissionRegistry(@NonNull Object lock) {
-        mLock = lock;
-    }
-
-    @GuardedBy("mLock")
-    @NonNull
-    public Collection<Permission> getPermissionsLocked() {
+    public Collection<Permission> getPermissions() {
         return mPermissions.values();
     }
 
-    @GuardedBy("mLock")
-    @Nullable
-    public Permission getPermissionLocked(@NonNull String permName) {
-        return mPermissions.get(permName);
-    }
-
     @Nullable
     public Permission getPermission(@NonNull String permissionName) {
-        synchronized (mLock) {
-            return getPermissionLocked(permissionName);
-        }
+        return mPermissions.get(permissionName);
     }
 
-    @GuardedBy("mLock")
-    public void addPermissionLocked(@NonNull Permission permission) {
+    public void addPermission(@NonNull Permission permission) {
         mPermissions.put(permission.getName(), permission);
     }
 
-    @GuardedBy("mLock")
-    public void removePermissionLocked(@NonNull String permissionName) {
+    public void removePermission(@NonNull String permissionName) {
         mPermissions.remove(permissionName);
     }
 
-    @GuardedBy("mLock")
     @NonNull
-    public Collection<Permission> getPermissionTreesLocked() {
+    public Collection<Permission> getPermissionTrees() {
         return mPermissionTrees.values();
     }
 
-    @GuardedBy("mLock")
     @Nullable
-    public Permission getPermissionTreeLocked(@NonNull String permissionTreeName) {
+    public Permission getPermissionTree(@NonNull String permissionTreeName) {
         return mPermissionTrees.get(permissionTreeName);
     }
 
-    @GuardedBy("mLock")
-    public void addPermissionTreeLocked(@NonNull Permission permissionTree) {
+    public void addPermissionTree(@NonNull Permission permissionTree) {
         mPermissionTrees.put(permissionTree.getName(), permissionTree);
     }
 
     /**
      * Transfers ownership of permissions from one package to another.
      */
-    public void transferPermissionsLocked(@NonNull String oldPackageName,
+    public void transferPermissions(@NonNull String oldPackageName,
             @NonNull String newPackageName) {
         for (int i = 0; i < 2; i++) {
             ArrayMap<String, Permission> permissions = i == 0 ? mPermissionTrees : mPermissions;
@@ -124,37 +97,31 @@
         }
     }
 
-    @GuardedBy("mLock")
     @NonNull
-    public Collection<ParsedPermissionGroup> getPermissionGroupsLocked() {
+    public Collection<ParsedPermissionGroup> getPermissionGroups() {
         return mPermissionGroups.values();
     }
 
-    @GuardedBy("mLock")
     @Nullable
-    public ParsedPermissionGroup getPermissionGroupLocked(@NonNull String permissionGroupName) {
+    public ParsedPermissionGroup getPermissionGroup(@NonNull String permissionGroupName) {
         return mPermissionGroups.get(permissionGroupName);
     }
 
-    @GuardedBy("mLock")
-    public void addPermissionGroupLocked(@NonNull ParsedPermissionGroup permissionGroup) {
+    public void addPermissionGroup(@NonNull ParsedPermissionGroup permissionGroup) {
         mPermissionGroups.put(permissionGroup.getName(), permissionGroup);
     }
 
-    @GuardedBy("mLock")
     @NonNull
-    public ArrayMap<String, ArraySet<String>> getAllAppOpPermissionPackagesLocked() {
+    public ArrayMap<String, ArraySet<String>> getAllAppOpPermissionPackages() {
         return mAppOpPermissionPackages;
     }
 
-    @GuardedBy("mLock")
     @Nullable
-    public ArraySet<String> getAppOpPermissionPackagesLocked(@NonNull String permissionName) {
+    public ArraySet<String> getAppOpPermissionPackages(@NonNull String permissionName) {
         return mAppOpPermissionPackages.get(permissionName);
     }
 
-    @GuardedBy("mLock")
-    public void addAppOpPermissionPackageLocked(@NonNull String permissionName,
+    public void addAppOpPermissionPackage(@NonNull String permissionName,
             @NonNull String packageName) {
         ArraySet<String> packageNames = mAppOpPermissionPackages.get(permissionName);
         if (packageNames == null) {
@@ -164,8 +131,7 @@
         packageNames.add(packageName);
     }
 
-    @GuardedBy("mLock")
-    public void removeAppOpPermissionPackageLocked(@NonNull String permissionName,
+    public void removeAppOpPermissionPackage(@NonNull String permissionName,
             @NonNull String packageName) {
         final ArraySet<String> packageNames = mAppOpPermissionPackages.get(permissionName);
         if (packageNames == null) {
@@ -184,23 +150,7 @@
      */
     @NonNull
     public Permission enforcePermissionTree(@NonNull String permissionName, int callingUid) {
-        synchronized (mLock) {
-            return Permission.enforcePermissionTree(mPermissionTrees.values(), permissionName,
-                    callingUid);
-        }
-    }
-
-    public boolean isPermissionInstant(@NonNull String permissionName) {
-        synchronized (mLock) {
-            final Permission permission = mPermissions.get(permissionName);
-            return permission != null && permission.isInstant();
-        }
-    }
-
-    boolean isPermissionAppOp(@NonNull String permissionName) {
-        synchronized (mLock) {
-            final Permission permission = mPermissions.get(permissionName);
-            return permission != null && permission.isAppOp();
-        }
+        return Permission.enforcePermissionTree(mPermissionTrees.values(), permissionName,
+                callingUid);
     }
 }
diff --git a/services/core/java/com/android/server/policy/DisplayFoldController.java b/services/core/java/com/android/server/policy/DisplayFoldController.java
index f8e26fc..b007a75 100644
--- a/services/core/java/com/android/server/policy/DisplayFoldController.java
+++ b/services/core/java/com/android/server/policy/DisplayFoldController.java
@@ -16,8 +16,10 @@
 
 package com.android.server.policy;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Rect;
+import android.hardware.ICameraService;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
@@ -26,11 +28,13 @@
 import android.os.Handler;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.util.Slog;
 import android.view.DisplayInfo;
 import android.view.IDisplayFoldListener;
 
 import com.android.server.DisplayThread;
 import com.android.server.LocalServices;
+import com.android.server.camera.CameraServiceProxy;
 import com.android.server.wm.WindowManagerInternal;
 
 /**
@@ -38,11 +42,13 @@
  * TODO(b/126160895): Move DisplayFoldController from PhoneWindowManager to DisplayPolicy.
  */
 class DisplayFoldController {
-
     private static final String TAG = "DisplayFoldController";
 
     private final WindowManagerInternal mWindowManagerInternal;
     private final DisplayManagerInternal mDisplayManagerInternal;
+    // Camera service proxy can be disabled through a config.
+    @Nullable
+    private final CameraServiceProxy mCameraServiceProxy;
     private final int mDisplayId;
     private final Handler mHandler;
 
@@ -58,10 +64,12 @@
     private final DisplayFoldDurationLogger mDurationLogger = new DisplayFoldDurationLogger();
 
     DisplayFoldController(WindowManagerInternal windowManagerInternal,
-            DisplayManagerInternal displayManagerInternal, int displayId, Rect foldedArea,
+            DisplayManagerInternal displayManagerInternal,
+            @Nullable CameraServiceProxy cameraServiceProxy, int displayId, Rect foldedArea,
             Handler handler) {
         mWindowManagerInternal = windowManagerInternal;
         mDisplayManagerInternal = displayManagerInternal;
+        mCameraServiceProxy = cameraServiceProxy;
         mDisplayId = displayId;
         mFoldedArea = new Rect(foldedArea);
         mHandler = handler;
@@ -116,6 +124,16 @@
             }
         }
 
+        if (mCameraServiceProxy != null) {
+            if (folded) {
+                mCameraServiceProxy.setDeviceStateFlags(ICameraService.DEVICE_STATE_FOLDED);
+            } else {
+                mCameraServiceProxy.clearDeviceStateFlags(ICameraService.DEVICE_STATE_FOLDED);
+            }
+        } else {
+            Slog.w(TAG, "Camera service unavailable to toggle folded state.");
+        }
+
         mDurationLogger.setDeviceFolded(folded);
         mDurationLogger.logFocusedAppWithFoldState(folded, mFocusedApp);
         mFolded = folded;
@@ -193,8 +211,13 @@
     }
 
     static DisplayFoldController create(Context context, int displayId) {
+        final WindowManagerInternal windowManagerService =
+                LocalServices.getService(WindowManagerInternal.class);
         final DisplayManagerInternal displayService =
                 LocalServices.getService(DisplayManagerInternal.class);
+        final CameraServiceProxy cameraServiceProxy =
+                LocalServices.getService(CameraServiceProxy.class);
+
         final String configFoldedArea = context.getResources().getString(
                 com.android.internal.R.string.config_foldedArea);
         final Rect foldedArea;
@@ -204,7 +227,7 @@
             foldedArea = Rect.unflattenFromString(configFoldedArea);
         }
 
-        return new DisplayFoldController(LocalServices.getService(WindowManagerInternal.class),
-                displayService, displayId, foldedArea, DisplayThread.getHandler());
+        return new DisplayFoldController(windowManagerService, displayService, cameraServiceProxy,
+                displayId, foldedArea, DisplayThread.getHandler());
     }
 }
diff --git a/services/core/java/com/android/server/power/AttentionDetector.java b/services/core/java/com/android/server/power/AttentionDetector.java
index 06edd19..1a4a222 100644
--- a/services/core/java/com/android/server/power/AttentionDetector.java
+++ b/services/core/java/com/android/server/power/AttentionDetector.java
@@ -18,6 +18,7 @@
 
 import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.SynchronousUserSwitchObserver;
 import android.attention.AttentionManagerInternal;
@@ -42,6 +43,7 @@
 import com.android.server.wm.WindowManagerInternal;
 
 import java.io.PrintWriter;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -66,6 +68,9 @@
     /** Default value in absence of {@link DeviceConfig} override. */
     static final long DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS = 2_000;
 
+    @VisibleForTesting
+    protected long mPreDimCheckDurationMillis;
+
     /** DeviceConfig flag name, describes how long to run the check beyond the screen dim event. */
     static final String KEY_POST_DIM_CHECK_DURATION_MILLIS =
             "post_dim_check_duration_millis";
@@ -73,12 +78,28 @@
     /** Default value in absence of {@link DeviceConfig} override. */
     static final long DEFAULT_POST_DIM_CHECK_DURATION_MILLIS = 0;
 
+    private long mRequestedPostDimTimeoutMillis;
+
+    /**
+     * Keep the last used post dim timeout for the dumpsys (it can't be longer the dim duration).
+     */
+    private long mEffectivePostDimTimeoutMillis;
+
     /**
      * DeviceConfig flag name, describes the limit of how long the device can remain unlocked due to
      * attention checking.
      */
     static final String KEY_MAX_EXTENSION_MILLIS = "max_extension_millis";
 
+    /**
+     * The default value for the maximum time, in millis, that the phone can stay unlocked because
+     * of attention events, triggered by any user.
+     */
+    @VisibleForTesting
+    protected long mDefaultMaximumExtensionMillis;
+
+    private long mMaximumExtensionMillis;
+
     private Context mContext;
 
     private boolean mIsSettingEnabled;
@@ -88,13 +109,6 @@
      */
     private final Runnable mOnUserAttention;
 
-    /**
-     * The default value for the maximum time, in millis, that the phone can stay unlocked because
-     * of attention events, triggered by any user.
-     */
-    @VisibleForTesting
-    protected long mDefaultMaximumExtensionMillis;
-
     private final Object mLock;
 
     /**
@@ -137,9 +151,6 @@
     @VisibleForTesting
     AttentionCallbackInternalImpl mCallback;
 
-    /** Keep the last used post dim timeout for the dumpsys. */
-    private long mLastPostDimTimeout;
-
     public AttentionDetector(Runnable onUserAttention, Object lock) {
         mOnUserAttention = onUserAttention;
         mLock = lock;
@@ -180,6 +191,11 @@
                         updateEnabledFromSettings(context);
                     }
                 }, UserHandle.USER_ALL);
+
+        readValuesFromDeviceConfig();
+        DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_ATTENTION_MANAGER_SERVICE,
+                context.getMainExecutor(),
+                (properties) -> onDeviceConfigChange(properties.getKeyset()));
     }
 
     /** To be called in {@link PowerManagerService#updateUserActivitySummaryLocked}. */
@@ -192,8 +208,8 @@
         }
 
         final long now = SystemClock.uptimeMillis();
-        final long whenToCheck = nextScreenDimming - getPreDimCheckDurationMillis();
-        final long whenToStopExtending = mLastUserActivityTime + getMaxExtensionMillis();
+        final long whenToCheck = nextScreenDimming - mPreDimCheckDurationMillis;
+        final long whenToStopExtending = mLastUserActivityTime + mMaximumExtensionMillis;
         if (now < whenToCheck) {
             if (DEBUG) {
                 Slog.d(TAG, "Do not check for attention yet, wait " + (whenToCheck - now));
@@ -220,9 +236,11 @@
         mRequestId++;
         mLastActedOnNextScreenDimming = nextScreenDimming;
         mCallback = new AttentionCallbackInternalImpl(mRequestId);
+        mEffectivePostDimTimeoutMillis = Math.min(mRequestedPostDimTimeoutMillis,
+                dimDurationMillis);
         Slog.v(TAG, "Checking user attention, ID: " + mRequestId);
         final boolean sent = mAttentionManager.checkAttention(
-                getPreDimCheckDurationMillis() + getPostDimCheckDurationMillis(dimDurationMillis),
+                mPreDimCheckDurationMillis + mEffectivePostDimTimeoutMillis,
                 mCallback);
         if (!sent) {
             mRequested.set(false);
@@ -294,9 +312,9 @@
     public void dump(PrintWriter pw) {
         pw.println("AttentionDetector:");
         pw.println(" mIsSettingEnabled=" + mIsSettingEnabled);
-        pw.println(" mMaxExtensionMillis=" + getMaxExtensionMillis());
-        pw.println(" preDimCheckDurationMillis=" + getPreDimCheckDurationMillis());
-        pw.println(" postDimCheckDurationMillis=" + mLastPostDimTimeout);
+        pw.println(" mMaxExtensionMillis=" + mMaximumExtensionMillis);
+        pw.println(" mPreDimCheckDurationMillis=" + mPreDimCheckDurationMillis);
+        pw.println(" mEffectivePostDimTimeout=" + mEffectivePostDimTimeoutMillis);
         pw.println(" mLastUserActivityTime(excludingAttention)=" + mLastUserActivityTime);
         pw.println(" mAttentionServiceSupported=" + isAttentionServiceSupported());
         pw.println(" mRequested=" + mRequested);
@@ -319,7 +337,7 @@
 
     /** How long to check <b>after</b> the screen dims, capped at the dim duration. */
     @VisibleForTesting
-    protected long getPostDimCheckDurationMillis(long dimDurationMillis) {
+    protected long getPostDimCheckDurationMillis() {
         final long millis = DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                 KEY_POST_DIM_CHECK_DURATION_MILLIS,
                 DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
@@ -328,9 +346,7 @@
             Slog.w(TAG, "Bad flag value supplied for: " + KEY_POST_DIM_CHECK_DURATION_MILLIS);
             return DEFAULT_POST_DIM_CHECK_DURATION_MILLIS;
         }
-
-        mLastPostDimTimeout = Math.min(millis, dimDurationMillis);
-        return mLastPostDimTimeout;
+        return millis;
     }
 
     /** How long the device can remain unlocked due to attention checking. */
@@ -348,6 +364,32 @@
         return millis;
     }
 
+    private void onDeviceConfigChange(@NonNull Set<String> keys) {
+        for (String key : keys) {
+            switch (key) {
+                case KEY_MAX_EXTENSION_MILLIS:
+                case KEY_POST_DIM_CHECK_DURATION_MILLIS:
+                case KEY_PRE_DIM_CHECK_DURATION_MILLIS:
+                    readValuesFromDeviceConfig();
+                    return;
+                default:
+                    Slog.i(TAG, "Ignoring change on " + key);
+            }
+        }
+    }
+
+    private void readValuesFromDeviceConfig() {
+        mMaximumExtensionMillis = getMaxExtensionMillis();
+        mPreDimCheckDurationMillis = getPreDimCheckDurationMillis();
+        mRequestedPostDimTimeoutMillis = getPostDimCheckDurationMillis();
+
+        Slog.i(TAG, "readValuesFromDeviceConfig():"
+                + "\nmMaximumExtensionMillis=" + mMaximumExtensionMillis
+                + "\nmPreDimCheckDurationMillis=" + mPreDimCheckDurationMillis
+                + "\nmRequestedPostDimTimeoutMillis=" + mRequestedPostDimTimeoutMillis);
+
+    }
+
     @VisibleForTesting
     final class AttentionCallbackInternalImpl extends AttentionCallbackInternal {
         private final int mId;
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/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/rollback/WatchdogRollbackLogger.java b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java
index e72c185..f9ef994 100644
--- a/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java
+++ b/services/core/java/com/android/server/rollback/WatchdogRollbackLogger.java
@@ -36,6 +36,7 @@
 import android.content.pm.VersionedPackage;
 import android.content.rollback.PackageRollbackInfo;
 import android.content.rollback.RollbackInfo;
+import android.os.SystemProperties;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Slog;
@@ -216,6 +217,34 @@
                     failingPackageName,
                     new byte[]{});
         }
+
+        logTestProperties(logPackage, type, rollbackReason, failingPackageName);
+    }
+
+    /**
+     * Writes properties which will be used by rollback tests to check if particular rollback
+     * events have occurred.
+     *
+     * persist.sys.rollbacktest.enabled: true if rollback tests are running
+     * persist.sys.rollbacktest.EVENT_TYPE: true if a particular rollback event has occurred
+     *   ex: persist.sys.rollbacktest.ROLLBACK_INITIATE is true if ROLLBACK_INITIATE has happened
+     * persist.sys.rollbacktest.EVENT_TYPE.logPackage: the package to associate the rollback with
+     * persist.sys.rollbacktest.EVENT_TYPE.rollbackReason: the reason Watchdog triggered a rollback
+     * persist.sys.rollbacktest.EVENT_TYPE.failedPackageName: the failing package or process which
+     *   triggered the rollback
+     */
+    private static void logTestProperties(@Nullable VersionedPackage logPackage, int type,
+            int rollbackReason, @NonNull String failingPackageName) {
+        // This property should be on only during the tests
+        final String prefix = "persist.sys.rollbacktest.";
+        if (!SystemProperties.getBoolean(prefix + "enabled", false)) {
+            return;
+        }
+        String key = prefix + rollbackTypeToString(type);
+        SystemProperties.set(key, String.valueOf(true));
+        SystemProperties.set(key + ".logPackage", logPackage != null ? logPackage.toString() : "");
+        SystemProperties.set(key + ".rollbackReason", rollbackReasonToString(rollbackReason));
+        SystemProperties.set(key + ".failedPackageName", failingPackageName);
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 7433a3a..d3b1ac6 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -247,6 +247,13 @@
     // 20% as a conservative estimate.
     private static final int MAX_PROCSTATS_RAW_SHARD_SIZE = (int) (MAX_PROCSTATS_SHARD_SIZE * 1.20);
 
+    /**
+     * Threshold to filter out small CPU times at frequency per UID. Those small values appear
+     * because of more precise accounting in a BPF program. Discarding them reduces the data by at
+     * least 20% with negligible error.
+     */
+    private static final int MIN_CPU_TIME_PER_UID_FREQ = 10;
+
     private final Object mThermalLock = new Object();
     @GuardedBy("mThermalLock")
     private IThermalService mThermalService;
@@ -1509,7 +1516,7 @@
     int pullCpuTimePerUidFreqLocked(int atomTag, List<StatsEvent> pulledData) {
         mCpuUidFreqTimeReader.readAbsolute((uid, cpuFreqTimeMs) -> {
             for (int freqIndex = 0; freqIndex < cpuFreqTimeMs.length; ++freqIndex) {
-                if (cpuFreqTimeMs[freqIndex] != 0) {
+                if (cpuFreqTimeMs[freqIndex] >= MIN_CPU_TIME_PER_UID_FREQ) {
                     pulledData.add(FrameworkStatsLog.buildStatsEvent(
                             atomTag, uid, freqIndex, cpuFreqTimeMs[freqIndex]));
                 }
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java
index 941be0e..1357608 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java
@@ -168,7 +168,7 @@
         // that support new types of auto detection on the same hardware.
         if (isAutoDetectionSupported()) {
             final boolean autoDetectionEnabled = configuration.isAutoDetectionEnabled();
-            setAutoDetectionEnabled(autoDetectionEnabled);
+            setAutoDetectionEnabledIfRequired(autoDetectionEnabled);
 
             // Avoid writing the geo detection enabled setting for devices that do not support geo
             // time zone detection: if we wrote it down then we'd set the value explicitly, which
@@ -176,7 +176,7 @@
             // releases that support geo detection on the same hardware.
             if (isGeoDetectionSupported()) {
                 final boolean geoTzDetectionEnabled = configuration.isGeoDetectionEnabled();
-                setGeoDetectionEnabled(userId, geoTzDetectionEnabled);
+                setGeoDetectionEnabledIfRequired(userId, geoTzDetectionEnabled);
             }
         }
     }
@@ -198,8 +198,14 @@
         return Settings.Global.getInt(mCr, Settings.Global.AUTO_TIME_ZONE, 1 /* default */) > 0;
     }
 
-    private void setAutoDetectionEnabled(boolean enabled) {
-        Settings.Global.putInt(mCr, Settings.Global.AUTO_TIME_ZONE, enabled ? 1 : 0);
+    private void setAutoDetectionEnabledIfRequired(boolean enabled) {
+        // This check is racey, but the whole settings update process is racey. This check prevents
+        // a ConfigurationChangeListener callback triggering due to ContentObserver's still
+        // triggering *sometimes* for no-op updates. Because callbacks are async this is necessary
+        // for stable behavior during tests.
+        if (isAutoDetectionEnabled() != enabled) {
+            Settings.Global.putInt(mCr, Settings.Global.AUTO_TIME_ZONE, enabled ? 1 : 0);
+        }
     }
 
     private boolean isLocationEnabled(@UserIdInt int userId) {
@@ -213,9 +219,12 @@
                 (geoDetectionEnabledByDefault ? 1 : 0) /* defaultValue */, userId) != 0;
     }
 
-    private void setGeoDetectionEnabled(@UserIdInt int userId, boolean enabled) {
-        Settings.Secure.putIntForUser(mCr, Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
-                enabled ? 1 : 0, userId);
+    private void setGeoDetectionEnabledIfRequired(@UserIdInt int userId, boolean enabled) {
+        // See comment in setAutoDetectionEnabledIfRequired. http://b/171953500
+        if (isGeoDetectionEnabled(userId) != enabled) {
+            Settings.Secure.putIntForUser(mCr, Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
+                    enabled ? 1 : 0, userId);
+        }
     }
 
     private boolean deviceHasTelephonyNetwork() {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 25b2523..910a1a2 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1195,12 +1195,7 @@
             }
         }
 
-        // Only allow app switching to be resumed if activity is not a restricted background
-        // activity, otherwise any background activity started in background task can stop
-        // home button protection mode.
-        if (!restrictedBgActivity) {
-            mService.onStartActivitySetDidAppSwitch();
-        }
+        mService.onStartActivitySetDidAppSwitch();
         mController.doPendingActivityLaunches(false);
 
         mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
@@ -1265,20 +1260,6 @@
             return false;
         }
 
-        // Always allow home application to start activities.
-        if (mService.mHomeProcess != null && callingUid == mService.mHomeProcess.mUid) {
-            if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")");
-            }
-            return false;
-        }
-
-        // App switching will be allowed if BAL app switching flag is not enabled, or if
-        // its app switching rule allows it.
-        // This is used to block background activity launch even if the app is still
-        // visible to user after user clicking home button.
-        final boolean appSwitchAllowed = mService.getBalAppSwitchesAllowed();
-
         // don't abort if the callingUid has a visible window or is a persistent system process
         final int callingUidProcState = mService.getUidState(callingUid);
         final boolean callingUidHasAnyVisibleWindow =
@@ -1288,8 +1269,7 @@
                 || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
         final boolean isCallingUidPersistentSystemProcess =
                 callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
-        if ((appSwitchAllowed && callingUidHasAnyVisibleWindow)
-                || isCallingUidPersistentSystemProcess) {
+        if (callingUidHasAnyVisibleWindow || isCallingUidPersistentSystemProcess) {
             if (DEBUG_ACTIVITY_STARTS) {
                 Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid
                         + ", isCallingUidPersistentSystemProcess = "
@@ -1315,7 +1295,6 @@
                         || realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
         if (realCallingUid != callingUid) {
             // don't abort if the realCallingUid has a visible window
-            // TODO(b/171459802): We should check appSwitchAllowed also
             if (realCallingUidHasAnyVisibleWindow) {
                 if (DEBUG_ACTIVITY_STARTS) {
                     Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
@@ -1397,7 +1376,7 @@
         // don't abort if the callerApp or other processes of that uid are allowed in any way
         if (callerApp != null) {
             // first check the original calling process
-            if (callerApp.areBackgroundActivityStartsAllowed(appSwitchAllowed)) {
+            if (callerApp.areBackgroundActivityStartsAllowed()) {
                 if (DEBUG_ACTIVITY_STARTS) {
                     Slog.d(TAG, "Background activity start allowed: callerApp process (pid = "
                             + callerApp.getPid() + ", uid = " + callerAppUid + ") is allowed");
@@ -1410,8 +1389,7 @@
             if (uidProcesses != null) {
                 for (int i = uidProcesses.size() - 1; i >= 0; i--) {
                     final WindowProcessController proc = uidProcesses.valueAt(i);
-                    if (proc != callerApp
-                            && proc.areBackgroundActivityStartsAllowed(appSwitchAllowed)) {
+                    if (proc != callerApp && proc.areBackgroundActivityStartsAllowed()) {
                         if (DEBUG_ACTIVITY_STARTS) {
                             Slog.d(TAG,
                                     "Background activity start allowed: process " + proc.getPid()
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 7ce8821..f649a2f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -562,4 +562,10 @@
 
     /** Set all associated companion app that belongs to an userId. */
     public abstract void setCompanionAppPackages(int userId, Set<String> companionAppPackages);
+
+    /**
+     * @param packageName The package to check
+     * @return Whether the package is the base of any locked task
+     */
+    public abstract boolean isBaseOfLockedTask(String packageName);
 }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 12c677f..581b367 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -161,11 +161,9 @@
 import android.app.admin.DevicePolicyCache;
 import android.app.assist.AssistContent;
 import android.app.assist.AssistStructure;
-import android.app.compat.CompatChanges;
 import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.EnterPipRequestedItem;
 import android.app.usage.UsageStatsManagerInternal;
-import android.compat.annotation.ChangeId;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -344,12 +342,6 @@
     /** This activity is being relaunched due to a free-resize operation. */
     public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
 
-    /**
-     * Apps are blocked from starting activities in the foreground after the user presses home.
-     */
-    @ChangeId
-    public static final long BLOCK_ACTIVITY_STARTS_AFTER_HOME = 159433730L;
-
     Context mContext;
 
     /**
@@ -2635,35 +2627,8 @@
         throw new SecurityException(msg);
     }
 
-    /**
-     * Return true if app switch protection will be handled by background activity launch logic.
-     */
-    boolean getBalAppSwitchesProtectionEnabled() {
-        return CompatChanges.isChangeEnabled(BLOCK_ACTIVITY_STARTS_AFTER_HOME);
-    }
-
-    /**
-     * Return true if app switching is allowed.
-     */
-    boolean getBalAppSwitchesAllowed() {
-        if (getBalAppSwitchesProtectionEnabled()) {
-            // Apps no longer able to start BAL again until app switching is resumed.
-            return mAppSwitchesAllowedTime == 0;
-        } else {
-            // Legacy behavior, BAL logic won't block app switching.
-            return true;
-        }
-    }
-
     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
             int callingPid, int callingUid, String name) {
-
-        // Background activity launch logic replaces app switching protection, so allow
-        // apps to start activity here now.
-        if (getBalAppSwitchesProtectionEnabled()) {
-            return true;
-        }
-
         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
             return true;
         }
@@ -4698,10 +4663,7 @@
             mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
             mLastStopAppSwitchesTime = SystemClock.uptimeMillis();
             mDidAppSwitch = false;
-            // If BAL app switching enabled, app switches are blocked not delayed.
-            if (!getBalAppSwitchesProtectionEnabled()) {
-                getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
-            }
+            getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
         }
     }
 
@@ -7456,5 +7418,13 @@
                 mCompanionAppUidsMap.put(userId, result);
             }
         }
+
+
+        @Override
+        public boolean isBaseOfLockedTask(String packageName) {
+            synchronized (mGlobalLock) {
+                return getLockTaskController().isBaseOfLockedTask(packageName);
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index e90436e..b33c2f2 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -871,6 +871,21 @@
     }
 
     /**
+     * @param packageName The package to check
+     * @return Whether the package is the base of any locked task
+     */
+    boolean isBaseOfLockedTask(String packageName) {
+        for (int i = 0; i < mLockTaskModeTasks.size(); i++) {
+            final Intent bi = mLockTaskModeTasks.get(i).getBaseIntent();
+            if (bi != null && packageName.equals(bi.getComponent()
+                    .getPackageName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
      * Gets the cached value of LockTask feature flags for a specific user.
      */
     private int getLockTaskFeaturesForUser(int userId) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index c51e63f..9273bf7 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -125,7 +125,6 @@
 import static com.android.server.wm.Task.ActivityState.PAUSING;
 import static com.android.server.wm.Task.ActivityState.RESUMED;
 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.TaskProto.ACTIVITY_TYPE;
 import static com.android.server.wm.TaskProto.BOUNDS;
@@ -4127,6 +4126,10 @@
         forAllActivities(r -> {
             info.addLaunchCookie(r.mLaunchCookie);
         });
+        final Task rootTask = getRootTask();
+        info.parentTaskId = rootTask == getParent() && rootTask.mCreatedByOrganizer
+                ? rootTask.mTaskId
+                : INVALID_TASK_ID;
     }
 
     @Nullable PictureInPictureParams getPictureInPictureParams() {
@@ -4843,6 +4846,17 @@
         return mTaskOrganizer != null;
     }
 
+    private boolean canBeOrganized() {
+        // All root tasks can be organized
+        if (isRootTask()) {
+            return true;
+        }
+
+        // Task could be organized if it's the direct child of the root created by organizer.
+        final Task rootTask = getRootTask();
+        return rootTask == getParent() && rootTask.mCreatedByOrganizer;
+    }
+
     @Override
     boolean showSurfaceOnCreation() {
         // Organized tasks handle their own surface visibility
@@ -4991,7 +5005,7 @@
             // is created.
             return false;
         }
-        if (!isRootTask()) {
+        if (!canBeOrganized()) {
             return setTaskOrganizer(null);
         }
 
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 2c39c2b..a1c5670 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);
+                }
+            });
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 084b766..c806c94 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1218,9 +1218,9 @@
         mAnimator = new WindowAnimator(this);
         mRoot = new RootWindowContainer(this);
 
-        mUseBLAST = DeviceConfig.getBoolean(
-                    DeviceConfig.NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT,
-                    WM_USE_BLAST_ADAPTER_FLAG, false);
+        final ContentResolver resolver = context.getContentResolver();
+        mUseBLAST = Settings.Global.getInt(resolver,
+            Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR, 1) == 1;
 
         mSyncEngine = new BLASTSyncEngine(this);
 
@@ -1298,7 +1298,6 @@
             }
         }, UserHandle.ALL, suspendPackagesFilter, null, null);
 
-        final ContentResolver resolver = context.getContentResolver();
         // Get persisted window scale setting
         mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver,
                 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 51857dc..7d54ea9 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -104,13 +104,55 @@
 
     @Override
     public void applyTransaction(WindowContainerTransaction t) {
-        applyTransaction(t, null /*callback*/, null /*transition*/);
+        enforceTaskPermission("applyTransaction()");
+        if (t == null) {
+            throw new IllegalArgumentException("Null transaction passed to applySyncTransaction");
+        }
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                applyTransaction(t, -1 /*syncId*/, null /*transition*/);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
     }
 
     @Override
     public int applySyncTransaction(WindowContainerTransaction t,
             IWindowContainerTransactionCallback callback) {
-        return applyTransaction(t, callback, null /*transition*/);
+        enforceTaskPermission("applySyncTransaction()");
+        if (t == null) {
+            throw new IllegalArgumentException("Null transaction passed to applySyncTransaction");
+        }
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                /**
+                 * If callback is non-null we are looking to synchronize this transaction by
+                 * collecting all the results in to a SurfaceFlinger transaction and then delivering
+                 * that to the given transaction ready callback. See {@link BLASTSyncEngine} for the
+                 * details of the operation. But at a high level we create a sync operation with a
+                 * given ID and an associated callback. Then we notify each WindowContainer in this
+                 * WindowContainer transaction that it is participating in a sync operation with
+                 * that ID. Once everything is notified we tell the BLASTSyncEngine "setSyncReady"
+                 * which means that we have added everything to the set. At any point after this,
+                 * all the WindowContainers will eventually finish applying their changes and notify
+                 * the BLASTSyncEngine which will deliver the Transaction to the callback.
+                 */
+                int syncId = -1;
+                if (callback != null) {
+                    syncId = startSyncWithOrganizer(callback);
+                }
+                applyTransaction(t, syncId, null /*transition*/);
+                if (syncId >= 0) {
+                    setSyncReady(syncId);
+                }
+                return syncId;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
     }
 
     @Override
@@ -131,7 +173,7 @@
                 if (t == null) {
                     t = new WindowContainerTransaction();
                 }
-                applyTransaction(t, null /*callback*/, transition);
+                applyTransaction(t, -1 /*syncId*/, transition);
                 return transition;
             }
         } finally {
@@ -148,10 +190,16 @@
         try {
             synchronized (mGlobalLock) {
                 int syncId = -1;
-                if (t != null) {
-                    syncId = applyTransaction(t, callback, null /*transition*/);
+                if (t != null && callback != null) {
+                    syncId = startSyncWithOrganizer(callback);
                 }
                 getTransitionController().finishTransition(transitionToken);
+                if (t != null) {
+                    applyTransaction(t, syncId, null /*transition*/);
+                }
+                if (syncId >= 0) {
+                    setSyncReady(syncId);
+                }
                 return syncId;
             }
         } finally {
@@ -160,154 +208,114 @@
     }
 
     /**
-     * @param callback If non-null, this will be a sync-transaction.
+     * @param syncId If non-null, this will be a sync-transaction.
      * @param transition A transition to collect changes into.
-     * @return a BLAST sync-id if this is a non-transition, sync transaction.
      */
-    private int applyTransaction(@NonNull WindowContainerTransaction t,
-            @Nullable IWindowContainerTransactionCallback callback,
+    private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
             @Nullable Transition transition) {
-        enforceTaskPermission("applySyncTransaction()");
-        int syncId = -1;
-        if (t == null) {
-            throw new IllegalArgumentException(
-                    "Null transaction passed to applySyncTransaction");
-        }
-        final long ident = Binder.clearCallingIdentity();
+        int effects = 0;
+        ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId);
+        mService.deferWindowLayout();
         try {
-            synchronized (mGlobalLock) {
-                int effects = 0;
-
-                /**
-                 * If callback is non-null we are looking to synchronize this transaction by
-                 * collecting all the results in to a SurfaceFlinger transaction and then delivering
-                 * that to the given transaction ready callback. See {@link BLASTSyncEngine} for the
-                 * details of the operation. But at a high level we create a sync operation with a
-                 * given ID and an associated callback. Then we notify each WindowContainer in this
-                 * WindowContainer transaction that it is participating in a sync operation with
-                 * that ID. Once everything is notified we tell the BLASTSyncEngine "setSyncReady"
-                 * which means that we have added everything to the set. At any point after this,
-                 * all the WindowContainers will eventually finish applying their changes and notify
-                 * the BLASTSyncEngine which will deliver the Transaction to the callback.
-                 */
-                if (callback != null) {
-                    syncId = startSyncWithOrganizer(callback);
+            ArraySet<WindowContainer> haveConfigChanges = new ArraySet<>();
+            Iterator<Map.Entry<IBinder, WindowContainerTransaction.Change>> entries =
+                    t.getChanges().entrySet().iterator();
+            while (entries.hasNext()) {
+                final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next();
+                final WindowContainer wc = WindowContainer.fromBinder(entry.getKey());
+                if (wc == null || !wc.isAttached()) {
+                    Slog.e(TAG, "Attempt to operate on detached container: " + wc);
+                    continue;
                 }
-                ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d",
-                        syncId);
-                mService.deferWindowLayout();
-                try {
-                    ArraySet<WindowContainer> haveConfigChanges = new ArraySet<>();
-                    Iterator<Map.Entry<IBinder, WindowContainerTransaction.Change>> entries =
-                            t.getChanges().entrySet().iterator();
-                    while (entries.hasNext()) {
-                        final Map.Entry<IBinder, WindowContainerTransaction.Change> entry =
-                                entries.next();
-                        final WindowContainer wc = WindowContainer.fromBinder(entry.getKey());
-                        if (wc == null || !wc.isAttached()) {
-                            Slog.e(TAG, "Attempt to operate on detached container: " + wc);
-                            continue;
-                        }
-                        // Make sure we add to the syncSet before performing
-                        // operations so we don't end up splitting effects between the WM
-                        // pending transaction and the BLASTSync transaction.
-                        if (syncId >= 0) {
-                            addToSyncSet(syncId, wc);
-                        }
+                // Make sure we add to the syncSet before performing
+                // operations so we don't end up splitting effects between the WM
+                // pending transaction and the BLASTSync transaction.
+                if (syncId >= 0) {
+                    addToSyncSet(syncId, wc);
+                }
 
-                        int containerEffect = applyWindowContainerChange(wc, entry.getValue());
-                        if (transition != null) transition.collect(wc);
-                        effects |= containerEffect;
+                int containerEffect = applyWindowContainerChange(wc, entry.getValue());
+                if (transition != null) transition.collect(wc);
+                effects |= containerEffect;
 
-                        // Lifecycle changes will trigger ensureConfig for everything.
-                        if ((effects & TRANSACT_EFFECTS_LIFECYCLE) == 0
-                                && (containerEffect & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
-                            haveConfigChanges.add(wc);
-                        }
-                    }
-                    // Hierarchy changes
-                    final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
-                    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()) {
-                            Slog.e(TAG, "Attempt to operate on detached container: " + wc);
-                            continue;
-                        }
-                        if (syncId >= 0) {
-                            addToSyncSet(syncId, wc);
-                        }
+                // Lifecycle changes will trigger ensureConfig for everything.
+                if ((effects & TRANSACT_EFFECTS_LIFECYCLE) == 0
+                        && (containerEffect & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
+                    haveConfigChanges.add(wc);
+                }
+            }
+            // Hierarchy changes
+            final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
+            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()) {
+                    Slog.e(TAG, "Attempt to operate on detached container: " + wc);
+                    continue;
+                }
+                if (syncId >= 0) {
+                    addToSyncSet(syncId, wc);
+                }
                         effects |= sanitizeAndApplyHierarchyOp(wc, hop);
-                        if (transition != null) {
-                            transition.collect(wc);
-                            if (hop.isReparent() && hop.getNewParent() != null) {
-                                transition.collect(WindowContainer.fromBinder(hop.getNewParent()));
-                            }
-                        }
-                    }
-                    // Queue-up bounds-change transactions for tasks which are now organized. Do
-                    // this after hierarchy ops so we have the final organized state.
-                    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 Rect surfaceBounds = entry.getValue().getBoundsChangeSurfaceBounds();
-                        if (task == null || !task.isAttached() || surfaceBounds == null) {
-                            continue;
-                        }
-                        if (!task.isOrganized()) {
-                            final Task parent =
-                                    task.getParent() != null ? task.getParent().asTask() : null;
-                            // Also allow direct children of created-by-organizer tasks to be
-                            // controlled. In the future, these will become organized anyways.
-                            if (parent == null || !parent.mCreatedByOrganizer) {
-                                throw new IllegalArgumentException(
-                                        "Can't manipulate non-organized task surface " + task);
-                            }
-                        }
-                        final SurfaceControl.Transaction sft = new SurfaceControl.Transaction();
-                        final SurfaceControl sc = task.getSurfaceControl();
-                        sft.setPosition(sc, surfaceBounds.left, surfaceBounds.top);
-                        if (surfaceBounds.isEmpty()) {
-                            sft.setWindowCrop(sc, null);
-                        } else {
-                            sft.setWindowCrop(sc, surfaceBounds.width(), surfaceBounds.height());
-                        }
-                        task.setMainWindowSizeChangeTransaction(sft);
-                    }
-                    if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) {
-                        // Already calls ensureActivityConfig
-                        mService.mRootWindowContainer.ensureActivitiesVisible(
-                                null, 0, PRESERVE_WINDOWS);
-                    } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
-                        final PooledConsumer f = PooledLambda.obtainConsumer(
-                                ActivityRecord::ensureActivityConfiguration,
-                                PooledLambda.__(ActivityRecord.class), 0,
-                                true /* preserveWindow */);
-                        try {
-                            for (int i = haveConfigChanges.size() - 1; i >= 0; --i) {
-                                haveConfigChanges.valueAt(i).forAllActivities(f);
-                            }
-                        } finally {
-                            f.recycle();
-                        }
-                    }
-
-                    if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) == 0) {
-                        mService.addWindowLayoutReasons(LAYOUT_REASON_CONFIG_CHANGED);
-                    }
-                } finally {
-                    mService.continueWindowLayout();
-                    if (syncId >= 0) {
-                        setSyncReady(syncId);
+                if (transition != null) {
+                    transition.collect(wc);
+                    if (hop.isReparent() && hop.getNewParent() != null) {
+                        transition.collect(WindowContainer.fromBinder(hop.getNewParent()));
                     }
                 }
             }
+            // Queue-up bounds-change transactions for tasks which are now organized. Do
+            // this after hierarchy ops so we have the final organized state.
+            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 Rect surfaceBounds = entry.getValue().getBoundsChangeSurfaceBounds();
+                if (task == null || !task.isAttached() || surfaceBounds == null) {
+                    continue;
+                }
+                if (!task.isOrganized()) {
+                    final Task parent = task.getParent() != null ? task.getParent().asTask() : null;
+                    // Also allow direct children of created-by-organizer tasks to be
+                    // controlled. In the future, these will become organized anyways.
+                    if (parent == null || !parent.mCreatedByOrganizer) {
+                        throw new IllegalArgumentException(
+                                "Can't manipulate non-organized task surface " + task);
+                    }
+                }
+                final SurfaceControl.Transaction sft = new SurfaceControl.Transaction();
+                final SurfaceControl sc = task.getSurfaceControl();
+                sft.setPosition(sc, surfaceBounds.left, surfaceBounds.top);
+                if (surfaceBounds.isEmpty()) {
+                    sft.setWindowCrop(sc, null);
+                } else {
+                    sft.setWindowCrop(sc, surfaceBounds.width(), surfaceBounds.height());
+                }
+                task.setMainWindowSizeChangeTransaction(sft);
+            }
+            if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) {
+                // Already calls ensureActivityConfig
+                mService.mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
+            } else if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
+                final PooledConsumer f = PooledLambda.obtainConsumer(
+                        ActivityRecord::ensureActivityConfiguration,
+                        PooledLambda.__(ActivityRecord.class), 0,
+                        true /* preserveWindow */);
+                try {
+                    for (int i = haveConfigChanges.size() - 1; i >= 0; --i) {
+                        haveConfigChanges.valueAt(i).forAllActivities(f);
+                    }
+                } finally {
+                    f.recycle();
+                }
+            }
+
+            if ((effects & TRANSACT_EFFECTS_CLIENT_CONFIG) == 0) {
+                mService.addWindowLayoutReasons(LAYOUT_REASON_CONFIG_CHANGED);
+            }
         } finally {
-            Binder.restoreCallingIdentity(ident);
+            mService.continueWindowLayout();
         }
-        return syncId;
     }
 
     private int applyChanges(WindowContainer container, WindowContainerTransaction.Change change) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 2d69dcb..2e7905c 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -505,33 +505,29 @@
         }
     }
 
-    boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed) {
-        // If app switching is not allowed, we ignore all the start activity grace period
-        // exception so apps cannot start itself in onPause() after pressing home button.
-        if (appSwitchAllowed) {
-            // allow if any activity in the caller has either started or finished very recently, and
-            // it must be started or finished after last stop app switches time.
-            final long now = SystemClock.uptimeMillis();
-            if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
-                    || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
-                // if activity is started and finished before stop app switch time, we should not
-                // let app to be able to start background activity even it's in grace period.
-                if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
-                        || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
-                    if (DEBUG_ACTIVITY_STARTS) {
-                        Slog.d(TAG, "[WindowProcessController(" + mPid
-                                + ")] Activity start allowed: within "
-                                + ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period");
-                    }
-                    return true;
-                }
+    boolean areBackgroundActivityStartsAllowed() {
+        // allow if any activity in the caller has either started or finished very recently, and
+        // it must be started or finished after last stop app switches time.
+        final long now = SystemClock.uptimeMillis();
+        if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
+                || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
+            // if activity is started and finished before stop app switch time, we should not
+            // let app to be able to start background activity even it's in grace period.
+            if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
+                    || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
                 if (DEBUG_ACTIVITY_STARTS) {
-                    Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start within "
-                            + ACTIVITY_BG_START_GRACE_PERIOD_MS
-                            + "ms grace period but also within stop app switch window");
+                    Slog.d(TAG, "[WindowProcessController(" + mPid
+                            + ")] Activity start allowed: within "
+                            + ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period");
                 }
-
+                return true;
             }
+            if (DEBUG_ACTIVITY_STARTS) {
+                Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start within "
+                        + ACTIVITY_BG_START_GRACE_PERIOD_MS
+                        + "ms grace period but also within stop app switch window");
+            }
+
         }
         // allow if the proc is instrumenting with background activity starts privs
         if (mInstrumentingWithBackgroundActivityStartPrivileges) {
@@ -543,7 +539,7 @@
             return true;
         }
         // allow if the caller has an activity in any foreground task
-        if (appSwitchAllowed && hasActivityInVisibleTask()) {
+        if (hasActivityInVisibleTask()) {
             if (DEBUG_ACTIVITY_STARTS) {
                 Slog.d(TAG, "[WindowProcessController(" + mPid
                         + ")] Activity start allowed: process has activity in foreground task");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ab2f424..9234390 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -421,6 +421,7 @@
 
     // Current transformation being applied.
     float mGlobalScale=1;
+    float mLastGlobalScale=1;
     float mInvGlobalScale=1;
     float mHScale=1, mVScale=1;
     float mLastHScale=1, mLastVScale=1;
@@ -5301,6 +5302,14 @@
         }
     }
 
+    private void updateGlobalScaleIfNeeded() {
+        if (mLastGlobalScale != mGlobalScale) {
+            getPendingTransaction().setMatrix(getSurfaceControl(),
+                mGlobalScale, 0, 0, mGlobalScale);
+            mLastGlobalScale = mGlobalScale;
+        }
+    }
+
     @Override
     void prepareSurfaces() {
         mIsDimming = false;
@@ -5308,6 +5317,7 @@
         updateSurfacePositionNonOrganized();
         // Send information to SufaceFlinger about the priority of the current window.
         updateFrameRateSelectionPriorityIfNeeded();
+        updateGlobalScaleIfNeeded();
 
         mWinAnimator.prepareSurfaceLocked(SurfaceControl.getGlobalTransaction(), true);
         super.prepareSurfaces();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 1e959e5..d845b12 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -624,10 +624,10 @@
 
         mShownAlpha = mAlpha;
         mHaveMatrix = false;
-        mDsDx = mWin.mGlobalScale;
+        mDsDx = 1;
         mDtDx = 0;
         mDtDy = 0;
-        mDsDy = mWin.mGlobalScale;
+        mDsDy = 1;
     }
 
     private boolean shouldConsumeMainWindowSizeTransaction() {
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/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4d553e2..3bfcb6d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4255,18 +4255,18 @@
                         mInjector.getPackageManager().getPackagesForUid(
                                 mInjector.binderGetCallingUid()))
                 .write();
-        final int callingUserId = mInjector.userHandleGetCallingUserId();
+        final CallerIdentity caller = getCallerIdentity();
 
-        if (parent) {
-            enforceProfileOwnerOrSystemUser();
-        }
-        enforceUserUnlocked(callingUserId);
+        Preconditions.checkCallAuthorization(!parent || (isDeviceOwner(caller)
+                        || isProfileOwner(caller) || isSystemUid(caller)),
+                "Only profile owner, device owner and system may call this method.");
+        enforceUserUnlocked(caller.getUserId());
         mContext.enforceCallingOrSelfPermission(
                 REQUEST_PASSWORD_COMPLEXITY,
                 "Must have " + REQUEST_PASSWORD_COMPLEXITY + " permission.");
 
         synchronized (getLockObject()) {
-            final int credentialOwner = getCredentialOwner(callingUserId, parent);
+            final int credentialOwner = getCredentialOwner(caller.getUserId(), parent);
             PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
             return metrics == null ? PASSWORD_COMPLEXITY_NONE : metrics.determineComplexity();
         }
@@ -7299,7 +7299,8 @@
 
     @Override
     public boolean hasDeviceOwner() {
-        enforceDeviceOwnerOrManageUsers();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || canManageUsers(caller));
         return mOwners.hasDeviceOwner();
     }
 
@@ -8355,32 +8356,6 @@
                 || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS);
     }
 
-    private void enforceDeviceOwnerOrManageUsers() {
-        final CallerIdentity caller = getCallerIdentity();
-        if (isDeviceOwner(caller)) {
-            return;
-        }
-        Preconditions.checkCallAuthorization(canManageUsers(caller));
-    }
-
-    private void enforceProfileOwnerOrSystemUser() {
-        final CallerIdentity caller = getCallerIdentity();
-        if (isDeviceOwner(caller) || isProfileOwner(caller)) {
-            return;
-        }
-        Preconditions.checkState(isSystemUid(caller),
-                "Only profile owner, device owner and system may call this method.");
-    }
-
-    private void enforceProfileOwnerOrFullCrossUsersPermission(CallerIdentity caller,
-            int userId) {
-        if ((userId == caller.getUserId()) && (isProfileOwner(caller) || isDeviceOwner(caller))) {
-            // Device Owner/Profile Owner may access the user it runs on.
-            return;
-        }
-        Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId));
-    }
-
     private boolean canUserUseLockTaskLocked(int userId) {
         if (isUserAffiliatedWithDeviceLocked(userId)) {
             return true;
@@ -12458,7 +12433,8 @@
         if (!mHasFeature) {
             return null;
         }
-        enforceDeviceOwnerOrManageUsers();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || canManageUsers(caller));
         synchronized (getLockObject()) {
             final ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdminLocked();
             return deviceOwnerAdmin == null ? null : deviceOwnerAdmin.organizationName;
@@ -13605,19 +13581,22 @@
 
     @Override
     public long getLastSecurityLogRetrievalTime() {
-        enforceDeviceOwnerOrManageUsers();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || canManageUsers(caller));
         return getUserData(UserHandle.USER_SYSTEM).mLastSecurityLogRetrievalTime;
      }
 
     @Override
     public long getLastBugReportRequestTime() {
-        enforceDeviceOwnerOrManageUsers();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || canManageUsers(caller));
         return getUserData(UserHandle.USER_SYSTEM).mLastBugReportRequestTime;
      }
 
     @Override
     public long getLastNetworkLogRetrievalTime() {
-        enforceDeviceOwnerOrManageUsers();
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isDeviceOwner(caller) || canManageUsers(caller));
         return getUserData(UserHandle.USER_SYSTEM).mLastNetworkLogsRetrievalTime;
     }
 
@@ -13721,15 +13700,21 @@
 
     @Override
     public boolean isCurrentInputMethodSetByOwner() {
-        enforceProfileOwnerOrSystemUser();
-        return getUserData(mInjector.userHandleGetCallingUserId()).mCurrentInputMethodSet;
+        final CallerIdentity caller = getCallerIdentity();
+        Preconditions.checkCallAuthorization(isDeviceOwner(caller)
+                || isProfileOwner(caller) || isSystemUid(caller),
+                "Only profile owner, device owner and system may call this method.");
+        return getUserData(caller.getUserId()).mCurrentInputMethodSet;
     }
 
     @Override
     public StringParceledListSlice getOwnerInstalledCaCerts(@NonNull UserHandle user) {
         final int userId = user.getIdentifier();
         final CallerIdentity caller = getCallerIdentity();
-        enforceProfileOwnerOrFullCrossUsersPermission(caller, userId);
+        Preconditions.checkCallAuthorization((userId == caller.getUserId())
+                || isProfileOwner(caller) || isDeviceOwner(caller)
+                || hasFullCrossUsersPermission(caller, userId));
+
         synchronized (getLockObject()) {
             return new StringParceledListSlice(
                     new ArrayList<>(getUserData(userId).mOwnerInstalledCaCerts));
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 03edc58..267c9b7 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1266,6 +1266,12 @@
             inputManager = new InputManagerService(context);
             t.traceEnd();
 
+            if (!disableCameraService) {
+                t.traceBegin("StartCameraServiceProxy");
+                mSystemServiceManager.startService(CameraServiceProxy.class);
+                t.traceEnd();
+            }
+
             t.traceBegin("StartWindowManagerService");
             // WMS needs sensor service ready
             ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
@@ -2200,12 +2206,6 @@
             t.traceEnd();
         }
 
-        if (!disableCameraService) {
-            t.traceBegin("StartCameraServiceProxy");
-            mSystemServiceManager.startService(CameraServiceProxy.class);
-            t.traceEnd();
-        }
-
         if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_EMBEDDED)) {
             t.traceBegin("StartIoTSystemService");
             mSystemServiceManager.startService(IOT_SERVICE_CLASS);
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 e17358d..7ae2fe0 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,11 +17,8 @@
 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)
@@ -40,7 +37,8 @@
     @Before
     @After
     fun removeApk() {
-        device.uninstallPackage(TEST_PKG_NAME)
+        HostUtils.deleteAllTestPackages(device, preparer)
+        device.uninstallPackage(DEVICE_SIDE_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 9399030..f0b60f4 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,6 +23,15 @@
 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())
@@ -89,12 +98,25 @@
 
 internal object HostUtils {
 
-    fun getDataDir(device: ITestDevice, pkgName: String) =
-            device.executeShellCommand("dumpsys package $pkgName")
-                    .lineSequence()
-                    .map(String::trim)
-                    .single { it.startsWith("dataDir=") }
-                    .removePrefix("dataDir=")
+    /**
+     * 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 makePathForApk(fileName: String, partition: Partition) =
             makePathForApk(File(fileName), partition)
@@ -136,14 +158,35 @@
             }
             .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) =
-            device.executeShellCommand("pm dump $pkgName")
-                    .lineSequence()
-                    .map(String::trim)
+            (packageSection(device, pkgName) +
+                    packageSection(device, pkgName, "Hidden system packages"))
                     .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 37c999c..8594706 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,12 +33,6 @@
 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)
     }
@@ -55,7 +49,7 @@
     @Before
     @After
     fun removeApk() {
-        device.uninstallPackage(TEST_PKG_NAME)
+        HostUtils.deleteAllTestPackages(device, preparer)
         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 4becae6..0c5816b 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,10 +34,6 @@
 
     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)
@@ -54,9 +50,7 @@
     @Before
     @After
     fun deleteApkFolders() {
-        preparer.deleteApkFolders(Partition.SYSTEM, VERSION_ONE, VERSION_TWO, VERSION_THREE,
-                NEW_PKG)
-                .reboot()
+        HostUtils.deleteAllTestPackages(device, preparer)
     }
 
     @Test
@@ -89,10 +83,10 @@
         device.pushFile(file, "${HostUtils.getDataDir(device, TEST_PKG_NAME)}/files/test.txt")
 
         preparer.deleteApkFolders(Partition.SYSTEM, apk)
-                .pushApk(NEW_PKG, Partition.SYSTEM)
+                .pushApk(VERSION_OVERRIDE, Partition.SYSTEM)
                 .reboot()
 
-        assertCodePath(NEW_PKG)
+        assertCodePath(VERSION_OVERRIDE)
 
         // 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
new file mode 100644
index 0000000..8d789e0
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SystemAppScanPriorityTest.kt
@@ -0,0 +1,272 @@
+/*
+ * 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 46120af..99dff08 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,9 +37,6 @@
 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
@@ -90,6 +87,12 @@
                 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/servicestests/src/com/android/server/appsearch/external/localbackend/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
similarity index 99%
rename from services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/AppSearchImplTest.java
rename to services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
index 081bfb5..0d0ac6d 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/AppSearchImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/AppSearchImplTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.appsearch.external.localbackend;
+package com.android.server.appsearch.external.localstorage;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
similarity index 86%
rename from services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverterTest.java
rename to services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
index a95290d..85d4f01 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/converter/GenericDocumentToProtoConverterTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/GenericDocumentToProtoConverterTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.appsearch.external.localbackend.converter;
+package com.android.server.appsearch.external.localstorage.converter;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -53,13 +53,13 @@
                         .setScore(1)
                         .setTtlMillis(1L)
                         .setNamespace("namespace")
-                        .setProperty("longKey1", 1L)
-                        .setProperty("doubleKey1", 1.0)
-                        .setProperty("booleanKey1", true)
-                        .setProperty("stringKey1", "test-value1")
-                        .setProperty("byteKey1", BYTE_ARRAY_1, BYTE_ARRAY_2)
-                        .setProperty("documentKey1", DOCUMENT_PROPERTIES_1)
-                        .setProperty(GenericDocument.PROPERTIES_FIELD, DOCUMENT_PROPERTIES_2)
+                        .setPropertyLong("longKey1", 1L)
+                        .setPropertyDouble("doubleKey1", 1.0)
+                        .setPropertyBoolean("booleanKey1", true)
+                        .setPropertyString("stringKey1", "test-value1")
+                        .setPropertyBytes("byteKey1", BYTE_ARRAY_1, BYTE_ARRAY_2)
+                        .setPropertyDocument("documentKey1", DOCUMENT_PROPERTIES_1)
+                        .setPropertyDocument("documentKey2", DOCUMENT_PROPERTIES_2)
                         .build();
 
         // Create the Document proto. Need to sort the property order by key.
@@ -87,8 +87,8 @@
                 PropertyProto.newBuilder().setName("documentKey1")
                         .addDocumentValues(
                                 GenericDocumentToProtoConverter.convert(DOCUMENT_PROPERTIES_1)));
-        propertyProtoMap.put(GenericDocument.PROPERTIES_FIELD,
-                PropertyProto.newBuilder().setName(GenericDocument.PROPERTIES_FIELD)
+        propertyProtoMap.put("documentKey2",
+                PropertyProto.newBuilder().setName("documentKey2")
                         .addDocumentValues(
                                 GenericDocumentToProtoConverter.convert(DOCUMENT_PROPERTIES_2)));
         List<String> sortedKey = new ArrayList<>(propertyProtoMap.keySet());
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverterTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
similarity index 96%
rename from services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverterTest.java
rename to services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
index 8b2fd1c..7336c3c 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SchemaToProtoConverterTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SchemaToProtoConverterTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.appsearch.external.localbackend.converter;
+package com.android.server.appsearch.external.localstorage.converter;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -50,7 +50,6 @@
                 .addProperties(PropertyConfigProto.newBuilder()
                         .setPropertyName("subject")
                         .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                        .setSchemaType("")
                         .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
                         .setIndexingConfig(
                                 com.android.server.appsearch.proto.IndexingConfig.newBuilder()
@@ -60,7 +59,6 @@
                 ).addProperties(PropertyConfigProto.newBuilder()
                         .setPropertyName("body")
                         .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                        .setSchemaType("")
                         .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
                         .setIndexingConfig(
                                 com.android.server.appsearch.proto.IndexingConfig.newBuilder()
@@ -94,7 +92,6 @@
                 .addProperties(PropertyConfigProto.newBuilder()
                         .setPropertyName("artist")
                         .setDataType(PropertyConfigProto.DataType.Code.STRING)
-                        .setSchemaType("")
                         .setCardinality(PropertyConfigProto.Cardinality.Code.REPEATED)
                         .setIndexingConfig(
                                 com.android.server.appsearch.proto.IndexingConfig.newBuilder()
@@ -104,7 +101,6 @@
                 ).addProperties(PropertyConfigProto.newBuilder()
                         .setPropertyName("pubDate")
                         .setDataType(PropertyConfigProto.DataType.Code.INT64)
-                        .setSchemaType("")
                         .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
                         .setIndexingConfig(
                                 com.android.server.appsearch.proto.IndexingConfig.newBuilder()
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SnippetTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
similarity index 98%
rename from services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SnippetTest.java
rename to services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
index e9357aa..d5762a1 100644
--- a/services/tests/servicestests/src/com/android/server/appsearch/external/localbackend/converter/SnippetTest.java
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/converter/SnippetTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.appsearch.external.localbackend.converter;
+package com.android.server.appsearch.external.localstorage.converter;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -123,7 +123,7 @@
 
         for (SearchResultProto.ResultProto proto : searchResultProto.getResultsList()) {
             SearchResult result = SearchResultToProtoConverter.convertSearchResult(proto);
-            assertThat(result.getMatches()).isEqualTo(null);
+            assertThat(result.getMatches()).isEmpty();
         }
     }
 
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 7a0d894..b73a783 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
@@ -46,6 +46,10 @@
     private Face10 mFace10;
     private IBinder mBinder;
 
+    private static void waitForIdle() {
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+    }
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -59,11 +63,8 @@
 
     @Test
     public void scheduleRevokeChallenge_doesNotCrash() {
-        mFace10.scheduleRevokeChallenge(mBinder, TAG);
+        mFace10.scheduleRevokeChallenge(0 /* sensorId */, 0 /* userId */, mBinder, TAG,
+                0 /* challenge */);
         waitForIdle();
     }
-
-    private static void waitForIdle() {
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java
index be05245..9660d6b 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java
@@ -15,33 +15,33 @@
  */
 package com.android.server.devicepolicy;
 
-import android.test.AndroidTestCase;
+import static com.google.common.truth.Truth.assertThat;
+
 import android.test.suitebuilder.annotation.SmallTest;
 
+import org.junit.Test;
+
 /**
  * Test for {@link DevicePolicyConstants}.
  *
- m FrameworksServicesTests &&
- adb install \
- -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
- adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyConstantsTest \
- -w com.android.frameworks.servicestests
-
-
- -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
+ * <p>Run this test with:
+ *
+ * {@code atest FrameworksServicesTests:com.android.server.devicepolicy.DevicePolicyConstantsTest}
  */
 @SmallTest
-public class DevicePolicyConstantsTest extends AndroidTestCase {
+public class DevicePolicyConstantsTest {
     private static final String TAG = "DevicePolicyConstantsTest";
 
+    @Test
     public void testDefaultValues() throws Exception {
         final DevicePolicyConstants constants = DevicePolicyConstants.loadFromString("");
 
-        assertEquals(1 * 60 * 60, constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC);
-        assertEquals(24 * 60 * 60, constants.DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC);
-        assertEquals(2.0, constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE);
+        assertThat(constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC).isEqualTo(1 * 60 * 60);
+        assertThat(constants.DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC).isEqualTo(24 * 60 * 60);
+        assertThat(constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE).isWithin(1.0e-10).of(2.0);
     }
 
+    @Test
     public void testCustomValues() throws Exception {
         final DevicePolicyConstants constants = DevicePolicyConstants.loadFromString(
                 "das_died_service_reconnect_backoff_sec=10,"
@@ -49,11 +49,13 @@
                 + "das_died_service_reconnect_max_backoff_sec=15"
         );
 
-        assertEquals(10, constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC);
-        assertEquals(15, constants.DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC);
-        assertEquals(1.25, constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE);
+        assertThat(constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC).isEqualTo(10);
+        assertThat(constants.DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC).isEqualTo(15);
+        assertThat(constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE).isWithin(1.0e-10)
+                .of(1.25);
     }
 
+    @Test
     public void testMinMax() throws Exception {
         final DevicePolicyConstants constants = DevicePolicyConstants.loadFromString(
                 "das_died_service_reconnect_backoff_sec=3,"
@@ -61,8 +63,8 @@
                         + "das_died_service_reconnect_max_backoff_sec=1"
         );
 
-        assertEquals(5, constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC);
-        assertEquals(5, constants.DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC);
-        assertEquals(1.0, constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE);
+        assertThat(constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC).isEqualTo(5);
+        assertThat(constants.DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC).isEqualTo(5);
+        assertThat(constants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE).isWithin(1.0e-10).of(1.0);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyEventLoggerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyEventLoggerTest.java
index b24bca8..350b390 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyEventLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyEventLoggerTest.java
@@ -46,8 +46,8 @@
                 .setTimePeriod(1234L);
         assertThat(eventLogger.getEventId()).isEqualTo(5);
         assertThat(eventLogger.getBoolean()).isTrue();
-        assertThat(eventLogger.getStringArray())
-                .isEqualTo(new String[] {"string1", "string2", "string3"});
+        assertThat(eventLogger.getStringArray()).asList()
+            .containsExactly("string1", "string2", "string3");
         assertThat(eventLogger.getAdminPackageName()).isEqualTo("com.test.package");
         assertThat(eventLogger.getInt()).isEqualTo(4321);
         assertThat(eventLogger.getTimePeriod()).isEqualTo(1234L);
@@ -57,23 +57,22 @@
     public void testStrings() {
         assertThat(DevicePolicyEventLogger
                 .createEvent(0)
-                .setStrings("string1", "string2", "string3").getStringArray())
-                .isEqualTo(new String[] {"string1", "string2", "string3"});
+                .setStrings("string1", "string2", "string3").getStringArray()).asList()
+                        .containsExactly("string1", "string2", "string3").inOrder();
 
         assertThat(DevicePolicyEventLogger
                 .createEvent(0)
                 .setStrings("string1", new String[] {"string2", "string3"}).getStringArray())
-                .isEqualTo(new String[] {"string1", "string2", "string3"});
+                        .asList().containsExactly("string1", "string2", "string3").inOrder();
 
         assertThat(DevicePolicyEventLogger
                 .createEvent(0)
                 .setStrings("string1", "string2", new String[] {"string3"}).getStringArray())
-                .isEqualTo(new String[] {"string1", "string2", "string3"});
-
+                        .asList().containsExactly("string1", "string2", "string3").inOrder();
         assertThat(DevicePolicyEventLogger
                 .createEvent(0)
-                .setStrings((String) null).getStringArray())
-                .isEqualTo(new String[] {null});
+                .setStrings((String) null).getStringArray()).asList()
+                        .containsExactly((String) null);
 
         assertThat(DevicePolicyEventLogger
                 .createEvent(0)
@@ -106,8 +105,8 @@
                 .createEvent(0);
         assertThat(eventLogger.getEventId()).isEqualTo(0);
         assertThat(eventLogger.getBoolean()).isFalse();
-        assertThat(eventLogger.getStringArray()).isEqualTo(null);
-        assertThat(eventLogger.getAdminPackageName()).isEqualTo(null);
+        assertThat(eventLogger.getStringArray()).isNull();
+        assertThat(eventLogger.getAdminPackageName()).isNull();
         assertThat(eventLogger.getInt()).isEqualTo(0);
         assertThat(eventLogger.getTimePeriod()).isEqualTo(0L);
     }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
index 3167820..fa3f45c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java
@@ -20,7 +20,9 @@
 import static com.android.server.devicepolicy.DpmTestUtils.writeInputStreamToFile;
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
-import static org.junit.Assert.assertArrayEquals;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
@@ -43,17 +45,23 @@
 import android.provider.Settings;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.frameworks.servicestests.R;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
 @Presubmit
+@RunWith(AndroidJUnit4.class)
 public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase {
 
     private static final String USER_TYPE_EMPTY = "";
@@ -63,9 +71,8 @@
 
     private DpmMockContext mContext;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
 
         mContext = getContext();
 
@@ -77,6 +84,7 @@
                 .thenReturn(true);
     }
 
+    @Test
     public void testMigration() throws Exception {
         final File user10dir = getServices().addUser(10, 0, USER_TYPE_EMPTY);
         final File user11dir = getServices().addUser(11, 0,
@@ -160,19 +168,19 @@
             mContext.binder.restoreCallingIdentity(ident);
         }
 
-        assertTrue(dpms.mOwners.hasDeviceOwner());
-        assertFalse(dpms.mOwners.hasProfileOwner(USER_SYSTEM));
-        assertTrue(dpms.mOwners.hasProfileOwner(10));
-        assertTrue(dpms.mOwners.hasProfileOwner(11));
-        assertFalse(dpms.mOwners.hasProfileOwner(12));
+        assertThat(dpms.mOwners.hasDeviceOwner()).isTrue();
+        assertThat(dpms.mOwners.hasProfileOwner(USER_SYSTEM)).isFalse();
+        assertThat(dpms.mOwners.hasProfileOwner(10)).isTrue();
+        assertThat(dpms.mOwners.hasProfileOwner(11)).isTrue();
+        assertThat(dpms.mOwners.hasProfileOwner(12)).isFalse();
 
         // Now all information should be migrated.
-        assertFalse(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration());
-        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(
-                USER_SYSTEM));
-        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(12));
+        assertThat(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+        assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(USER_SYSTEM))
+            .isFalse();
+        assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
+        assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+        assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(12)).isFalse();
 
         // Check the new base restrictions.
         DpmTestUtils.assertRestrictions(
@@ -221,6 +229,7 @@
                 dpms.getProfileOwnerAdminLocked(11).ensureUserRestrictions());
     }
 
+    @Test
     public void testMigration2_profileOwnerOnUser0() throws Exception {
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
 
@@ -271,13 +280,13 @@
         } finally {
             mContext.binder.restoreCallingIdentity(ident);
         }
-        assertFalse(dpms.mOwners.hasDeviceOwner());
-        assertTrue(dpms.mOwners.hasProfileOwner(USER_SYSTEM));
+        assertThat(dpms.mOwners.hasDeviceOwner()).isFalse();
+        assertThat(dpms.mOwners.hasProfileOwner(USER_SYSTEM)).isTrue();
 
         // Now all information should be migrated.
-        assertFalse(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration());
-        assertFalse(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(
-                USER_SYSTEM));
+        assertThat(dpms.mOwners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+        assertThat(dpms.mOwners.getProfileOwnerUserRestrictionsNeedsMigration(USER_SYSTEM))
+            .isFalse();
 
         // Check the new base restrictions.
         DpmTestUtils.assertRestrictions(
@@ -297,6 +306,7 @@
     }
 
     // Test setting default restrictions for managed profile.
+    @Test
     public void testMigration3_managedProfileOwner() throws Exception {
         // Create a managed profile user.
         final File user10dir = getServices().addUser(10, 0,
@@ -339,8 +349,8 @@
             mContext.binder.restoreCallingIdentity(ident);
         }
 
-        assertFalse(dpms.mOwners.hasDeviceOwner());
-        assertTrue(dpms.mOwners.hasProfileOwner(10));
+        assertThat(dpms.mOwners.hasDeviceOwner()).isFalse();
+        assertThat(dpms.mOwners.hasProfileOwner(10)).isTrue();
 
         // Check that default restrictions were applied.
         DpmTestUtils.assertRestrictions(
@@ -352,11 +362,12 @@
 
         final Set<String> alreadySet =
                 dpms.getProfileOwnerAdminLocked(10).defaultEnabledRestrictionsAlreadySet;
-        assertEquals(alreadySet.size(), 1);
-        assertTrue(alreadySet.contains(UserManager.DISALLOW_BLUETOOTH_SHARING));
+        assertThat(alreadySet).hasSize(1);
+        assertThat(alreadySet.contains(UserManager.DISALLOW_BLUETOOTH_SHARING)).isTrue();
     }
 
     @SmallTest
+    @Test
     public void testCompMigrationUnAffiliated_skipped() throws Exception {
         prepareAdmin1AsDo();
         prepareAdminAnotherPackageAsPo(COPE_PROFILE_USER_ID);
@@ -364,10 +375,11 @@
         final DevicePolicyManagerServiceTestable dpms = bootDpmsUp();
 
         // DO should still be DO since no migration should happen.
-        assertTrue(dpms.mOwners.hasDeviceOwner());
+        assertThat(dpms.mOwners.hasDeviceOwner()).isTrue();
     }
 
     @SmallTest
+    @Test
     public void testCompMigrationAffiliated() throws Exception {
         prepareAdmin1AsDo();
         prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.R);
@@ -378,48 +390,54 @@
         final DevicePolicyManagerServiceTestable dpms = bootDpmsUp();
 
         // DO should cease to be DO.
-        assertFalse(dpms.mOwners.hasDeviceOwner());
+        assertThat(dpms.mOwners.hasDeviceOwner()).isFalse();
 
         final DpmMockContext poContext = new DpmMockContext(getServices(), mRealTestContext);
         poContext.binder.callingUid = UserHandle.getUid(COPE_PROFILE_USER_ID, COPE_ADMIN1_APP_ID);
 
         runAsCaller(poContext, dpms, dpm -> {
-            assertEquals("Password history policy wasn't migrated to PO parent instance",
-                    33, dpm.getParentProfileInstance(admin1).getPasswordHistoryLength(admin1));
-            assertEquals("Password history policy was put into non-parent PO instance",
-                    0, dpm.getPasswordHistoryLength(admin1));
-            assertTrue("Screen capture restriction wasn't migrated to PO parent instance",
-                    dpm.getParentProfileInstance(admin1).getScreenCaptureDisabled(admin1));
+            assertWithMessage("Password history policy wasn't migrated to PO parent instance")
+                    .that(dpm.getParentProfileInstance(admin1).getPasswordHistoryLength(admin1))
+                    .isEqualTo(33);
+            assertWithMessage("Password history policy was put into non-parent PO instance")
+                    .that(dpm.getPasswordHistoryLength(admin1)).isEqualTo(0);
+            assertWithMessage("Screen capture restriction wasn't migrated to PO parent instance")
+                    .that(dpm.getParentProfileInstance(admin1).getScreenCaptureDisabled(admin1))
+                    .isTrue();
 
-            assertArrayEquals("Accounts with management disabled weren't migrated to PO parent",
-                    new String[] {"com.google-primary"},
-                    dpm.getParentProfileInstance(admin1).getAccountTypesWithManagementDisabled());
-            assertArrayEquals("Accounts with management disabled for profile were lost",
-                    new String[] {"com.google-profile"},
-                    dpm.getAccountTypesWithManagementDisabled());
+            assertWithMessage("Accounts with management disabled weren't migrated to PO parent")
+                    .that(dpm.getParentProfileInstance(admin1)
+                            .getAccountTypesWithManagementDisabled()).asList()
+                    .containsExactly("com.google-primary");
 
-            assertTrue("User restriction wasn't migrated to PO parent instance",
-                    dpm.getParentProfileInstance(admin1).getUserRestrictions(admin1)
-                            .containsKey(UserManager.DISALLOW_BLUETOOTH));
-            assertFalse("User restriction was put into non-parent PO instance",
-                    dpm.getUserRestrictions(admin1).containsKey(UserManager.DISALLOW_BLUETOOTH));
+            assertWithMessage("Accounts with management disabled for profile were lost")
+                    .that(dpm.getAccountTypesWithManagementDisabled()).asList()
+                    .containsExactly("com.google-profile");
 
-            assertTrue("User restriction wasn't migrated to PO parent instance",
-                    dpms.getProfileOwnerAdminLocked(COPE_PROFILE_USER_ID)
-                            .getParentActiveAdmin()
-                            .getEffectiveRestrictions()
-                            .containsKey(UserManager.DISALLOW_CONFIG_DATE_TIME));
-            assertFalse("User restriction was put into non-parent PO instance",
-                    dpms.getProfileOwnerAdminLocked(COPE_PROFILE_USER_ID)
-                            .getEffectiveRestrictions()
-                            .containsKey(UserManager.DISALLOW_CONFIG_DATE_TIME));
-            assertEquals("Personal apps suspension wasn't migrated",
-                    DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED,
-                    dpm.getPersonalAppsSuspendedReasons(admin1));
+            assertWithMessage("User restriction wasn't migrated to PO parent instance")
+                    .that(dpm.getParentProfileInstance(admin1).getUserRestrictions(admin1).keySet())
+                    .contains(UserManager.DISALLOW_BLUETOOTH);
+
+            assertWithMessage("User restriction was put into non-parent PO instance").that(
+                    dpm.getUserRestrictions(admin1).keySet())
+                    .doesNotContain(UserManager.DISALLOW_BLUETOOTH);
+
+            assertWithMessage("User restriction wasn't migrated to PO parent instance")
+                    .that(dpms.getProfileOwnerAdminLocked(COPE_PROFILE_USER_ID)
+                            .getParentActiveAdmin().getEffectiveRestrictions().keySet())
+                    .contains(UserManager.DISALLOW_CONFIG_DATE_TIME);
+            assertWithMessage("User restriction was put into non-parent PO instance")
+                    .that(dpms.getProfileOwnerAdminLocked(COPE_PROFILE_USER_ID)
+                            .getEffectiveRestrictions().keySet())
+                    .doesNotContain(UserManager.DISALLOW_CONFIG_DATE_TIME);
+            assertWithMessage("Personal apps suspension wasn't migrated")
+                    .that(dpm.getPersonalAppsSuspendedReasons(admin1))
+                    .isEqualTo(DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED);
         });
     }
 
     @SmallTest
+    @Test
     public void testCompMigration_keepSuspendedAppsWhenDpcIsRPlus() throws Exception {
         prepareAdmin1AsDo();
         prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.R);
@@ -445,13 +463,14 @@
         poContext.binder.callingUid = UserHandle.getUid(COPE_PROFILE_USER_ID, COPE_ADMIN1_APP_ID);
 
         runAsCaller(poContext, dpms, dpm -> {
-            assertEquals("Personal apps suspension wasn't migrated",
-                    DevicePolicyManager.PERSONAL_APPS_SUSPENDED_EXPLICITLY,
-                    dpm.getPersonalAppsSuspendedReasons(admin1));
+            assertWithMessage("Personal apps suspension wasn't migrated")
+                    .that(dpm.getPersonalAppsSuspendedReasons(admin1))
+                    .isEqualTo(DevicePolicyManager.PERSONAL_APPS_SUSPENDED_EXPLICITLY);
         });
     }
 
     @SmallTest
+    @Test
     public void testCompMigration_unsuspendAppsWhenDpcNotRPlus() throws Exception {
         prepareAdmin1AsDo();
         prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.Q);
@@ -470,9 +489,9 @@
         poContext.binder.callingUid = UserHandle.getUid(COPE_PROFILE_USER_ID, COPE_ADMIN1_APP_ID);
 
         runAsCaller(poContext, dpms, dpm -> {
-            assertEquals("Personal apps weren't unsuspended",
-                    DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED,
-                    dpm.getPersonalAppsSuspendedReasons(admin1));
+            assertWithMessage("Personal apps weren't unsuspended")
+                    .that(dpm.getPersonalAppsSuspendedReasons(admin1))
+                    .isEqualTo(DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED);
         });
     }
 
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 c4f7b95..8d7bc16 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -39,7 +39,9 @@
 import static com.android.server.testutils.TestUtils.assertExpectException;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assert.fail;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyInt;
@@ -89,13 +91,14 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.annotations.FlakyTest;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 import android.security.KeyChain;
 import android.security.keystore.AttestationUtils;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
-import android.test.MoreAsserts;
+import android.test.MoreAsserts; // TODO(b/171932723): replace by Truth
 import android.util.ArraySet;
 import android.util.Pair;
 
@@ -111,6 +114,9 @@
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 import org.mockito.Mockito;
 import org.mockito.internal.util.collections.Sets;
 import org.mockito.stubbing.Answer;
@@ -127,17 +133,11 @@
 
 /**
  * Tests for DevicePolicyManager( and DevicePolicyManagerService).
- * You can run them via:
- m FrameworksServicesTests &&
- adb install \
-   -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
- adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest \
-   -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
-
- (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
  *
- * , or:
- * runtest -c com.android.server.devicepolicy.DevicePolicyManagerTest frameworks-services
+ * <p>Run this test with:
+ *
+ * {@code atest FrameworksServicesTests:com.android.server.devicepolicy.DevicePolicyManagerTest}
+ *
  */
 @SmallTest
 @Presubmit
@@ -205,9 +205,8 @@
     private static final String PROFILE_OFF_SUSPENSION_TEXT = "suspension_text";
     private static final String PROFILE_OFF_SUSPENSION_SOON_TEXT = "suspension_tomorrow_text";
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
 
         mContext = getContext();
         mServiceContext = mContext;
@@ -251,11 +250,10 @@
         return dpms.mTransferOwnershipMetadataManager;
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         flushTasks(dpms);
         getMockTransferMetadataManager().deleteMetadataFile();
-        super.tearDown();
     }
 
     private void initializeDpms() {
@@ -336,14 +334,15 @@
             // PO needs to be a DA.
             dpm.setActiveAdmin(admin, /*replace=*/ false);
             // Fire!
-            assertTrue(dpm.setProfileOwner(admin, "owner-name", CALLER_USER_HANDLE));
+            assertThat(dpm.setProfileOwner(admin, "owner-name", CALLER_USER_HANDLE)).isTrue();
             // Check
-            assertEquals(admin, dpm.getProfileOwnerAsUser(CALLER_USER_HANDLE));
+            assertThat(dpm.getProfileOwnerAsUser(CALLER_USER_HANDLE)).isEqualTo(admin);
         });
 
         mServiceContext.binder.restoreCallingIdentity(ident);
     }
 
+    @Test
     public void testHasNoFeature() throws Exception {
         when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                 .thenReturn(false);
@@ -352,9 +351,10 @@
         new DevicePolicyManagerServiceTestable(getServices(), mContext);
 
         // If the device has no DPMS feature, it shouldn't register the local service.
-        assertNull(LocalServices.getService(DevicePolicyManagerInternal.class));
+        assertThat(LocalServices.getService(DevicePolicyManagerInternal.class)).isNull();
     }
 
+    @Test
     public void testLoadAdminData() throws Exception {
         // Device owner in SYSTEM_USER
         setDeviceOwner();
@@ -365,7 +365,7 @@
         final int ANOTHER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 1306);
         setUpPackageManagerForFakeAdmin(adminAnotherPackage, ANOTHER_UID, admin2);
         dpm.setActiveAdmin(adminAnotherPackage, /* replace =*/ false, CALLER_USER_HANDLE);
-        assertTrue(dpm.isAdminActiveAsUser(adminAnotherPackage, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActiveAsUser(adminAnotherPackage, CALLER_USER_HANDLE)).isTrue();
 
         initializeDpms();
 
@@ -381,6 +381,7 @@
         verify(getServices().networkPolicyManagerInternal).onAdminDataAvailable();
     }
 
+    @Test
     public void testLoadAdminData_noAdmins() throws Exception {
         final int ANOTHER_USER_ID = 15;
         getServices().addUser(ANOTHER_USER_ID, 0, "");
@@ -399,6 +400,7 @@
     /**
      * Caller doesn't have proper permissions.
      */
+    @Test
     public void testSetActiveAdmin_SecurityException() {
         // 1. Failure cases.
 
@@ -422,6 +424,7 @@
      * {@link DevicePolicyManager#getActiveAdmins}
      * {@link DevicePolicyManager#getActiveAdminsAsUser}
      */
+    @Test
     public void testSetActiveAdmin() throws Exception {
         // 1. Make sure the caller has proper permissions.
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
@@ -456,9 +459,9 @@
         // TODO Verify other calls too.
 
         // Make sure it's active admin1.
-        assertTrue(dpm.isAdminActive(admin1));
-        assertFalse(dpm.isAdminActive(admin2));
-        assertFalse(dpm.isAdminActive(admin3));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
+        assertThat(dpm.isAdminActive(admin2)).isFalse();
+        assertThat(dpm.isAdminActive(admin3)).isFalse();
 
         // But not admin1 for a different user.
 
@@ -466,8 +469,8 @@
         // (Because we're checking a different user's status from CALLER_USER_HANDLE.)
         mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
 
-        assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE + 1));
-        assertFalse(dpm.isAdminActiveAsUser(admin2, CALLER_USER_HANDLE + 1));
+        assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE + 1)).isFalse();
+        assertThat(dpm.isAdminActiveAsUser(admin2, CALLER_USER_HANDLE + 1)).isFalse();
 
         mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
 
@@ -479,9 +482,9 @@
         dpm.setActiveAdmin(admin2, /* replace =*/ false);
 
         // Now we have two admins.
-        assertTrue(dpm.isAdminActive(admin1));
-        assertTrue(dpm.isAdminActive(admin2));
-        assertFalse(dpm.isAdminActive(admin3));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
+        assertThat(dpm.isAdminActive(admin2)).isTrue();
+        assertThat(dpm.isAdminActive(admin3)).isFalse();
 
         // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called
         // again.  (times(1) because it was previously called for admin1)
@@ -508,9 +511,9 @@
 
         // 6. Test getActiveAdmins()
         List<ComponentName> admins = dpm.getActiveAdmins();
-        assertEquals(2, admins.size());
-        assertEquals(admin1, admins.get(0));
-        assertEquals(admin2, admins.get(1));
+        assertThat(admins.size()).isEqualTo(2);
+        assertThat(admins.get(0)).isEqualTo(admin1);
+        assertThat(admins.get(1)).isEqualTo(admin2);
 
         // There shouldn't be any callback to UsageStatsManagerInternal when the admin is being
         // replaced
@@ -519,12 +522,13 @@
         // Another user has no admins.
         mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
 
-        assertEquals(0, DpmTestUtils.getListSizeAllowingNull(
-                dpm.getActiveAdminsAsUser(CALLER_USER_HANDLE + 1)));
+        assertThat(DpmTestUtils.getListSizeAllowingNull(
+        dpm.getActiveAdminsAsUser(CALLER_USER_HANDLE + 1))).isEqualTo(0);
 
         mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
     }
 
+    @Test
     public void testSetActiveAdmin_multiUsers() throws Exception {
 
         final int ANOTHER_USER_ID = 100;
@@ -544,12 +548,12 @@
 
 
         mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
-        assertTrue(dpm.isAdminActive(admin1));
-        assertFalse(dpm.isAdminActive(admin2));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
+        assertThat(dpm.isAdminActive(admin2)).isFalse();
 
         mMockContext.binder.callingUid = ANOTHER_ADMIN_UID;
-        assertFalse(dpm.isAdminActive(admin1));
-        assertTrue(dpm.isAdminActive(admin2));
+        assertThat(dpm.isAdminActive(admin1)).isFalse();
+        assertThat(dpm.isAdminActive(admin2)).isTrue();
     }
 
     /**
@@ -557,12 +561,13 @@
      * {@link DevicePolicyManager#setActiveAdmin}
      * with replace=false
      */
+    @Test
     public void testSetActiveAdmin_twiceWithoutReplace() throws Exception {
         // 1. Make sure the caller has proper permissions.
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
 
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
-        assertTrue(dpm.isAdminActive(admin1));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
 
         // Add the same admin1 again without replace, which should throw.
         assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
@@ -574,6 +579,7 @@
      * {@link DevicePolicyManager#setActiveAdmin} when the admin isn't protected with
      * BIND_DEVICE_ADMIN.
      */
+    @Test
     public void testSetActiveAdmin_permissionCheck() throws Exception {
         // 1. Make sure the caller has proper permissions.
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
@@ -581,13 +587,13 @@
         assertExpectException(IllegalArgumentException.class,
                 /* messageRegex= */ permission.BIND_DEVICE_ADMIN,
                 () -> dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false));
-        assertFalse(dpm.isAdminActive(adminNoPerm));
+        assertThat(dpm.isAdminActive(adminNoPerm)).isFalse();
 
         // Change the target API level to MNC.  Now it can be set as DA.
         setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID, null,
                 VERSION_CODES.M);
         dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
-        assertTrue(dpm.isAdminActive(adminNoPerm));
+        assertThat(dpm.isAdminActive(adminNoPerm)).isTrue();
 
         // TODO Test the "load from the file" case where DA will still be loaded even without
         // BIND_DEVICE_ADMIN and target API is N.
@@ -597,6 +603,7 @@
      * Test for:
      * {@link DevicePolicyManager#removeActiveAdmin}
      */
+    @Test
     public void testRemoveActiveAdmin_SecurityException() {
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
 
@@ -604,9 +611,9 @@
 
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
 
-        assertTrue(dpm.isAdminActive(admin1));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
 
-        assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse();
 
         // Directly call the DPMS method with a different userid, which should fail.
         assertExpectException(SecurityException.class, /* messageRegex =*/ null,
@@ -627,6 +634,7 @@
      * {@link DevicePolicyManager#removeActiveAdmin} should fail with the user is not unlocked
      * (because we can't send the remove broadcast).
      */
+    @Test
     public void testRemoveActiveAdmin_userNotRunningOrLocked() {
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
 
@@ -636,9 +644,9 @@
 
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
 
-        assertTrue(dpm.isAdminActive(admin1));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
 
-        assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse();
 
         // 1. User not unlocked.
         setUserUnlocked(CALLER_USER_HANDLE, false);
@@ -646,7 +654,7 @@
                 /* messageRegex= */ "User must be running and unlocked",
                 () -> dpm.removeActiveAdmin(admin1));
 
-        assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse();
         verify(getServices().usageStatsManagerInternal, times(0)).setActiveAdminApps(
                 null, CALLER_USER_HANDLE);
 
@@ -654,7 +662,7 @@
         setUserUnlocked(CALLER_USER_HANDLE, true);
 
         dpm.removeActiveAdmin(admin1);
-        assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse();
         verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
                 null, CALLER_USER_HANDLE);
     }
@@ -663,6 +671,7 @@
      * Test for:
      * {@link DevicePolicyManager#removeActiveAdmin}
      */
+    @Test
     public void testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL() {
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
 
@@ -670,8 +679,8 @@
 
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
 
-        assertTrue(dpm.isAdminActive(admin1));
-        assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
+        assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse();
 
         // Different user, but should work, because caller has proper permissions.
         mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
@@ -680,7 +689,7 @@
         mContext.binder.callingUid = 1234567;
 
         dpms.removeActiveAdmin(admin1, CALLER_USER_HANDLE);
-        assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse();
         verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
                 null, CALLER_USER_HANDLE);
 
@@ -691,6 +700,7 @@
      * Test for:
      * {@link DevicePolicyManager#removeActiveAdmin}
      */
+    @Test
     public void testRemoveActiveAdmin_sameUserNoMANAGE_DEVICE_ADMINS() {
         // Need MANAGE_DEVICE_ADMINS for setActiveAdmin.  We'll remove it later.
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
@@ -699,8 +709,8 @@
 
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
 
-        assertTrue(dpm.isAdminActive(admin1));
-        assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
+        assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse();
 
         // Broadcast from saveSettingsLocked().
         verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
@@ -725,7 +735,7 @@
                 isNull(String.class),
                 isNull(Bundle.class));
 
-        assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse();
         verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
                 null, CALLER_USER_HANDLE);
 
@@ -738,6 +748,7 @@
         // TODO Check other internal calls.
     }
 
+    @Test
     public void testRemoveActiveAdmin_multipleAdminsInUser() {
         // Need MANAGE_DEVICE_ADMINS for setActiveAdmin.  We'll remove it later.
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
@@ -745,14 +756,14 @@
         // Add admin1.
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
 
-        assertTrue(dpm.isAdminActive(admin1));
-        assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
+        assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse();
 
         // Add admin2.
         dpm.setActiveAdmin(admin2, /* replace =*/ false);
 
-        assertTrue(dpm.isAdminActive(admin2));
-        assertFalse(dpm.isRemovingAdmin(admin2, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActive(admin2)).isTrue();
+        assertThat(dpm.isRemovingAdmin(admin2, CALLER_USER_HANDLE)).isFalse();
 
         // Broadcast from saveSettingsLocked().
         verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
@@ -777,7 +788,7 @@
                 isNull(String.class),
                 isNull(Bundle.class));
 
-        assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse();
         verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
                 MockUtils.checkApps(admin2.getPackageName()),
                 eq(CALLER_USER_HANDLE));
@@ -793,6 +804,7 @@
      * Test for:
      * {@link DevicePolicyManager#forceRemoveActiveAdmin(ComponentName, int)}
      */
+    @Test
     public void testForceRemoveActiveAdmin() throws Exception {
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
 
@@ -802,7 +814,7 @@
                 /* appId= */ 10138,
                 /* flags= */ ApplicationInfo.FLAG_TEST_ONLY);
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
-        assertTrue(dpm.isAdminActive(admin1));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
 
         // Calling from a non-shell uid should fail with a SecurityException
         mContext.binder.callingUid = 123456;
@@ -815,7 +827,7 @@
 
         mContext.callerPermissions.add(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
         // Verify
-        assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse();
         verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
                 null, CALLER_USER_HANDLE);
     }
@@ -825,6 +837,7 @@
      *
      * Validates that when the password history length is set, it is persisted after rebooting
      */
+    @Test
     public void testSaveAndLoadPasswordHistoryLength_persistedAfterReboot() throws Exception {
         int passwordHistoryLength = 2;
 
@@ -842,13 +855,13 @@
         // Save password history length
         dpm.setPasswordHistoryLength(admin1, passwordHistoryLength);
 
-        assertEquals(dpm.getPasswordHistoryLength(admin1), passwordHistoryLength);
+        assertThat(passwordHistoryLength).isEqualTo(dpm.getPasswordHistoryLength(admin1));
 
         initializeDpms();
         reset(mContext.spiedContext);
 
         // Password history length should persist after rebooted
-        assertEquals(dpm.getPasswordHistoryLength(admin1), passwordHistoryLength);
+        assertThat(passwordHistoryLength).isEqualTo(dpm.getPasswordHistoryLength(admin1));
     }
 
     /**
@@ -858,6 +871,7 @@
      * {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is sent to managed profile owners, in
      * addition to ones in the original user.
      */
+    @Test
     public void testSetActivePasswordState_sendToProfiles() throws Exception {
         mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
 
@@ -893,6 +907,7 @@
      * intent {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is only sent to the profile, not
      * its parent.
      */
+    @Test
     public void testSetActivePasswordState_notSentToParent() throws Exception {
         mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
 
@@ -932,6 +947,7 @@
     /**
      * Test for: {@link DevicePolicyManager#setDeviceOwner} DO on system user installs successfully.
      */
+    @Test
     public void testSetDeviceOwner() throws Exception {
         setDeviceOwner();
 
@@ -944,7 +960,7 @@
 
         // DO admin can't be deactivated.
         dpm.removeActiveAdmin(admin1);
-        assertTrue(dpm.isAdminActive(admin1));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
 
         // TODO Test getDeviceOwnerName() too. To do so, we need to change
         // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
@@ -969,19 +985,19 @@
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
 
         // Fire!
-        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
+        assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue();
 
         // getDeviceOwnerComponent should return the admin1 component.
-        assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
-        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
+        assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1);
+        assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
 
         // Check various get APIs.
         checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ true);
 
         // getDeviceOwnerComponent should *NOT* return the admin1 component for other users.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
-        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
-        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
+        assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null);
+        assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
 
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
@@ -997,7 +1013,7 @@
                 MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
 
-        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
+        assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
     }
 
     private void checkGetDeviceOwnerInfoApi(DevicePolicyManager dpm, boolean hasDeviceOwner) {
@@ -1012,89 +1028,89 @@
         // TODO Test getDeviceOwnerName() too.  To do so, we need to change
         // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
         if (hasDeviceOwner) {
-            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
+            assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue();
+            assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue();
+            assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1);
 
-            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
-            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
-            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
+            assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue();
+            assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
+            assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
         } else {
-            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
+            assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse();
+            assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse();
+            assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null);
 
-            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
-            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
-            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
+            assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isFalse();
+            assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(null);
+            assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
         }
 
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         if (hasDeviceOwner) {
-            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
+            assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue();
+            assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue();
+            assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1);
 
-            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
-            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
-            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
+            assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue();
+            assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
+            assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
         } else {
-            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
+            assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse();
+            assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse();
+            assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null);
 
-            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
-            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
-            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
+            assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isFalse();
+            assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(null);
+            assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
         }
 
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         // Still with MANAGE_USERS.
-        assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-        assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
+        assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse();
+        assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse();
+        assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null);
 
         if (hasDeviceOwner) {
-            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
-            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
-            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
+            assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue();
+            assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
+            assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
         } else {
-            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
-            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
-            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
+            assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isFalse();
+            assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(null);
+            assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
         }
 
         mContext.binder.callingUid = Process.SYSTEM_UID;
         mContext.callerPermissions.remove(permission.MANAGE_USERS);
         // System can still call "OnAnyUser" without MANAGE_USERS.
         if (hasDeviceOwner) {
-            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
+            assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue();
+            assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue();
+            assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1);
 
-            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
-            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
-            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
+            assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue();
+            assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
+            assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
         } else {
-            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
+            assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse();
+            assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse();
+            assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null);
 
-            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
-            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
-            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
+            assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isFalse();
+            assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(null);
+            assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
         }
 
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         // Still no MANAGE_USERS.
         if (hasDeviceOwner) {
-            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
+            assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue();
+            assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue();
+            assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1);
         } else {
-            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
+            assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse();
+            assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse();
+            assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null);
         }
 
         assertExpectException(SecurityException.class, /* messageRegex =*/ null,
@@ -1108,9 +1124,9 @@
 
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         // Still no MANAGE_USERS.
-        assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-        assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
+        assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse();
+        assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse();
+        assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null);
 
         assertExpectException(SecurityException.class, /* messageRegex =*/ null,
                 () -> dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
@@ -1130,6 +1146,7 @@
     /**
      * Test for: {@link DevicePolicyManager#setDeviceOwner} Package doesn't exist.
      */
+    @Test
     public void testSetDeviceOwner_noSuchPackage() {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_USERS);
@@ -1144,10 +1161,12 @@
                 () -> dpm.setDeviceOwner(new ComponentName("a.b.c", ".def")));
     }
 
+    @Test
     public void testSetDeviceOwner_failures() throws Exception {
         // TODO Test more failure cases.  Basically test all chacks in enforceCanSetDeviceOwner().
     }
 
+    @Test
     public void testClearDeviceOwner() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_USERS);
@@ -1164,20 +1183,20 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
-        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
+        assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue();
 
         // Verify internal calls.
         verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
                 eq(admin1.getPackageName()));
 
-        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
+        assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
         when(getServices().userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM))).thenReturn(true);
 
-        assertTrue(dpm.isAdminActive(admin1));
-        assertFalse(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
+        assertThat(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM)).isFalse();
 
         // Set up other mocks.
         when(getServices().userManager.getUserRestrictions()).thenReturn(new Bundle());
@@ -1196,7 +1215,7 @@
         dpm.clearDeviceOwnerApp(admin1.getPackageName());
 
         // Now DO shouldn't be set.
-        assertNull(dpm.getDeviceOwnerComponentOnAnyUser());
+        assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isNull();
 
         verify(getServices().userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
                 eq(false),
@@ -1209,7 +1228,7 @@
         verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
                 null, UserHandle.USER_SYSTEM);
 
-        assertFalse(dpm.isAdminActiveAsUser(admin1, UserHandle.USER_SYSTEM));
+        assertThat(dpm.isAdminActiveAsUser(admin1, UserHandle.USER_SYSTEM)).isFalse();
 
         // ACTION_DEVICE_OWNER_CHANGED should be sent twice, once for setting the device owner
         // and once for clearing it.
@@ -1219,6 +1238,7 @@
         // TODO Check other calls.
     }
 
+    @Test
     public void testDeviceOwnerBackupActivateDeactivate() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
@@ -1227,7 +1247,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
-        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
+        assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue();
 
         verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
                 eq(UserHandle.USER_SYSTEM), eq(false));
@@ -1238,6 +1258,7 @@
                 eq(UserHandle.USER_SYSTEM), eq(true));
     }
 
+    @Test
     public void testProfileOwnerBackupActivateDeactivate() throws Exception {
         setAsProfileOwner(admin1);
 
@@ -1250,6 +1271,7 @@
                 eq(CALLER_USER_HANDLE), eq(true));
     }
 
+    @Test
     public void testClearDeviceOwner_fromDifferentUser() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_USERS);
@@ -1266,13 +1288,13 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
-        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
+        assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue();
 
         // Verify internal calls.
         verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
                 eq(admin1.getPackageName()));
 
-        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
+        assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
 
         // Now call clear from the secondary user, which should throw.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -1286,7 +1308,7 @@
                 () -> dpm.clearDeviceOwnerApp(admin1.getPackageName()));
 
         // DO shouldn't be removed.
-        assertTrue(dpm.isDeviceManaged());
+        assertThat(dpm.isDeviceManaged()).isTrue();
     }
 
     /**
@@ -1294,6 +1316,7 @@
      *
      * Validates that when the device owner is removed, the reset password token is cleared
      */
+    @Test
     public void testClearDeviceOwner_clearResetPasswordToken() throws Exception {
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
@@ -1312,13 +1335,13 @@
         when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM),
                 nullable(EscrowTokenStateChangeCallback.class)))
                 .thenReturn(handle);
-        assertTrue(dpm.setResetPasswordToken(admin1, token));
+        assertThat(dpm.setResetPasswordToken(admin1, token)).isTrue();
 
         // Assert reset password token is active
         when(getServices().lockPatternUtils.isEscrowTokenActive(eq(handle),
                 eq(UserHandle.USER_SYSTEM)))
                 .thenReturn(true);
-        assertTrue(dpm.isResetPasswordTokenActive(admin1));
+        assertThat(dpm.isResetPasswordTokenActive(admin1)).isTrue();
 
         // Remove the device owner
         dpm.clearDeviceOwnerApp(admin1.getPackageName());
@@ -1328,12 +1351,13 @@
                 eq(UserHandle.USER_SYSTEM));
     }
 
+    @Test
     public void testSetProfileOwner() throws Exception {
         setAsProfileOwner(admin1);
 
         // PO admin can't be deactivated.
         dpm.removeActiveAdmin(admin1);
-        assertTrue(dpm.isAdminActive(admin1));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
 
         // Try setting DO on the same user, which should fail.
         setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
@@ -1347,13 +1371,14 @@
         });
     }
 
+    @Test
     public void testClearProfileOwner() throws Exception {
         setAsProfileOwner(admin1);
 
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
-        assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName()));
-        assertFalse(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isProfileOwnerApp(admin1.getPackageName())).isTrue();
+        assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse();
 
         // First try when the user is locked, which should fail.
         when(getServices().userManager.isUserUnlocked(anyInt()))
@@ -1367,16 +1392,18 @@
         dpm.clearProfileOwner(admin1);
 
         // Check
-        assertFalse(dpm.isProfileOwnerApp(admin1.getPackageName()));
-        assertFalse(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE));
+        assertThat(dpm.isProfileOwnerApp(admin1.getPackageName())).isFalse();
+        assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse();
         verify(getServices().usageStatsManagerInternal).setActiveAdminApps(
                 null, CALLER_USER_HANDLE);
     }
 
+    @Test
     public void testSetProfileOwner_failures() throws Exception {
         // TODO Test more failure cases.  Basically test all chacks in enforceCanSetProfileOwner().
     }
 
+    @Test
     public void testGetDeviceOwnerAdminLocked() throws Exception {
         checkDeviceOwnerWithMultipleDeviceAdmins();
     }
@@ -1421,13 +1448,13 @@
 
         // Set DO on the first non-system user.
         getServices().setUserRunning(CALLER_USER_HANDLE, true);
-        assertTrue(dpm.setDeviceOwner(admin2, "owner-name", CALLER_USER_HANDLE));
+        assertThat(dpm.setDeviceOwner(admin2, "owner-name", CALLER_USER_HANDLE)).isTrue();
 
-        assertEquals(admin2, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
+        assertThat(dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false)).isEqualTo(admin2);
 
         // Then check getDeviceOwnerAdminLocked().
-        assertEquals(admin2, getDeviceOwner().info.getComponent());
-        assertEquals(DpmMockContext.CALLER_UID, getDeviceOwner().getUid());
+        assertThat(getDeviceOwner().info.getComponent()).isEqualTo(admin2);
+        assertThat(getDeviceOwner().getUid()).isEqualTo(DpmMockContext.CALLER_UID);
     }
 
     /**
@@ -1438,6 +1465,7 @@
      * We didn't use to persist the DO component class name, but now we do, and the above method
      * finds the right component from a package name upon migration.
      */
+    @Test
     public void testDeviceOwnerMigration() throws Exception {
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         checkDeviceOwnerWithMultipleDeviceAdmins();
@@ -1449,7 +1477,8 @@
         dpms.mOwners.writeDeviceOwner();
 
         // Make sure the DO component name doesn't have a class name.
-        assertEquals("", dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false).getClassName());
+        assertThat(dpms.getDeviceOwnerComponent(/* callingUserOnly= */ false).getClassName())
+                .isEmpty();
 
         // Then create a new DPMS to have it load the settings from files.
         when(getServices().userManager.getUserRestrictions(any(UserHandle.class)))
@@ -1459,9 +1488,10 @@
         // Now the DO component name is a full name.
         // *BUT* because both admin1 and admin2 belong to the same package, we think admin1 is the
         // DO.
-        assertEquals(admin1, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
+        assertThat(dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false)).isEqualTo(admin1);
     }
 
+    @Test
     public void testSetGetApplicationRestriction() {
         setAsProfileOwner(admin1);
         mContext.packageName = admin1.getPackageName();
@@ -1480,20 +1510,20 @@
 
         {
             Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg1");
-            assertNotNull(returned);
-            assertEquals(returned.size(), 1);
-            assertEquals(returned.get("KEY_STRING"), "Foo1");
+            assertThat(returned).isNotNull();
+            assertThat(returned.size()).isEqualTo(1);
+            assertThat("Foo1").isEqualTo(returned.get("KEY_STRING"));
         }
 
         {
             Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg2");
-            assertNotNull(returned);
-            assertEquals(returned.size(), 1);
-            assertEquals(returned.get("KEY_STRING"), "Foo2");
+            assertThat(returned).isNotNull();
+            assertThat(returned.size()).isEqualTo(1);
+            assertThat("Foo2").isEqualTo(returned.get("KEY_STRING"));
         }
 
         dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle());
-        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg2").size());
+        assertThat(dpm.getApplicationRestrictions(admin1, "pkg2").size()).isEqualTo(0);
     }
 
     /**
@@ -1546,6 +1576,7 @@
         return uid;
     }
 
+    @Test
     public void testCertificateDisclosure() throws Exception {
         final int userId = CALLER_USER_HANDLE;
         final UserHandle user = UserHandle.of(userId);
@@ -1571,7 +1602,8 @@
                 .cancelAsUser(anyString(), anyInt(), eq(user));
 
         // Given that we have four certificates installed,
-        when(getServices().keyChainConnection.getService().getUserCaAliases()).thenReturn(fourCerts);
+        when(getServices().keyChainConnection.getService().getUserCaAliases())
+                .thenReturn(fourCerts);
         // when two of them are approved (one of them approved twice hence no action),
         dpms.approveCaCert(fourCerts.getList().get(0), userId, true);
         dpms.approveCaCert(fourCerts.getList().get(1), userId, true);
@@ -1586,6 +1618,7 @@
      * Simple test for delegate set/get and general delegation. Tests verifying that delegated
      * privileges can acually be exercised by a delegate are not covered here.
      */
+    @Test
     public void testDelegation() throws Exception {
         setAsProfileOwner(admin1);
 
@@ -1606,17 +1639,18 @@
 
         // DPMS correctly stores and retrieves the delegates
         DevicePolicyData policy = dpms.mUserData.get(userHandle);
-        assertEquals(2, policy.mDelegationMap.size());
+        assertThat(policy.mDelegationMap.size()).isEqualTo(2);
         MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(CERT_DELEGATE),
             DELEGATION_CERT_INSTALL);
         MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, CERT_DELEGATE),
             DELEGATION_CERT_INSTALL);
-        assertEquals(CERT_DELEGATE, dpm.getCertInstallerPackage(admin1));
+        assertThat(dpm.getCertInstallerPackage(admin1)).isEqualTo(CERT_DELEGATE);
         MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(RESTRICTIONS_DELEGATE),
             DELEGATION_APP_RESTRICTIONS);
         MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, RESTRICTIONS_DELEGATE),
             DELEGATION_APP_RESTRICTIONS);
-        assertEquals(RESTRICTIONS_DELEGATE, dpm.getApplicationRestrictionsManagingPackage(admin1));
+        assertThat(dpm.getApplicationRestrictionsManagingPackage(admin1))
+                .isEqualTo(RESTRICTIONS_DELEGATE);
 
         // On calling install certificate APIs from an unauthorized process
         mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID;
@@ -1658,6 +1692,7 @@
         }
     }
 
+    @Test
     public void testApplicationRestrictionsManagingApp() throws Exception {
         setAsProfileOwner(admin1);
 
@@ -1673,7 +1708,7 @@
         // delegated that permission yet.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         mContext.packageName = admin1.getPackageName();
-        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
+        assertThat(dpm.isCallerApplicationRestrictionsManagingPackage()).isFalse();
         final Bundle rest = new Bundle();
         rest.putString("KEY_STRING", "Foo1");
         assertExpectException(SecurityException.class, INVALID_CALLING_IDENTITY_MSG,
@@ -1682,7 +1717,7 @@
         // Check via the profile owner that no restrictions were set.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         mContext.packageName = admin1.getPackageName();
-        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
+        assertThat(dpm.getApplicationRestrictions(admin1, "pkg1").size()).isEqualTo(0);
 
         // Check the API does not allow setting a non-existent package
         assertExpectException(PackageManager.NameNotFoundException.class,
@@ -1692,22 +1727,22 @@
 
         // Let appRestrictionsManagerPackage manage app restrictions
         dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage);
-        assertEquals(appRestrictionsManagerPackage,
-                dpm.getApplicationRestrictionsManagingPackage(admin1));
+        assertThat(dpm.getApplicationRestrictionsManagingPackage(admin1))
+                .isEqualTo(appRestrictionsManagerPackage);
 
         // Now that package should be able to set and retrieve app restrictions.
         mContext.binder.callingUid = appRestrictionsManagerUid;
         mContext.packageName = appRestrictionsManagerPackage;
-        assertTrue(dpm.isCallerApplicationRestrictionsManagingPackage());
+        assertThat(dpm.isCallerApplicationRestrictionsManagingPackage()).isTrue();
         dpm.setApplicationRestrictions(null, "pkg1", rest);
         Bundle returned = dpm.getApplicationRestrictions(null, "pkg1");
-        assertEquals(1, returned.size(), 1);
-        assertEquals("Foo1", returned.get("KEY_STRING"));
+        assertThat(returned.size()).isEqualTo(1);
+        assertThat(returned.get("KEY_STRING")).isEqualTo("Foo1");
 
         // The same app running on a separate user shouldn't be able to manage app restrictions.
         mContext.binder.callingUid = UserHandle.getUid(
                 UserHandle.USER_SYSTEM, appRestrictionsManagerAppId);
-        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
+        assertThat(dpm.isCallerApplicationRestrictionsManagingPackage()).isFalse();
         assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex,
                 () -> dpm.setApplicationRestrictions(null, "pkg1", rest));
 
@@ -1715,20 +1750,21 @@
         // too.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         mContext.packageName = admin1.getPackageName();
-        assertEquals(returned, dpm.getApplicationRestrictions(admin1, "pkg1"));
+        assertThat(dpm.getApplicationRestrictions(admin1, "pkg1")).isEqualTo(returned);
         dpm.setApplicationRestrictions(admin1, "pkg1", null);
-        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
+        assertThat(dpm.getApplicationRestrictions(admin1, "pkg1").size()).isEqualTo(0);
 
         // Removing the ability for the package to manage app restrictions.
         dpm.setApplicationRestrictionsManagingPackage(admin1, null);
-        assertNull(dpm.getApplicationRestrictionsManagingPackage(admin1));
+        assertThat(dpm.getApplicationRestrictionsManagingPackage(admin1)).isNull();
         mContext.binder.callingUid = appRestrictionsManagerUid;
         mContext.packageName = appRestrictionsManagerPackage;
-        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
+        assertThat(dpm.isCallerApplicationRestrictionsManagingPackage()).isFalse();
         assertExpectException(SecurityException.class, INVALID_CALLING_IDENTITY_MSG,
                 () -> dpm.setApplicationRestrictions(null, "pkg1", null));
     }
 
+    @Test
     public void testSetUserRestriction_asDo() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_USERS);
@@ -1745,8 +1781,8 @@
 
         // Call.
         dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM);
-        assertTrue(dpm.setDeviceOwner(admin1, "owner-name",
-                UserHandle.USER_SYSTEM));
+        assertThat(dpm.setDeviceOwner(admin1, "owner-name",
+        UserHandle.USER_SYSTEM)).isTrue();
 
         assertNoDeviceOwnerRestrictions();
         reset(getServices().userManagerInternal);
@@ -1859,6 +1895,7 @@
         return null;
     }
 
+    @Test
     public void testDaDisallowedPolicies_SecurityException() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
@@ -1869,25 +1906,28 @@
         boolean originalCameraDisabled = dpm.getCameraDisabled(admin1);
         assertExpectException(SecurityException.class, /* messageRegex= */ null,
                 () -> dpm.setCameraDisabled(admin1, true));
-        assertEquals(originalCameraDisabled, dpm.getCameraDisabled(admin1));
+        assertThat(dpm.getCameraDisabled(admin1)).isEqualTo(originalCameraDisabled);
 
         int originalKeyguardDisabledFeatures = dpm.getKeyguardDisabledFeatures(admin1);
         assertExpectException(SecurityException.class, /* messageRegex= */ null,
                 () -> dpm.setKeyguardDisabledFeatures(admin1,
                         DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL));
-        assertEquals(originalKeyguardDisabledFeatures, dpm.getKeyguardDisabledFeatures(admin1));
+        assertThat(dpm.getKeyguardDisabledFeatures(admin1))
+                .isEqualTo(originalKeyguardDisabledFeatures);
 
         long originalPasswordExpirationTimeout = dpm.getPasswordExpirationTimeout(admin1);
         assertExpectException(SecurityException.class, /* messageRegex= */ null,
                 () -> dpm.setPasswordExpirationTimeout(admin1, 1234));
-        assertEquals(originalPasswordExpirationTimeout, dpm.getPasswordExpirationTimeout(admin1));
+        assertThat(dpm.getPasswordExpirationTimeout(admin1))
+                .isEqualTo(originalPasswordExpirationTimeout);
 
         int originalPasswordQuality = dpm.getPasswordQuality(admin1);
         assertExpectException(SecurityException.class, /* messageRegex= */ null,
                 () -> dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC));
-        assertEquals(originalPasswordQuality, dpm.getPasswordQuality(admin1));
+        assertThat(dpm.getPasswordQuality(admin1)).isEqualTo(originalPasswordQuality);
     }
 
+    @Test
     public void testSetUserRestriction_asPo() {
         setAsProfileOwner(admin1);
 
@@ -2023,6 +2063,7 @@
                     UserManager.DISALLOW_UNMUTE_MICROPHONE
             );
 
+    @Test
     public void testSetUserRestriction_asPoOfOrgOwnedDevice() throws Exception {
         final int MANAGED_PROFILE_ADMIN_UID =
                 UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
@@ -2097,6 +2138,7 @@
         );
     }
 
+    @Test
     public void testNoDefaultEnabledUserRestrictions() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_USERS);
@@ -2112,8 +2154,8 @@
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
 
         dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM);
-        assertTrue(dpm.setDeviceOwner(admin1, "owner-name",
-                UserHandle.USER_SYSTEM));
+        assertThat(dpm.setDeviceOwner(admin1, "owner-name",
+        UserHandle.USER_SYSTEM)).isTrue();
 
         assertNoDeviceOwnerRestrictions();
 
@@ -2132,6 +2174,7 @@
         );
     }
 
+    @Test
     public void testSetFactoryResetProtectionPolicyWithDO() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -2156,6 +2199,7 @@
                 eq(android.Manifest.permission.MANAGE_FACTORY_RESET_PROTECTION));
     }
 
+    @Test
     public void testSetFactoryResetProtectionPolicyFailWithPO() throws Exception {
         setupProfileOwner();
 
@@ -2167,6 +2211,7 @@
                 () -> dpm.setFactoryResetProtectionPolicy(admin1, policy));
     }
 
+    @Test
     public void testSetFactoryResetProtectionPolicyWithPOOfOrganizationOwnedDevice()
             throws Exception {
         setupProfileOwner();
@@ -2204,6 +2249,7 @@
                 eq(android.Manifest.permission.MANAGE_FACTORY_RESET_PROTECTION));
     }
 
+    @Test
     public void testGetFactoryResetProtectionPolicyWithFrpManagementAgent()
             throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -2245,6 +2291,7 @@
         assertThat(actualAccounts).containsExactlyElementsIn(expectedAccounts);
     }
 
+    @Test
     public void testSetKeyguardDisabledFeaturesWithDO() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -2255,6 +2302,7 @@
                 DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA);
     }
 
+    @Test
     public void testSetKeyguardDisabledFeaturesWithPO() throws Exception {
         setupProfileOwner();
 
@@ -2264,6 +2312,7 @@
                 DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
     }
 
+    @Test
     public void testSetKeyguardDisabledFeaturesWithPOOfOrganizationOwnedDevice()
             throws Exception {
         final int MANAGED_PROFILE_USER_ID = CALLER_USER_HANDLE;
@@ -2281,6 +2330,7 @@
                 DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA);
     }
 
+    @Test
     public void testSetApplicationHiddenWithDO() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -2304,6 +2354,7 @@
                 UserHandle.USER_SYSTEM);
     }
 
+    @Test
     public void testSetApplicationHiddenWithPOOfOrganizationOwnedDevice() throws Exception {
         final int MANAGED_PROFILE_USER_ID = CALLER_USER_HANDLE;
         final int MANAGED_PROFILE_ADMIN_UID =
@@ -2334,6 +2385,7 @@
                 false, UserHandle.USER_SYSTEM);
     }
 
+    @Test
     public void testGetMacAddress() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
@@ -2351,7 +2403,7 @@
 
         // DO needs to be an DA.
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
-        assertTrue(dpm.isAdminActive(admin1));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
 
         // Test 2. Caller has DA, but not DO.
         assertExpectException(SecurityException.class,
@@ -2359,7 +2411,7 @@
                 () -> dpm.getWifiMacAddress(admin1));
 
         // Test 3. Caller has PO, but not DO.
-        assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
+        assertThat(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue();
         assertExpectException(SecurityException.class,
                 /* messageRegex= */ INVALID_CALLING_IDENTITY_MSG,
                 () -> dpm.getWifiMacAddress(admin1));
@@ -2368,30 +2420,32 @@
         dpm.clearProfileOwner(admin1);
         dpm.setActiveAdmin(admin1, false);
         // Test 4, Caller is DO now.
-        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
+        assertThat(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue();
 
         // 4-1.  But WifiManager is not ready.
-        assertNull(dpm.getWifiMacAddress(admin1));
+        assertThat(dpm.getWifiMacAddress(admin1)).isNull();
 
         // 4-2.  When WifiManager returns an empty array, dpm should also output null.
         when(getServices().wifiManager.getFactoryMacAddresses()).thenReturn(new String[0]);
-        assertNull(dpm.getWifiMacAddress(admin1));
+        assertThat(dpm.getWifiMacAddress(admin1)).isNull();
 
         // 4-3. With a real MAC address.
         final String[] macAddresses = new String[]{"11:22:33:44:55:66"};
         when(getServices().wifiManager.getFactoryMacAddresses()).thenReturn(macAddresses);
-        assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
+        assertThat(dpm.getWifiMacAddress(admin1)).isEqualTo("11:22:33:44:55:66");
     }
 
+    @Test
     public void testGetMacAddressByOrgOwnedPO() throws Exception {
         setupProfileOwner();
         configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
 
         final String[] macAddresses = new String[]{"11:22:33:44:55:66"};
         when(getServices().wifiManager.getFactoryMacAddresses()).thenReturn(macAddresses);
-        assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
+        assertThat(dpm.getWifiMacAddress(admin1)).isEqualTo("11:22:33:44:55:66");
     }
 
+    @Test
     public void testReboot() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
@@ -2404,19 +2458,19 @@
 
         // Set admin1 as DA.
         dpm.setActiveAdmin(admin1, false);
-        assertTrue(dpm.isAdminActive(admin1));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
         assertExpectException(SecurityException.class, /* messageRegex= */
                 INVALID_CALLING_IDENTITY_MSG, () -> dpm.reboot(admin1));
 
         // Set admin1 as PO.
-        assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
+        assertThat(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue();
         assertExpectException(SecurityException.class, /* messageRegex= */
                 INVALID_CALLING_IDENTITY_MSG, () -> dpm.reboot(admin1));
 
         // Remove PO and add DO.
         dpm.clearProfileOwner(admin1);
         dpm.setActiveAdmin(admin1, false);
-        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
+        assertThat(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue();
 
         // admin1 is DO.
         // Set current call state of device to ringing.
@@ -2432,10 +2486,12 @@
                 () -> dpm.reboot(admin1));
 
         // Set current call state of device to idle.
-        when(getServices().telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
+        when(getServices().telephonyManager.getCallState())
+                .thenReturn(TelephonyManager.CALL_STATE_IDLE);
         dpm.reboot(admin1);
     }
 
+    @Test
     public void testSetGetSupportText() {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         dpm.setActiveAdmin(admin1, true);
@@ -2444,11 +2500,11 @@
 
         // Null default support messages.
         {
-            assertNull(dpm.getLongSupportMessage(admin1));
-            assertNull(dpm.getShortSupportMessage(admin1));
+            assertThat(dpm.getLongSupportMessage(admin1)).isNull();
+            assertThat(dpm.getShortSupportMessage(admin1)).isNull();
             mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-            assertNull(dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE));
-            assertNull(dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE));
+            assertThat(dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE)).isNull();
+            assertThat(dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE)).isNull();
             mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
         }
 
@@ -2473,46 +2529,46 @@
         {
             final String supportText = "Some text to test with.";
             dpm.setShortSupportMessage(admin1, supportText);
-            assertEquals(supportText, dpm.getShortSupportMessage(admin1));
-            assertNull(dpm.getLongSupportMessage(admin1));
-            assertNull(dpm.getShortSupportMessage(admin2));
+            assertThat(dpm.getShortSupportMessage(admin1)).isEqualTo(supportText);
+            assertThat(dpm.getLongSupportMessage(admin1)).isNull();
+            assertThat(dpm.getShortSupportMessage(admin2)).isNull();
 
             mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-            assertEquals(supportText, dpm.getShortSupportMessageForUser(admin1,
-                    CALLER_USER_HANDLE));
-            assertNull(dpm.getShortSupportMessageForUser(admin2, CALLER_USER_HANDLE));
-            assertNull(dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE));
+            assertThat(dpm.getShortSupportMessageForUser(admin1,
+            CALLER_USER_HANDLE)).isEqualTo(supportText);
+            assertThat(dpm.getShortSupportMessageForUser(admin2, CALLER_USER_HANDLE)).isNull();
+            assertThat(dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE)).isNull();
             mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
             dpm.setShortSupportMessage(admin1, null);
-            assertNull(dpm.getShortSupportMessage(admin1));
+            assertThat(dpm.getShortSupportMessage(admin1)).isNull();
         }
 
         // Set/Get long returns what it sets and other admins text isn't changed.
         {
             final String supportText = "Some text to test with.\nWith more text.";
             dpm.setLongSupportMessage(admin1, supportText);
-            assertEquals(supportText, dpm.getLongSupportMessage(admin1));
-            assertNull(dpm.getShortSupportMessage(admin1));
-            assertNull(dpm.getLongSupportMessage(admin2));
+            assertThat(dpm.getLongSupportMessage(admin1)).isEqualTo(supportText);
+            assertThat(dpm.getShortSupportMessage(admin1)).isNull();
+            assertThat(dpm.getLongSupportMessage(admin2)).isNull();
 
             mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-            assertEquals(supportText, dpm.getLongSupportMessageForUser(admin1,
-                    CALLER_USER_HANDLE));
-            assertNull(dpm.getLongSupportMessageForUser(admin2, CALLER_USER_HANDLE));
-            assertNull(dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE));
+            assertThat(dpm.getLongSupportMessageForUser(admin1,
+            CALLER_USER_HANDLE)).isEqualTo(supportText);
+            assertThat(dpm.getLongSupportMessageForUser(admin2, CALLER_USER_HANDLE)).isNull();
+            assertThat(dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE)).isNull();
             mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
             dpm.setLongSupportMessage(admin1, null);
-            assertNull(dpm.getLongSupportMessage(admin1));
+            assertThat(dpm.getLongSupportMessage(admin1)).isNull();
         }
     }
 
+    @Test
     public void testSetGetMeteredDataDisabledPackages() throws Exception {
         setAsProfileOwner(admin1);
 
-        final ArrayList<String> emptyList = new ArrayList<>();
-        assertEquals(emptyList, dpm.getMeteredDataDisabledPackages(admin1));
+        assertThat(dpm.getMeteredDataDisabledPackages(admin1)).isEmpty();
 
         // Setup
         final ArrayList<String> pkgsToRestrict = new ArrayList<>();
@@ -2525,8 +2581,8 @@
         List<String> excludedPkgs = dpm.setMeteredDataDisabledPackages(admin1, pkgsToRestrict);
 
         // Verify
-        assertEquals(emptyList, excludedPkgs);
-        assertEquals(pkgsToRestrict, dpm.getMeteredDataDisabledPackages(admin1));
+        assertThat(excludedPkgs).isEmpty();
+        assertThat(dpm.getMeteredDataDisabledPackages(admin1)).isEqualTo(pkgsToRestrict);
         verify(getServices().networkPolicyManagerInternal).setMeteredRestrictedPackages(
                 MockUtils.checkApps(pkgsToRestrict.toArray(new String[0])),
                 eq(CALLER_USER_HANDLE));
@@ -2536,17 +2592,18 @@
         excludedPkgs = dpm.setMeteredDataDisabledPackages(admin1, pkgsToRestrict);
 
         // Verify
-        assertEquals(emptyList, excludedPkgs);
-        assertEquals(pkgsToRestrict, dpm.getMeteredDataDisabledPackages(admin1));
+        assertThat(excludedPkgs).isEmpty();
+        assertThat(dpm.getMeteredDataDisabledPackages(admin1)).isEqualTo(pkgsToRestrict);
         verify(getServices().networkPolicyManagerInternal).setMeteredRestrictedPackages(
                 MockUtils.checkApps(pkgsToRestrict.toArray(new String[0])),
                 eq(CALLER_USER_HANDLE));
     }
 
+    @Test
     public void testSetGetMeteredDataDisabledPackages_deviceAdmin() {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         dpm.setActiveAdmin(admin1, true);
-        assertTrue(dpm.isAdminActive(admin1));
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
         mContext.callerPermissions.remove(permission.MANAGE_DEVICE_ADMINS);
 
         assertExpectException(SecurityException.class,  /* messageRegex= */ NOT_PROFILE_OWNER_MSG,
@@ -2555,11 +2612,11 @@
                 () -> dpm.getMeteredDataDisabledPackages(admin1));
     }
 
+    @Test
     public void testIsMeteredDataDisabledForUserPackage() throws Exception {
         setAsProfileOwner(admin1);
 
         // Setup
-        final ArrayList<String> emptyList = new ArrayList<>();
         final ArrayList<String> pkgsToRestrict = new ArrayList<>();
         final String package1 = "com.example.one";
         final String package2 = "com.example.two";
@@ -2571,16 +2628,20 @@
         List<String> excludedPkgs = dpm.setMeteredDataDisabledPackages(admin1, pkgsToRestrict);
 
         // Verify
-        assertEquals(emptyList, excludedPkgs);
+        assertThat(excludedPkgs).isEmpty();
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertTrue(package1 + "should be restricted",
-                dpm.isMeteredDataDisabledPackageForUser(admin1, package1, CALLER_USER_HANDLE));
-        assertTrue(package2 + "should be restricted",
-                dpm.isMeteredDataDisabledPackageForUser(admin1, package2, CALLER_USER_HANDLE));
-        assertFalse(package3 + "should not be restricted",
-                dpm.isMeteredDataDisabledPackageForUser(admin1, package3, CALLER_USER_HANDLE));
+        assertWithMessage("%s should be restricted", package1)
+                .that(dpm.isMeteredDataDisabledPackageForUser(admin1, package1, CALLER_USER_HANDLE))
+                .isTrue();
+        assertWithMessage("%s should be restricted", package2)
+                .that(dpm.isMeteredDataDisabledPackageForUser(admin1, package2, CALLER_USER_HANDLE))
+                .isTrue();
+        assertWithMessage("%s should not be restricted", package3)
+                .that(dpm.isMeteredDataDisabledPackageForUser(admin1, package3, CALLER_USER_HANDLE))
+                .isFalse();
     }
 
+    @Test
     public void testIsMeteredDataDisabledForUserPackage_nonSystemUidCaller() throws Exception {
         setAsProfileOwner(admin1);
         assertExpectException(SecurityException.class,
@@ -2597,6 +2658,7 @@
         clearDeviceOwner();
     }
 
+    @Test
     public void testCreateAdminSupportIntent() throws Exception {
         // Setup device owner.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -2604,11 +2666,11 @@
 
         // Nonexisting permission returns null
         Intent intent = dpm.createAdminSupportIntent("disallow_nothing");
-        assertNull(intent);
+        assertThat(intent).isNull();
 
         // Existing permission that is not set returns null
         intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
-        assertNull(intent);
+        assertThat(intent).isNull();
 
         // Existing permission that is not set by device/profile owner returns null
         when(getServices().userManager.hasUserRestriction(
@@ -2616,7 +2678,7 @@
                 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
                 .thenReturn(true);
         intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
-        assertNull(intent);
+        assertThat(intent).isNull();
 
         // UM.getUserRestrictionSources() will return a list of size 1 with the caller resource.
         doAnswer((Answer<List<UserManager.EnforcingUser>>) invocation -> Collections.singletonList(
@@ -2626,51 +2688,53 @@
                 eq(UserManager.DISALLOW_ADJUST_VOLUME),
                 eq(UserHandle.of(UserHandle.myUserId())));
         intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
-        assertNotNull(intent);
-        assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction());
-        assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
-                intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
-        assertEquals(admin1, intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN));
-        assertEquals(UserManager.DISALLOW_ADJUST_VOLUME,
-                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
+        assertThat(intent).isNotNull();
+        assertThat(intent.getAction()).isEqualTo(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
+        assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, -1))
+                .isEqualTo(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID));
+        assertThat(
+                (ComponentName) intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN))
+                        .isEqualTo(admin1);
+        assertThat(intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION))
+                .isEqualTo(UserManager.DISALLOW_ADJUST_VOLUME);
 
         // Try with POLICY_DISABLE_CAMERA and POLICY_DISABLE_SCREEN_CAPTURE, which are not
         // user restrictions
 
         // Camera is not disabled
         intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
-        assertNull(intent);
+        assertThat(intent).isNull();
 
         // Camera is disabled
         dpm.setCameraDisabled(admin1, true);
         intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
-        assertNotNull(intent);
-        assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA,
-                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
+        assertThat(intent).isNotNull();
+        assertThat(intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION))
+                .isEqualTo(DevicePolicyManager.POLICY_DISABLE_CAMERA);
 
         // Screen capture is not disabled
         intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
-        assertNull(intent);
+        assertThat(intent).isNull();
 
         // Screen capture is disabled
         dpm.setScreenCaptureDisabled(admin1, true);
         intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
-        assertNotNull(intent);
-        assertEquals(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE,
-                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
+        assertThat(intent).isNotNull();
+        assertThat(intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION))
+                .isEqualTo(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
 
         // Same checks for different user
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         // Camera should be disabled by device owner
         intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
-        assertNotNull(intent);
-        assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA,
-                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
-        assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
-                intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
+        assertThat(intent).isNotNull();
+        assertThat(intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION))
+                .isEqualTo(DevicePolicyManager.POLICY_DISABLE_CAMERA);
+        assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, -1))
+                .isEqualTo(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID));
         // ScreenCapture should not be disabled by device owner
         intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
-        assertNull(intent);
+        assertThat(intent).isNull();
     }
 
     /**
@@ -2679,6 +2743,7 @@
      * {@link DevicePolicyManager#getAffiliationIds}
      * {@link DevicePolicyManager#isAffiliatedUser}
      */
+    @Test
     public void testUserAffiliation() throws Exception {
         mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
@@ -2686,20 +2751,20 @@
 
         // Check that the system user is unaffiliated.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
-        assertFalse(dpm.isAffiliatedUser());
+        assertThat(dpm.isAffiliatedUser()).isFalse();
 
         // Set a device owner on the system user. Check that the system user becomes affiliated.
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
-        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
-        assertTrue(dpm.isAffiliatedUser());
-        assertTrue(dpm.getAffiliationIds(admin1).isEmpty());
+        assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue();
+        assertThat(dpm.isAffiliatedUser()).isTrue();
+        assertThat(dpm.getAffiliationIds(admin1).isEmpty()).isTrue();
 
         // Install a profile owner. Check that the test user is unaffiliated.
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         setAsProfileOwner(admin2);
-        assertFalse(dpm.isAffiliatedUser());
-        assertTrue(dpm.getAffiliationIds(admin2).isEmpty());
+        assertThat(dpm.isAffiliatedUser()).isFalse();
+        assertThat(dpm.getAffiliationIds(admin2).isEmpty()).isTrue();
 
         // Have the profile owner specify a set of affiliation ids. Check that the test user remains
         // unaffiliated.
@@ -2709,7 +2774,7 @@
         userAffiliationIds.add("blue");
         dpm.setAffiliationIds(admin2, userAffiliationIds);
         MoreAsserts.assertContentsInAnyOrder(dpm.getAffiliationIds(admin2), "red", "green", "blue");
-        assertFalse(dpm.isAffiliatedUser());
+        assertThat(dpm.isAffiliatedUser()).isFalse();
 
         // Have the device owner specify a set of affiliation ids that do not intersect with those
         // specified by the profile owner. Check that the test user remains unaffiliated.
@@ -2722,7 +2787,7 @@
         MoreAsserts.assertContentsInAnyOrder(
             dpm.getAffiliationIds(admin1), "cyan", "yellow", "magenta");
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
-        assertFalse(dpm.isAffiliatedUser());
+        assertThat(dpm.isAffiliatedUser()).isFalse();
 
         // Have the profile owner specify a set of affiliation ids that intersect with those
         // specified by the device owner. Check that the test user becomes affiliated.
@@ -2730,33 +2795,36 @@
         dpm.setAffiliationIds(admin2, userAffiliationIds);
         MoreAsserts.assertContentsInAnyOrder(
             dpm.getAffiliationIds(admin2), "red", "green", "blue", "yellow");
-        assertTrue(dpm.isAffiliatedUser());
+        assertThat(dpm.isAffiliatedUser()).isTrue();
 
         // Clear affiliation ids for the profile owner. The user becomes unaffiliated.
         dpm.setAffiliationIds(admin2, Collections.emptySet());
-        assertTrue(dpm.getAffiliationIds(admin2).isEmpty());
-        assertFalse(dpm.isAffiliatedUser());
+        assertThat(dpm.getAffiliationIds(admin2).isEmpty()).isTrue();
+        assertThat(dpm.isAffiliatedUser()).isFalse();
 
         // Set affiliation ids again, then clear PO to check that the user becomes unaffiliated
         dpm.setAffiliationIds(admin2, userAffiliationIds);
-        assertTrue(dpm.isAffiliatedUser());
+        assertThat(dpm.isAffiliatedUser()).isTrue();
         dpm.clearProfileOwner(admin2);
-        assertFalse(dpm.isAffiliatedUser());
+        assertThat(dpm.isAffiliatedUser()).isFalse();
 
         // Check that the system user remains affiliated.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
-        assertTrue(dpm.isAffiliatedUser());
+        assertThat(dpm.isAffiliatedUser()).isTrue();
 
         // Clear the device owner - the user becomes unaffiliated.
         clearDeviceOwner();
-        assertFalse(dpm.isAffiliatedUser());
+        assertThat(dpm.isAffiliatedUser()).isFalse();
     }
 
+    @Test
     public void testGetUserProvisioningState_defaultResult() {
         mContext.callerPermissions.add(permission.MANAGE_USERS);
-        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
+        assertThat(dpm.getUserProvisioningState())
+                .isEqualTo(DevicePolicyManager.STATE_USER_UNMANAGED);
     }
 
+    @Test
     public void testSetUserProvisioningState_permission() throws Exception {
         setupProfileOwner();
 
@@ -2764,6 +2832,7 @@
                 DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
     }
 
+    @Test
     public void testSetUserProvisioningState_unprivileged() throws Exception {
         setupProfileOwner();
         assertExpectException(SecurityException.class, /* messageRegex =*/ null,
@@ -2771,6 +2840,7 @@
                         CALLER_USER_HANDLE));
     }
 
+    @Test
     public void testSetUserProvisioningState_noManagement() {
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         mContext.callerPermissions.add(permission.MANAGE_USERS);
@@ -2778,9 +2848,11 @@
                 /* messageRegex= */ "change provisioning state unless a .* owner is set",
                 () -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
                         CALLER_USER_HANDLE));
-        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
+        assertThat(dpm.getUserProvisioningState())
+                .isEqualTo(DevicePolicyManager.STATE_USER_UNMANAGED);
     }
 
+    @Test
     public void testSetUserProvisioningState_deviceOwnerFromSetupWizard() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -2790,6 +2862,7 @@
                 DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
     }
 
+    @Test
     public void testSetUserProvisioningState_deviceOwnerFromSetupWizardAlternative()
             throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -2800,6 +2873,7 @@
                 DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
     }
 
+    @Test
     public void testSetUserProvisioningState_deviceOwnerWithoutSetupWizard() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -2808,6 +2882,7 @@
                 DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
     }
 
+    @Test
     public void testSetUserProvisioningState_managedProfileFromSetupWizard_primaryUser()
             throws Exception {
         setupProfileOwner();
@@ -2817,6 +2892,7 @@
                 DevicePolicyManager.STATE_USER_PROFILE_FINALIZED);
     }
 
+    @Test
     public void testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile()
             throws Exception {
         setupProfileOwner();
@@ -2826,6 +2902,7 @@
                 DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
     }
 
+    @Test
     public void testSetUserProvisioningState_managedProfileWithoutSetupWizard() throws Exception {
         setupProfileOwner();
 
@@ -2833,6 +2910,7 @@
                 DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
     }
 
+    @Test
     public void testSetUserProvisioningState_illegalTransitionOutOfFinalized1() throws Exception {
         setupProfileOwner();
 
@@ -2843,6 +2921,7 @@
                         DevicePolicyManager.STATE_USER_UNMANAGED));
     }
 
+    @Test
     public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState()
             throws Exception {
         setupProfileOwner();
@@ -2858,10 +2937,11 @@
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         mContext.callerPermissions.add(permission.MANAGE_USERS);
 
-        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
+        assertThat(dpm.getUserProvisioningState())
+                .isEqualTo(DevicePolicyManager.STATE_USER_UNMANAGED);
         for (int state : states) {
             dpm.setUserProvisioningState(state, userId);
-            assertEquals(state, dpm.getUserProvisioningState());
+            assertThat(dpm.getUserProvisioningState()).isEqualTo(state);
         }
     }
 
@@ -2870,7 +2950,7 @@
 
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
         dpm.setActiveAdmin(admin1, false);
-        assertTrue(dpm.setProfileOwner(admin1, null, CALLER_USER_HANDLE));
+        assertThat(dpm.setProfileOwner(admin1, null, CALLER_USER_HANDLE)).isTrue();
 
         mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
     }
@@ -2880,7 +2960,7 @@
 
         setUpPackageManagerForAdmin(admin1, DpmMockContext.SYSTEM_UID);
         dpm.setActiveAdmin(admin1, false);
-        assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
+        assertThat(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue();
 
         mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
     }
@@ -2890,11 +2970,12 @@
 
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin1, false);
-        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
+        assertThat(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue();
 
         mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
     }
 
+    @Test
     public void testSetMaximumTimeToLock() {
         mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
 
@@ -2956,6 +3037,7 @@
         verifyStayOnWhilePluggedCleared(false);
     }
 
+    @Test
     public void testIsActiveSupervisionApp() throws Exception {
         when(mServiceContext.resources
                 .getString(R.string.config_defaultSupervisionProfileOwnerComponent))
@@ -2968,11 +3050,12 @@
 
         final DevicePolicyManagerInternal dpmi =
                 LocalServices.getService(DevicePolicyManagerInternal.class);
-        assertTrue(dpmi.isActiveSupervisionApp(PROFILE_ADMIN));
+        assertThat(dpmi.isActiveSupervisionApp(PROFILE_ADMIN)).isTrue();
     }
 
     // Test if lock timeout on managed profile is handled correctly depending on whether profile
     // uses separate challenge.
+    @Test
     public void testSetMaximumTimeToLockProfile() throws Exception {
         final int PROFILE_USER = 15;
         final int PROFILE_ADMIN = UserHandle.getUid(PROFILE_USER, 19436);
@@ -3039,6 +3122,7 @@
         verifyScreenTimeoutCall(Long.MAX_VALUE, UserHandle.USER_SYSTEM);
     }
 
+    @Test
     public void testSetRequiredStrongAuthTimeout_DeviceOwner() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -3055,8 +3139,8 @@
         getServices().buildMock.isDebuggable = false;
 
         dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE);
+        assertThat(MAX_MINUS_ONE_MINUTE).isEqualTo(dpm.getRequiredStrongAuthTimeout(admin1));
+        assertThat(MAX_MINUS_ONE_MINUTE).isEqualTo(dpm.getRequiredStrongAuthTimeout(null));
 
         verify(getServices().systemProperties, never()).getLong(anyString(), anyLong());
 
@@ -3067,45 +3151,47 @@
         dpm.setRequiredStrongAuthTimeout(admin1, 0);
 
         // aggregation should be the default if unset by any admin
-        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
-                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
+        assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS)
+                .isEqualTo(dpm.getRequiredStrongAuthTimeout(null));
 
         // admin not participating by default
-        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0);
+        assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(0);
 
         //clamping from the top
         dpm.setRequiredStrongAuthTimeout(admin1,
                 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1),
-                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
-                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
+        assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS)
+                .isEqualTo(dpm.getRequiredStrongAuthTimeout(admin1));
+        assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS)
+                .isEqualTo(dpm.getRequiredStrongAuthTimeout(null));
 
         // 0 means the admin is not participating, so default should be returned
         dpm.setRequiredStrongAuthTimeout(admin1, 0);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
-                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
+        assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(0);
+        assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS)
+                .isEqualTo(dpm.getRequiredStrongAuthTimeout(null));
 
         // clamping from the bottom
         dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS - ONE_MINUTE);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS);
+        assertThat(dpm.getRequiredStrongAuthTimeout(admin1))
+                .isEqualTo(MINIMUM_STRONG_AUTH_TIMEOUT_MS);
+        assertThat(dpm.getRequiredStrongAuthTimeout(null))
+                .isEqualTo(MINIMUM_STRONG_AUTH_TIMEOUT_MS);
 
         // values within range
         dpm.setRequiredStrongAuthTimeout(admin1, MIN_PLUS_ONE_MINUTE);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MIN_PLUS_ONE_MINUTE);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MIN_PLUS_ONE_MINUTE);
+        assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(MIN_PLUS_ONE_MINUTE);
+        assertThat(dpm.getRequiredStrongAuthTimeout(null)).isEqualTo(MIN_PLUS_ONE_MINUTE);
 
         dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE);
+        assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(MAX_MINUS_ONE_MINUTE);
+        assertThat(dpm.getRequiredStrongAuthTimeout(null)).isEqualTo(MAX_MINUS_ONE_MINUTE);
 
         // reset to default
         dpm.setRequiredStrongAuthTimeout(admin1, 0);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0);
-        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
-                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
+        assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(0);
+        assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS)
+                .isEqualTo(dpm.getRequiredStrongAuthTimeout(null));
 
         // negative value
         assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null,
@@ -3130,8 +3216,8 @@
     private void setup_DeviceAdminFeatureOff() throws Exception {
         when(getServices().packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
                 .thenReturn(false);
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(false);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(false);
         initializeDpms();
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
         when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
@@ -3141,6 +3227,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_DeviceAdminFeatureOff() throws Exception {
         setup_DeviceAdminFeatureOff();
         mContext.packageName = admin1.getPackageName();
@@ -3153,6 +3240,7 @@
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_DeviceAdminFeatureOff() throws Exception {
         setup_DeviceAdminFeatureOff();
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
@@ -3170,8 +3258,8 @@
     }
 
     private void setup_ManagedProfileFeatureOff() throws Exception {
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(false);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(false);
         initializeDpms();
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
         when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
@@ -3181,6 +3269,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_ManagedProfileFeatureOff() throws Exception {
         setup_ManagedProfileFeatureOff();
         mContext.packageName = admin1.getPackageName();
@@ -3202,6 +3291,7 @@
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_ManagedProfileFeatureOff() throws Exception {
         setup_ManagedProfileFeatureOff();
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
@@ -3233,8 +3323,8 @@
     }
 
     private void setup_nonSplitUser_firstBoot_primaryUser() throws Exception {
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(true);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
         when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
@@ -3244,6 +3334,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_nonSplitUser_firstBoot_primaryUser() throws Exception {
         setup_nonSplitUser_firstBoot_primaryUser();
         mContext.packageName = admin1.getPackageName();
@@ -3257,6 +3348,7 @@
                 false /* because of non-split user */);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_nonSplitUser_firstBoot_primaryUser()
             throws Exception {
         setup_nonSplitUser_firstBoot_primaryUser();
@@ -3275,8 +3367,8 @@
     }
 
     private void setup_nonSplitUser_afterDeviceSetup_primaryUser() throws Exception {
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(true);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
         when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(true);
@@ -3302,6 +3394,7 @@
                 true)).thenReturn(true);
     }
 
+    @Test
     public void testIsProvisioningAllowed_nonSplitUser_afterDeviceSetup_primaryUser()
             throws Exception {
         setup_nonSplitUser_afterDeviceSetup_primaryUser();
@@ -3318,6 +3411,7 @@
                 false/* because of non-split user */);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_nonSplitUser_afterDeviceSetup_primaryUser()
             throws Exception {
         setup_nonSplitUser_afterDeviceSetup_primaryUser();
@@ -3335,6 +3429,7 @@
                 DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
     }
 
+    @Test
     public void testProvisioning_nonSplitUser_withDo_primaryUser() throws Exception {
         setup_nonSplitUser_withDo_primaryUser();
         mContext.packageName = admin1.getPackageName();
@@ -3361,6 +3456,7 @@
                 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
     }
 
+    @Test
     public void testProvisioning_nonSplitUser_withDo_primaryUser_restrictedBySystem()
             throws Exception {
         setup_nonSplitUser_withDo_primaryUser();
@@ -3388,6 +3484,7 @@
                 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
     }
 
+    @Test
     public void testCheckCannotSetProfileOwnerWithDeviceOwner() throws Exception {
         setup_nonSplitUser_withDo_primaryUser();
         final int managedProfileUserId = 18;
@@ -3399,10 +3496,11 @@
         mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
         setUpPackageManagerForFakeAdmin(admin1, managedProfileAdminUid, admin1);
         dpm.setActiveAdmin(admin1, false, userId);
-        assertFalse(dpm.setProfileOwner(admin1, null, userId));
+        assertThat(dpm.setProfileOwner(admin1, null, userId)).isFalse();
         mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_nonSplitUser_attemptingComp() throws Exception {
         setup_nonSplitUser_withDo_primaryUser_ManagedProfile();
         mContext.packageName = admin1.getPackageName();
@@ -3420,6 +3518,7 @@
                 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_nonSplitUser_comp_cannot_remove_profile()
             throws Exception {
         setup_nonSplitUser_withDo_primaryUser_ManagedProfile();
@@ -3449,8 +3548,8 @@
     }
 
     private void setup_splitUser_firstBoot_systemUser() throws Exception {
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(true);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(false);
@@ -3459,6 +3558,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_splitUser_firstBoot_systemUser() throws Exception {
         setup_splitUser_firstBoot_systemUser();
         mContext.packageName = admin1.getPackageName();
@@ -3473,6 +3573,7 @@
                 false/* because calling uid is system user */);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_splitUser_firstBoot_systemUser()
             throws Exception {
         setup_splitUser_firstBoot_systemUser();
@@ -3491,8 +3592,8 @@
     }
 
     private void setup_splitUser_afterDeviceSetup_systemUser() throws Exception {
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(true);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(false);
@@ -3501,6 +3602,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_systemUser() throws Exception {
         setup_splitUser_afterDeviceSetup_systemUser();
         mContext.packageName = admin1.getPackageName();
@@ -3517,6 +3619,7 @@
                 false/* because calling uid is system user */);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_systemUser()
             throws Exception {
         setup_splitUser_afterDeviceSetup_systemUser();
@@ -3535,8 +3638,8 @@
     }
 
     private void setup_splitUser_firstBoot_primaryUser() throws Exception {
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(true);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
                 true)).thenReturn(true);
@@ -3545,6 +3648,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_splitUser_firstBoot_primaryUser() throws Exception {
         setup_splitUser_firstBoot_primaryUser();
         mContext.packageName = admin1.getPackageName();
@@ -3557,6 +3661,7 @@
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, true);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_splitUser_firstBoot_primaryUser()
             throws Exception {
         setup_splitUser_firstBoot_primaryUser();
@@ -3575,8 +3680,8 @@
     }
 
     private void setup_splitUser_afterDeviceSetup_primaryUser() throws Exception {
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(true);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE,
                 true)).thenReturn(true);
@@ -3585,6 +3690,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_primaryUser()
             throws Exception {
         setup_splitUser_afterDeviceSetup_primaryUser();
@@ -3601,6 +3707,7 @@
                 false/* because user setup completed */);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_primaryUser()
             throws Exception {
         setup_splitUser_afterDeviceSetup_primaryUser();
@@ -3621,8 +3728,8 @@
     private void setup_provisionManagedProfileWithDeviceOwner_systemUser() throws Exception {
         setDeviceOwner();
 
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(true);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
                 .thenReturn(false);
@@ -3631,6 +3738,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_systemUser()
             throws Exception {
         setup_provisionManagedProfileWithDeviceOwner_systemUser();
@@ -3640,6 +3748,7 @@
                 false /* can't provision managed profile on system user */);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_systemUser()
             throws Exception {
         setup_provisionManagedProfileWithDeviceOwner_systemUser();
@@ -3651,8 +3760,8 @@
     private void setup_provisionManagedProfileWithDeviceOwner_primaryUser() throws Exception {
         setDeviceOwner();
 
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(true);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false);
         when(getServices().userManager.getProfileParent(CALLER_USER_HANDLE))
             .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
@@ -3663,6 +3772,7 @@
         mContext.binder.callingUid = DpmMockContext.ANOTHER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_primaryUser()
             throws Exception {
         setup_provisionManagedProfileWithDeviceOwner_primaryUser();
@@ -3671,6 +3781,7 @@
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_primaryUser()
             throws Exception {
         setup_provisionManagedProfileWithDeviceOwner_primaryUser();
@@ -3684,8 +3795,8 @@
     private void setup_provisionManagedProfileCantRemoveUser_primaryUser() throws Exception {
         setDeviceOwner();
 
-        when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
-                .thenReturn(true);
+        when(getServices().ipackageManager
+                .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true);
         when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true);
         when(getServices().userManager.hasUserRestriction(
                 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
@@ -3700,6 +3811,7 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
     }
 
+    @Test
     public void testIsProvisioningAllowed_provisionManagedProfileCantRemoveUser_primaryUser()
             throws Exception {
         setup_provisionManagedProfileCantRemoveUser_primaryUser();
@@ -3708,6 +3820,7 @@
         assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_provisionManagedProfileCantRemoveUser_primaryUser()
             throws Exception {
         setup_provisionManagedProfileCantRemoveUser_primaryUser();
@@ -3716,6 +3829,7 @@
                 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE);
     }
 
+    @Test
     public void testCheckProvisioningPreCondition_permission() {
         // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
         assertExpectException(SecurityException.class, /* messageRegex =*/ null,
@@ -3723,12 +3837,14 @@
                         DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, "some.package"));
     }
 
+    @Test
     public void testForceUpdateUserSetupComplete_permission() {
         // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
         assertExpectException(SecurityException.class, /* messageRegex =*/ null,
                 () -> dpm.forceUpdateUserSetupComplete());
     }
 
+    @Test
     public void testForceUpdateUserSetupComplete_systemUser() {
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         // GIVEN calling from user 20
@@ -3737,6 +3853,7 @@
                 () -> dpm.forceUpdateUserSetupComplete());
     }
 
+    @Test
     public void testForceUpdateUserSetupComplete_userbuild() {
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -3753,14 +3870,15 @@
         // GIVEN it's user build
         getServices().buildMock.isDebuggable = false;
 
-        assertTrue(dpms.hasUserSetupCompleted());
+        assertThat(dpms.hasUserSetupCompleted()).isTrue();
 
         dpm.forceUpdateUserSetupComplete();
 
         // THEN the state in dpms is not changed
-        assertTrue(dpms.hasUserSetupCompleted());
+        assertThat(dpms.hasUserSetupCompleted()).isTrue();
     }
 
+    @Test
     public void testForceUpdateUserSetupComplete_userDebugbuild() {
         mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -3777,12 +3895,12 @@
         // GIVEN it's userdebug build
         getServices().buildMock.isDebuggable = true;
 
-        assertTrue(dpms.hasUserSetupCompleted());
+        assertThat(dpms.hasUserSetupCompleted()).isTrue();
 
         dpm.forceUpdateUserSetupComplete();
 
         // THEN the state in dpms is not changed
-        assertFalse(dpms.hasUserSetupCompleted());
+        assertThat(dpms.hasUserSetupCompleted()).isFalse();
     }
 
     private void clearDeviceOwner() throws Exception {
@@ -3795,6 +3913,7 @@
         });
     }
 
+    @Test
     public void testGetLastSecurityLogRetrievalTime() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -3806,7 +3925,7 @@
                 .thenReturn(true);
 
         // No logs were retrieved so far.
-        assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
+        assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(-1);
 
         // Enabling logging should not change the timestamp.
         dpm.setSecurityLoggingEnabled(admin1, true);
@@ -3814,55 +3933,56 @@
                 .securityLogSetLoggingEnabledProperty(true);
         when(getServices().settings.securityLogGetLoggingEnabledProperty())
                 .thenReturn(true);
-        assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
+        assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(-1);
 
         // Retrieving the logs should update the timestamp.
         final long beforeRetrieval = System.currentTimeMillis();
         dpm.retrieveSecurityLogs(admin1);
         final long firstSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
         final long afterRetrieval = System.currentTimeMillis();
-        assertTrue(firstSecurityLogRetrievalTime >= beforeRetrieval);
-        assertTrue(firstSecurityLogRetrievalTime <= afterRetrieval);
+        assertThat(firstSecurityLogRetrievalTime >= beforeRetrieval).isTrue();
+        assertThat(firstSecurityLogRetrievalTime <= afterRetrieval).isTrue();
 
         // Retrieving the pre-boot logs should update the timestamp.
         Thread.sleep(2);
         dpm.retrievePreRebootSecurityLogs(admin1);
         final long secondSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
-        assertTrue(secondSecurityLogRetrievalTime > firstSecurityLogRetrievalTime);
+        assertThat(secondSecurityLogRetrievalTime > firstSecurityLogRetrievalTime).isTrue();
 
         // Checking the timestamp again should not change it.
         Thread.sleep(2);
-        assertEquals(secondSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
+        assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(secondSecurityLogRetrievalTime);
 
         // Retrieving the logs again should update the timestamp.
         dpm.retrieveSecurityLogs(admin1);
         final long thirdSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
-        assertTrue(thirdSecurityLogRetrievalTime > secondSecurityLogRetrievalTime);
+        assertThat(thirdSecurityLogRetrievalTime > secondSecurityLogRetrievalTime).isTrue();
 
         // Disabling logging should not change the timestamp.
         Thread.sleep(2);
         dpm.setSecurityLoggingEnabled(admin1, false);
-        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
+        assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(thirdSecurityLogRetrievalTime);
 
         // Restarting the DPMS should not lose the timestamp.
         initializeDpms();
-        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
+        assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(thirdSecurityLogRetrievalTime);
 
         // Any uid holding MANAGE_USERS permission can retrieve the timestamp.
         mContext.binder.callingUid = 1234567;
         mContext.callerPermissions.add(permission.MANAGE_USERS);
-        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
+        assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(thirdSecurityLogRetrievalTime);
         mContext.callerPermissions.remove(permission.MANAGE_USERS);
 
         // System can retrieve the timestamp.
         mContext.binder.clearCallingIdentity();
-        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
+        assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(thirdSecurityLogRetrievalTime);
 
         // Removing the device owner should clear the timestamp.
         clearDeviceOwner();
-        assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
+        assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(-1);
     }
 
+    @Test
     public void testSetConfiguredNetworksLockdownStateWithDO() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -3875,6 +3995,7 @@
                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0);
     }
 
+    @Test
     public void testSetConfiguredNetworksLockdownStateWithPO() throws Exception {
         setupProfileOwner();
         assertExpectException(SecurityException.class, null,
@@ -3883,6 +4004,7 @@
                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0);
     }
 
+    @Test
     public void testSetConfiguredNetworksLockdownStateWithPOOfOrganizationOwnedDevice()
             throws Exception {
         setupProfileOwner();
@@ -3896,6 +4018,7 @@
                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0);
     }
 
+    @Test
     public void testSetSystemSettingFailWithNonWhitelistedSettings() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -3903,6 +4026,7 @@
                 dpm.setSystemSetting(admin1, Settings.System.SCREEN_BRIGHTNESS_FOR_VR, "0"));
     }
 
+    @Test
     public void testSetSystemSettingWithDO() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -3911,6 +4035,7 @@
                 Settings.System.SCREEN_BRIGHTNESS, "0", UserHandle.USER_SYSTEM);
     }
 
+    @Test
     public void testSetSystemSettingWithPO() throws Exception {
         setupProfileOwner();
         dpm.setSystemSetting(admin1, Settings.System.SCREEN_BRIGHTNESS, "0");
@@ -3918,6 +4043,7 @@
             Settings.System.SCREEN_BRIGHTNESS, "0", CALLER_USER_HANDLE);
     }
 
+    @Test
     public void testSetAutoTimeEnabledModifiesSetting() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -3928,6 +4054,7 @@
         verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0);
     }
 
+    @Test
     public void testSetAutoTimeEnabledWithPOOnUser0() throws Exception {
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         setupProfileOwnerOnUser0();
@@ -3938,6 +4065,7 @@
         verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0);
     }
 
+    @Test
     public void testSetAutoTimeEnabledFailWithPONotOnUser0() throws Exception {
         setupProfileOwner();
         assertExpectException(SecurityException.class, null,
@@ -3945,6 +4073,7 @@
         verify(getServices().settings, never()).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0);
     }
 
+    @Test
     public void testSetAutoTimeEnabledWithPOOfOrganizationOwnedDevice() throws Exception {
         setupProfileOwner();
         configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
@@ -3956,6 +4085,7 @@
         verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0);
     }
 
+    @Test
     public void testSetAutoTimeZoneEnabledModifiesSetting() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -3966,6 +4096,7 @@
         verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 0);
     }
 
+    @Test
     public void testSetAutoTimeZoneEnabledWithPOOnUser0() throws Exception {
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         setupProfileOwnerOnUser0();
@@ -3976,6 +4107,7 @@
         verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 0);
     }
 
+    @Test
     public void testSetAutoTimeZoneEnabledFailWithPONotOnUser0() throws Exception {
         setupProfileOwner();
         assertExpectException(SecurityException.class, null,
@@ -3984,6 +4116,7 @@
                 0);
     }
 
+    @Test
     public void testSetAutoTimeZoneEnabledWithPOOfOrganizationOwnedDevice() throws Exception {
         setupProfileOwner();
         configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
@@ -3995,12 +4128,13 @@
         verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 0);
     }
 
+    @Test
     public void testIsOrganizationOwnedDevice() throws Exception {
         // Set up the user manager to return correct user info
         addManagedProfile(admin1, DpmMockContext.CALLER_UID, admin1);
 
         // Any caller should be able to call this method.
-        assertFalse(dpm.isOrganizationOwnedDeviceWithManagedProfile());
+        assertThat(dpm.isOrganizationOwnedDeviceWithManagedProfile()).isFalse();
         configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
 
         verify(getServices().userManager).setUserRestriction(
@@ -4008,13 +4142,14 @@
                 eq(true),
                 eq(UserHandle.of(UserHandle.USER_SYSTEM)));
 
-        assertTrue(dpm.isOrganizationOwnedDeviceWithManagedProfile());
+        assertThat(dpm.isOrganizationOwnedDeviceWithManagedProfile()).isTrue();
 
         // A random caller from another user should also be able to get the right result.
         mContext.binder.callingUid = DpmMockContext.ANOTHER_UID;
-        assertTrue(dpm.isOrganizationOwnedDeviceWithManagedProfile());
+        assertThat(dpm.isOrganizationOwnedDeviceWithManagedProfile()).isTrue();
     }
 
+    @Test
     public void testMarkOrganizationOwnedDevice_baseRestrictionsAdded() throws Exception {
         addManagedProfile(admin1, DpmMockContext.CALLER_UID, admin1);
 
@@ -4044,6 +4179,7 @@
                 parentDpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER));
     }
 
+    @Test
     public void testSetTime() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -4051,11 +4187,13 @@
         verify(getServices().alarmManager).setTime(0);
     }
 
+    @Test
     public void testSetTimeFailWithPO() throws Exception {
         setupProfileOwner();
         assertExpectException(SecurityException.class, null, () -> dpm.setTime(admin1, 0));
     }
 
+    @Test
     public void testSetTimeWithPOOfOrganizationOwnedDevice() throws Exception {
         setupProfileOwner();
         configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
@@ -4063,14 +4201,16 @@
         verify(getServices().alarmManager).setTime(0);
     }
 
+    @Test
     public void testSetTimeWithAutoTimeOn() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
         when(getServices().settings.settingsGlobalGetInt(Settings.Global.AUTO_TIME, 0))
                 .thenReturn(1);
-        assertFalse(dpm.setTime(admin1, 0));
+        assertThat(dpm.setTime(admin1, 0)).isFalse();
     }
 
+    @Test
     public void testSetTimeZone() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -4078,12 +4218,14 @@
         verify(getServices().alarmManager).setTimeZone("Asia/Shanghai");
     }
 
+    @Test
     public void testSetTimeZoneFailWithPO() throws Exception {
         setupProfileOwner();
         assertExpectException(SecurityException.class, null,
                 () -> dpm.setTimeZone(admin1, "Asia/Shanghai"));
     }
 
+    @Test
     public void testSetTimeZoneWithPOOfOrganizationOwnedDevice() throws Exception {
         setupProfileOwner();
         configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
@@ -4091,14 +4233,16 @@
         verify(getServices().alarmManager).setTimeZone("Asia/Shanghai");
     }
 
+    @Test
     public void testSetTimeZoneWithAutoTimeZoneOn() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
         when(getServices().settings.settingsGlobalGetInt(Settings.Global.AUTO_TIME_ZONE, 0))
                 .thenReturn(1);
-        assertFalse(dpm.setTimeZone(admin1, "Asia/Shanghai"));
+        assertThat(dpm.setTimeZone(admin1, "Asia/Shanghai")).isFalse();
     }
 
+    @Test
     public void testGetLastBugReportRequestTime() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -4115,39 +4259,40 @@
         getServices().removeUser(CALLER_USER_HANDLE);
 
         // No bug reports were requested so far.
-        assertEquals(-1, dpm.getLastBugReportRequestTime());
+        assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(-1);
 
         // Requesting a bug report should update the timestamp.
         final long beforeRequest = System.currentTimeMillis();
         dpm.requestBugreport(admin1);
         final long bugReportRequestTime = dpm.getLastBugReportRequestTime();
         final long afterRequest = System.currentTimeMillis();
-        assertTrue(bugReportRequestTime >= beforeRequest);
-        assertTrue(bugReportRequestTime <= afterRequest);
+        assertThat(bugReportRequestTime).isAtLeast(beforeRequest);
+        assertThat(bugReportRequestTime).isAtMost(afterRequest);
 
         // Checking the timestamp again should not change it.
         Thread.sleep(2);
-        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
+        assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(bugReportRequestTime);
 
         // Restarting the DPMS should not lose the timestamp.
         initializeDpms();
-        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
+        assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(bugReportRequestTime);
 
         // Any uid holding MANAGE_USERS permission can retrieve the timestamp.
         mContext.binder.callingUid = 1234567;
         mContext.callerPermissions.add(permission.MANAGE_USERS);
-        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
+        assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(bugReportRequestTime);
         mContext.callerPermissions.remove(permission.MANAGE_USERS);
 
         // System can retrieve the timestamp.
         mContext.binder.clearCallingIdentity();
-        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
+        assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(bugReportRequestTime);
 
         // Removing the device owner should clear the timestamp.
         clearDeviceOwner();
-        assertEquals(-1, dpm.getLastBugReportRequestTime());
+        assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(-1);
     }
 
+    @Test
     public void testGetLastNetworkLogRetrievalTime() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -4165,57 +4310,58 @@
                 .thenReturn(true);
 
         // No logs were retrieved so far.
-        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
+        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1);
 
         // Attempting to retrieve logs without enabling logging should not change the timestamp.
         dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
-        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
+        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1);
 
         // Enabling logging should not change the timestamp.
         dpm.setNetworkLoggingEnabled(admin1, true);
-        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
+        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1);
 
         // Retrieving the logs should update the timestamp.
         final long beforeRetrieval = System.currentTimeMillis();
         dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
         final long firstNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime();
         final long afterRetrieval = System.currentTimeMillis();
-        assertTrue(firstNetworkLogRetrievalTime >= beforeRetrieval);
-        assertTrue(firstNetworkLogRetrievalTime <= afterRetrieval);
+        assertThat(firstNetworkLogRetrievalTime >= beforeRetrieval).isTrue();
+        assertThat(firstNetworkLogRetrievalTime <= afterRetrieval).isTrue();
 
         // Checking the timestamp again should not change it.
         Thread.sleep(2);
-        assertEquals(firstNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
+        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(firstNetworkLogRetrievalTime);
 
         // Retrieving the logs again should update the timestamp.
         dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
         final long secondNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime();
-        assertTrue(secondNetworkLogRetrievalTime > firstNetworkLogRetrievalTime);
+        assertThat(secondNetworkLogRetrievalTime > firstNetworkLogRetrievalTime).isTrue();
 
         // Disabling logging should not change the timestamp.
         Thread.sleep(2);
         dpm.setNetworkLoggingEnabled(admin1, false);
-        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
+        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(secondNetworkLogRetrievalTime);
 
         // Restarting the DPMS should not lose the timestamp.
         initializeDpms();
-        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
+        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(secondNetworkLogRetrievalTime);
 
         // Any uid holding MANAGE_USERS permission can retrieve the timestamp.
         mContext.binder.callingUid = 1234567;
         mContext.callerPermissions.add(permission.MANAGE_USERS);
-        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
+        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(secondNetworkLogRetrievalTime);
         mContext.callerPermissions.remove(permission.MANAGE_USERS);
 
         // System can retrieve the timestamp.
         mContext.binder.clearCallingIdentity();
-        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
+        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(secondNetworkLogRetrievalTime);
 
         // Removing the device owner should clear the timestamp.
         clearDeviceOwner();
-        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
+        assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1);
     }
 
+    @Test
     public void testGetBindDeviceAdminTargetUsers() throws Exception {
         // Setup device owner.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -4268,9 +4414,9 @@
         dpm.setLockTaskPackages(who, packages);
         MoreAsserts.assertEquals(packages, dpm.getLockTaskPackages(who));
         for (String p : packages) {
-            assertTrue(dpm.isLockTaskPermitted(p));
+            assertThat(dpm.isLockTaskPermitted(p)).isTrue();
         }
-        assertFalse(dpm.isLockTaskPermitted("anotherPackage"));
+        assertThat(dpm.isLockTaskPermitted("anotherPackage")).isFalse();
         // Test to see if set lock task features can be set
         dpm.setLockTaskFeatures(who, flags);
         verifyLockTaskState(userId, packages, flags);
@@ -4283,11 +4429,12 @@
                 () -> dpm.setLockTaskPackages(who, packages));
         assertExpectException(SecurityException.class, /* messageRegex =*/ null,
                 () -> dpm.getLockTaskPackages(who));
-        assertFalse(dpm.isLockTaskPermitted("doPackage1"));
+        assertThat(dpm.isLockTaskPermitted("doPackage1")).isFalse();
         assertExpectException(SecurityException.class, /* messageRegex =*/ null,
                 () -> dpm.setLockTaskFeatures(who, flags));
     }
 
+    @Test
     public void testLockTaskPolicyForProfileOwner() throws Exception {
         // Setup a PO
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
@@ -4315,9 +4462,11 @@
         final int mpoFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS
                 | DevicePolicyManager.LOCK_TASK_FEATURE_HOME
                 | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
-        verifyCanNotSetLockTask(MANAGED_PROFILE_ADMIN_UID, adminDifferentPackage, mpoPackages, mpoFlags);
+        verifyCanNotSetLockTask(MANAGED_PROFILE_ADMIN_UID, adminDifferentPackage, mpoPackages,
+                mpoFlags);
     }
 
+    @Test
     public void testLockTaskFeatures_IllegalArgumentException() throws Exception {
         // Setup a device owner.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -4332,12 +4481,13 @@
                 () -> dpm.setLockTaskFeatures(admin1, flags));
     }
 
+    @Test
     public void testSecondaryLockscreen_profileOwner() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
         // Initial state is disabled.
-        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
-                CALLER_USER_HANDLE)));
+        assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
+        CALLER_USER_HANDLE))).isFalse();
 
         // Profile owner can set enabled state.
         setAsProfileOwner(admin1);
@@ -4345,8 +4495,8 @@
                 .getString(R.string.config_defaultSupervisionProfileOwnerComponent))
                 .thenReturn(admin1.flattenToString());
         dpm.setSecondaryLockscreenEnabled(admin1, true);
-        assertTrue(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
-                CALLER_USER_HANDLE)));
+        assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(
+        CALLER_USER_HANDLE))).isTrue();
 
         // Managed profile managed by different package is unaffiliated - cannot set enabled.
         final int managedProfileUserId = 15;
@@ -4359,11 +4509,13 @@
                 () -> dpm.setSecondaryLockscreenEnabled(adminDifferentPackage, false));
     }
 
+    @Test
     public void testSecondaryLockscreen_deviceOwner() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
         // Initial state is disabled.
-        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(UserHandle.USER_SYSTEM)));
+        assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(UserHandle.USER_SYSTEM)))
+                .isFalse();
 
         // Device owners can set enabled state.
         setupDeviceOwner();
@@ -4371,14 +4523,16 @@
                 .getString(R.string.config_defaultSupervisionProfileOwnerComponent))
                 .thenReturn(admin1.flattenToString());
         dpm.setSecondaryLockscreenEnabled(admin1, true);
-        assertTrue(dpm.isSecondaryLockscreenEnabled(UserHandle.of(UserHandle.USER_SYSTEM)));
+        assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(UserHandle.USER_SYSTEM)))
+                .isTrue();
     }
 
+    @Test
     public void testSecondaryLockscreen_nonOwner() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
         // Initial state is disabled.
-        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
+        assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse();
 
         // Non-DO/PO cannot set enabled state.
         when(mServiceContext.resources
@@ -4386,9 +4540,10 @@
                 .thenReturn(admin1.flattenToString());
         assertExpectException(SecurityException.class, /* messageRegex= */ null,
                 () -> dpm.setSecondaryLockscreenEnabled(admin1, true));
-        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
+        assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse();
     }
 
+    @Test
     public void testSecondaryLockscreen_nonSupervisionApp() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
 
@@ -4403,13 +4558,13 @@
                 eq(CALLER_USER_HANDLE));
 
         // Initial state is disabled.
-        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
+        assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse();
 
         // Caller is Profile Owner, but no supervision app is configured.
         setAsProfileOwner(admin1);
         assertExpectException(SecurityException.class, "is not the default supervision component",
                 () -> dpm.setSecondaryLockscreenEnabled(admin1, true));
-        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
+        assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse();
 
         // Caller is Profile Owner, but is not the default configured supervision app.
         when(mServiceContext.resources
@@ -4417,22 +4572,23 @@
                 .thenReturn(admin2.flattenToString());
         assertExpectException(SecurityException.class, "is not the default supervision component",
                 () -> dpm.setSecondaryLockscreenEnabled(admin1, true));
-        assertFalse(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE)));
+        assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse();
     }
 
+    @Test
     public void testIsDeviceManaged() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
 
         // The device owner itself, any uid holding MANAGE_USERS permission and the system can
         // find out that the device has a device owner.
-        assertTrue(dpm.isDeviceManaged());
+        assertThat(dpm.isDeviceManaged()).isTrue();
         mContext.binder.callingUid = 1234567;
         mContext.callerPermissions.add(permission.MANAGE_USERS);
-        assertTrue(dpm.isDeviceManaged());
+        assertThat(dpm.isDeviceManaged()).isTrue();
         mContext.callerPermissions.remove(permission.MANAGE_USERS);
         mContext.binder.clearCallingIdentity();
-        assertTrue(dpm.isDeviceManaged());
+        assertThat(dpm.isDeviceManaged()).isTrue();
 
         clearDeviceOwner();
 
@@ -4440,12 +4596,13 @@
         // not have a device owner.
         mContext.binder.callingUid = 1234567;
         mContext.callerPermissions.add(permission.MANAGE_USERS);
-        assertFalse(dpm.isDeviceManaged());
+        assertThat(dpm.isDeviceManaged()).isFalse();
         mContext.callerPermissions.remove(permission.MANAGE_USERS);
         mContext.binder.clearCallingIdentity();
-        assertFalse(dpm.isDeviceManaged());
+        assertThat(dpm.isDeviceManaged()).isFalse();
     }
 
+    @Test
     public void testDeviceOwnerOrganizationName() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -4453,23 +4610,24 @@
         dpm.setOrganizationName(admin1, "organization");
 
         // Device owner can retrieve organization managing the device.
-        assertEquals("organization", dpm.getDeviceOwnerOrganizationName());
+        assertThat(dpm.getDeviceOwnerOrganizationName()).isEqualTo("organization");
 
         // Any uid holding MANAGE_USERS permission can retrieve organization managing the device.
         mContext.binder.callingUid = 1234567;
         mContext.callerPermissions.add(permission.MANAGE_USERS);
-        assertEquals("organization", dpm.getDeviceOwnerOrganizationName());
+        assertThat(dpm.getDeviceOwnerOrganizationName()).isEqualTo("organization");
         mContext.callerPermissions.remove(permission.MANAGE_USERS);
 
         // System can retrieve organization managing the device.
         mContext.binder.clearCallingIdentity();
-        assertEquals("organization", dpm.getDeviceOwnerOrganizationName());
+        assertThat(dpm.getDeviceOwnerOrganizationName()).isEqualTo("organization");
 
         // Removing the device owner clears the organization managing the device.
         clearDeviceOwner();
-        assertNull(dpm.getDeviceOwnerOrganizationName());
+        assertThat(dpm.getDeviceOwnerOrganizationName()).isNull();
     }
 
+    @Test
     public void testWipeDataManagedProfile() throws Exception {
         final int MANAGED_PROFILE_USER_ID = 15;
         final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
@@ -4489,6 +4647,7 @@
                 MANAGED_PROFILE_USER_ID);
     }
 
+    @Test
     public void testWipeDataManagedProfileDisallowed() throws Exception {
         final int MANAGED_PROFILE_USER_ID = 15;
         final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
@@ -4512,6 +4671,7 @@
                 () -> dpm.wipeData(0));
     }
 
+    @Test
     public void testWipeDataDeviceOwner() throws Exception {
         setDeviceOwner();
         when(getServices().userManager.getUserRestrictionSource(
@@ -4527,6 +4687,7 @@
                 /*wipeEuicc=*/ eq(false));
     }
 
+    @Test
     public void testWipeEuiccDataEnabled() throws Exception {
         setDeviceOwner();
         when(getServices().userManager.getUserRestrictionSource(
@@ -4542,6 +4703,7 @@
                 /*wipeEuicc=*/ eq(true));
     }
 
+    @Test
     public void testWipeDataDeviceOwnerDisallowed() throws Exception {
         setDeviceOwner();
         when(getServices().userManager.getUserRestrictionSource(
@@ -4556,6 +4718,7 @@
                 () -> dpm.wipeData(0));
     }
 
+    @Test
     public void testMaximumFailedPasswordAttemptsReachedManagedProfile() throws Exception {
         final int MANAGED_PROFILE_USER_ID = 15;
         final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
@@ -4588,6 +4751,7 @@
         verifyZeroInteractions(getServices().recoverySystem);
     }
 
+    @Test
     public void testMaximumFailedPasswordAttemptsReachedManagedProfileDisallowed()
             throws Exception {
         final int MANAGED_PROFILE_USER_ID = 15;
@@ -4621,6 +4785,7 @@
         verifyZeroInteractions(getServices().recoverySystem);
     }
 
+    @Test
     public void testMaximumFailedPasswordAttemptsReachedDeviceOwner() throws Exception {
         setDeviceOwner();
         when(getServices().userManager.getUserRestrictionSource(
@@ -4643,6 +4808,7 @@
                 /*wipeEuicc=*/ eq(false));
     }
 
+    @Test
     public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception {
         setDeviceOwner();
         when(getServices().userManager.getUserRestrictionSource(
@@ -4664,6 +4830,7 @@
                 .removeUserEvenWhenDisallowed(anyInt());
     }
 
+    @Test
     public void testMaximumFailedDevicePasswordAttemptsReachedOrgOwnedManagedProfile()
             throws Exception {
         final int MANAGED_PROFILE_USER_ID = 15;
@@ -4679,16 +4846,16 @@
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
         dpm.setMaximumFailedPasswordsForWipe(admin1, 3);
 
-        assertEquals(3, dpm.getMaximumFailedPasswordsForWipe(admin1));
-        assertEquals(3, dpm.getMaximumFailedPasswordsForWipe(null));
+        assertThat(dpm.getMaximumFailedPasswordsForWipe(admin1)).isEqualTo(3);
+        assertThat(dpm.getMaximumFailedPasswordsForWipe(null)).isEqualTo(3);
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
 
-        assertEquals(3, dpm.getMaximumFailedPasswordsForWipe(null, UserHandle.USER_SYSTEM));
+        assertThat(dpm.getMaximumFailedPasswordsForWipe(null, UserHandle.USER_SYSTEM)).isEqualTo(3);
         // Check that primary will be wiped as a result of failed primary user unlock attempts.
-        assertEquals(UserHandle.USER_SYSTEM,
-                dpm.getProfileWithMinimumFailedPasswordsForWipe(UserHandle.USER_SYSTEM));
+        assertThat(dpm.getProfileWithMinimumFailedPasswordsForWipe(UserHandle.USER_SYSTEM))
+                .isEqualTo(UserHandle.USER_SYSTEM);
 
         // Failed password attempts on the parent user are taken into account, as there isn't a
         // separate work challenge.
@@ -4702,6 +4869,7 @@
                 /*wipeEuicc=*/ eq(false));
     }
 
+    @Test
     public void testMaximumFailedProfilePasswordAttemptsReachedOrgOwnedManagedProfile()
             throws Exception {
         final int MANAGED_PROFILE_USER_ID = 15;
@@ -4724,14 +4892,15 @@
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
 
-        assertEquals(0, dpm.getMaximumFailedPasswordsForWipe(null, UserHandle.USER_SYSTEM));
-        assertEquals(3, dpm.getMaximumFailedPasswordsForWipe(null, MANAGED_PROFILE_USER_ID));
+        assertThat(dpm.getMaximumFailedPasswordsForWipe(null, UserHandle.USER_SYSTEM)).isEqualTo(0);
+        assertThat(dpm.getMaximumFailedPasswordsForWipe(null, MANAGED_PROFILE_USER_ID))
+                .isEqualTo(3);
         // Check that the policy is not affecting primary profile challenge.
-        assertEquals(UserHandle.USER_NULL,
-                dpm.getProfileWithMinimumFailedPasswordsForWipe(UserHandle.USER_SYSTEM));
+        assertThat(dpm.getProfileWithMinimumFailedPasswordsForWipe(UserHandle.USER_SYSTEM))
+                .isEqualTo(UserHandle.USER_NULL);
         // Check that primary will be wiped as a result of failed profile unlock attempts.
-        assertEquals(UserHandle.USER_SYSTEM,
-                dpm.getProfileWithMinimumFailedPasswordsForWipe(MANAGED_PROFILE_USER_ID));
+        assertThat(dpm.getProfileWithMinimumFailedPasswordsForWipe(MANAGED_PROFILE_USER_ID))
+                .isEqualTo(UserHandle.USER_SYSTEM);
 
         // Simulate three failed attempts at solving the separate challenge.
         dpm.reportFailedPasswordAttempt(MANAGED_PROFILE_USER_ID);
@@ -4744,6 +4913,7 @@
                 /*wipeEuicc=*/ eq(false));
     }
 
+    @Test
     public void testGetPermissionGrantState() throws Exception {
         final String permission = "some.permission";
         final String app1 = "com.example.app1";
@@ -4766,10 +4936,10 @@
         // System can retrieve permission grant state.
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
         mContext.packageName = "android";
-        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
-                dpm.getPermissionGrantState(null, app1, permission));
-        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT,
-                dpm.getPermissionGrantState(null, app2, permission));
+        assertThat(dpm.getPermissionGrantState(null, app1, permission))
+                .isEqualTo(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+        assertThat(dpm.getPermissionGrantState(null, app2, permission))
+                .isEqualTo(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
 
         // A regular app cannot retrieve permission grant state.
         mContext.binder.callingUid = setupPackageInPackageManager(app1, 1);
@@ -4781,12 +4951,13 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         mContext.packageName = admin1.getPackageName();
         setAsProfileOwner(admin1);
-        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
-                dpm.getPermissionGrantState(admin1, app1, permission));
-        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT,
-                dpm.getPermissionGrantState(admin1, app2, permission));
+        assertThat(dpm.getPermissionGrantState(admin1, app1, permission))
+                .isEqualTo(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+        assertThat(dpm.getPermissionGrantState(admin1, app2, permission))
+                .isEqualTo(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
     }
 
+    @Test
     public void testResetPasswordWithToken() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         setupDeviceOwner();
@@ -4801,27 +4972,26 @@
         when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM),
                 nullable(EscrowTokenStateChangeCallback.class)))
                 .thenReturn(handle);
-        assertTrue(dpm.setResetPasswordToken(admin1, token));
+        assertThat(dpm.setResetPasswordToken(admin1, token)).isTrue();
 
         // test password activation
-        when(getServices().lockPatternUtils.isEscrowTokenActive(eq(handle), eq(UserHandle.USER_SYSTEM)))
-            .thenReturn(true);
-        assertTrue(dpm.isResetPasswordTokenActive(admin1));
+        when(getServices().lockPatternUtils.isEscrowTokenActive(handle, UserHandle.USER_SYSTEM))
+                .thenReturn(true);
+        assertThat(dpm.isResetPasswordTokenActive(admin1)).isTrue();
 
         // test reset password with token
         when(getServices().lockPatternUtils.setLockCredentialWithToken(
-                eq(LockscreenCredential.createPassword(password)),
-                eq(handle), eq(token),
-                eq(UserHandle.USER_SYSTEM)))
-                .thenReturn(true);
-        assertTrue(dpm.resetPasswordWithToken(admin1, password, token, 0));
+                LockscreenCredential.createPassword(password), handle, token,
+                UserHandle.USER_SYSTEM)).thenReturn(true);
+        assertThat(dpm.resetPasswordWithToken(admin1, password, token, 0)).isTrue();
 
         // test removing a token
-        when(getServices().lockPatternUtils.removeEscrowToken(eq(handle), eq(UserHandle.USER_SYSTEM)))
+        when(getServices().lockPatternUtils.removeEscrowToken(handle, UserHandle.USER_SYSTEM))
                 .thenReturn(true);
-        assertTrue(dpm.clearResetPasswordToken(admin1));
+        assertThat(dpm.clearResetPasswordToken(admin1)).isTrue();
     }
 
+    @Test
     public void testIsActivePasswordSufficient() throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         mContext.packageName = admin1.getPackageName();
@@ -4841,11 +5011,11 @@
         PasswordMetrics passwordMetricsNoSymbols = computeForPassword("abcdXYZ5".getBytes());
 
         setActivePasswordState(passwordMetricsNoSymbols);
-        assertTrue(dpm.isActivePasswordSufficient());
+        assertThat(dpm.isActivePasswordSufficient()).isTrue();
 
         initializeDpms();
         reset(mContext.spiedContext);
-        assertTrue(dpm.isActivePasswordSufficient());
+        assertThat(dpm.isActivePasswordSufficient()).isTrue();
 
         // This call simulates the user entering the password for the first time after a reboot.
         // This causes password metrics to be reloaded into memory.  Until this happens,
@@ -4854,23 +5024,24 @@
         // requirements.  This is a known limitation of the current implementation of
         // isActivePasswordSufficient() - see b/34218769.
         setActivePasswordState(passwordMetricsNoSymbols);
-        assertTrue(dpm.isActivePasswordSufficient());
+        assertThat(dpm.isActivePasswordSufficient()).isTrue();
 
         dpm.setPasswordMinimumSymbols(admin1, 1);
         // This assertion would fail if we had not called setActivePasswordState() again after
         // initializeDpms() - see previous comment.
-        assertFalse(dpm.isActivePasswordSufficient());
+        assertThat(dpm.isActivePasswordSufficient()).isFalse();
 
         initializeDpms();
         reset(mContext.spiedContext);
-        assertFalse(dpm.isActivePasswordSufficient());
+        assertThat(dpm.isActivePasswordSufficient()).isFalse();
 
         PasswordMetrics passwordMetricsWithSymbols = computeForPassword("abcd.XY5".getBytes());
 
         setActivePasswordState(passwordMetricsWithSymbols);
-        assertTrue(dpm.isActivePasswordSufficient());
+        assertThat(dpm.isActivePasswordSufficient()).isTrue();
     }
 
+    @Test
     public void testIsActivePasswordSufficient_noLockScreen() throws Exception {
         // If there is no lock screen, the password is considered empty no matter what, because
         // it provides no security.
@@ -4885,7 +5056,7 @@
                 .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE));
 
         // If no password requirements are set, isActivePasswordSufficient should succeed.
-        assertTrue(dpm.isActivePasswordSufficient());
+        assertThat(dpm.isActivePasswordSufficient()).isTrue();
 
         // Now set some password quality requirements.
         dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
@@ -4900,9 +5071,10 @@
                 MockUtils.checkUserHandle(userHandle));
 
         // The active (nonexistent) password doesn't comply with the requirements.
-        assertFalse(dpm.isActivePasswordSufficient());
+        assertThat(dpm.isActivePasswordSufficient()).isFalse();
     }
 
+    @Test
     public void testIsPasswordSufficientAfterProfileUnification() throws Exception {
         final int managedProfileUserId = CALLER_USER_HANDLE;
         final int managedProfileAdminUid =
@@ -4921,13 +5093,13 @@
 
         // Numeric password is compliant with current requirement (QUALITY_NUMERIC set explicitly
         // on the parent admin)
-        assertTrue(dpm.isPasswordSufficientAfterProfileUnification(UserHandle.USER_SYSTEM,
-                UserHandle.USER_NULL));
+        assertThat(dpm.isPasswordSufficientAfterProfileUnification(UserHandle.USER_SYSTEM,
+        UserHandle.USER_NULL)).isTrue();
         // Numeric password is not compliant if profile is to be unified: the profile has a
         // QUALITY_ALPHABETIC policy on itself which will be enforced on the password after
         // unification.
-        assertFalse(dpm.isPasswordSufficientAfterProfileUnification(UserHandle.USER_SYSTEM,
-                managedProfileUserId));
+        assertThat(dpm.isPasswordSufficientAfterProfileUnification(UserHandle.USER_SYSTEM,
+        managedProfileUserId)).isFalse();
     }
 
     private void setActivePasswordState(PasswordMetrics passwordMetrics)
@@ -4961,6 +5133,7 @@
         mContext.binder.restoreCallingIdentity(ident);
     }
 
+    @Test
     public void testIsCurrentInputMethodSetByOwnerForDeviceOwner() throws Exception {
         final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD;
         final Uri currentImeUri = Settings.Secure.getUriFor(currentIme);
@@ -4976,70 +5149,71 @@
 
         // First and second user set IMEs manually.
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
 
         // Device owner changes IME for first user.
         mContext.binder.callingUid = deviceOwnerUid;
-        when(getServices().settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
-                .thenReturn("ime1");
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme,
+                UserHandle.USER_SYSTEM)).thenReturn("ime1");
         dpm.setSecureSetting(admin1, currentIme, "ime2");
         verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2",
                 UserHandle.USER_SYSTEM);
         reset(getServices().settings);
         dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
         mContext.binder.callingUid = firstUserSystemUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
 
         // Second user changes IME manually.
         dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE);
         mContext.binder.callingUid = firstUserSystemUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
 
         // First user changes IME manually.
         dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
 
         // Device owner changes IME for first user again.
         mContext.binder.callingUid = deviceOwnerUid;
-        when(getServices().settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
-                .thenReturn("ime2");
+        when(getServices().settings.settingsSecureGetStringForUser(currentIme,
+                UserHandle.USER_SYSTEM)).thenReturn("ime2");
         dpm.setSecureSetting(admin1, currentIme, "ime3");
         verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3",
                 UserHandle.USER_SYSTEM);
         dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
         mContext.binder.callingUid = firstUserSystemUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
 
         // Restarting the DPMS should not lose information.
         initializeDpms();
         mContext.binder.callingUid = firstUserSystemUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
 
         // Device owner can find out whether it set the current IME itself.
         mContext.binder.callingUid = deviceOwnerUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
 
         // Removing the device owner should clear the information that it set the current IME.
         clearDeviceOwner();
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
     }
 
+    @Test
     public void testIsCurrentInputMethodSetByOwnerForProfileOwner() throws Exception {
         final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD;
         final Uri currentImeUri = Settings.Secure.getUriFor(currentIme);
@@ -5055,9 +5229,9 @@
 
         // First and second user set IMEs manually.
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
 
         // Profile owner changes IME for second user.
         mContext.binder.callingUid = profileOwnerUid;
@@ -5069,23 +5243,23 @@
         reset(getServices().settings);
         dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE);
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
 
         // First user changes IME manually.
         dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
 
         // Second user changes IME manually.
         dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE);
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
 
         // Profile owner changes IME for second user again.
         mContext.binder.callingUid = profileOwnerUid;
@@ -5096,29 +5270,30 @@
                 CALLER_USER_HANDLE);
         dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE);
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
 
         // Restarting the DPMS should not lose information.
         initializeDpms();
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
 
         // Profile owner can find out whether it set the current IME itself.
         mContext.binder.callingUid = profileOwnerUid;
-        assertTrue(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue();
 
         // Removing the profile owner should clear the information that it set the current IME.
         dpm.clearProfileOwner(admin1);
         mContext.binder.callingUid = firstUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
         mContext.binder.callingUid = secondUserSystemUid;
-        assertFalse(dpm.isCurrentInputMethodSetByOwner());
+        assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse();
     }
 
+    @Test
     public void testSetPermittedCrossProfileNotificationListeners_unavailableForDo()
             throws Exception {
         // Set up a device owner.
@@ -5127,6 +5302,7 @@
         assertSetPermittedCrossProfileNotificationListenersUnavailable(mContext.binder.callingUid);
     }
 
+    @Test
     public void testSetPermittedCrossProfileNotificationListeners_unavailableForPoOnUser()
             throws Exception {
         // Set up a profile owner.
@@ -5141,23 +5317,24 @@
         final int userId = UserHandle.getUserId(adminUid);
 
         final String packageName = "some.package";
-        assertFalse(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.singletonList(packageName)));
-        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
+        assertThat(dpms.setPermittedCrossProfileNotificationListeners(
+        admin1, Collections.singletonList(packageName))).isFalse();
+        assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertTrue(dpms.isNotificationListenerServicePermitted(packageName, userId));
+        assertThat(dpms.isNotificationListenerServicePermitted(packageName, userId)).isTrue();
 
         // Attempt to set to empty list (which means no listener is allowlisted)
         mContext.binder.callingUid = adminUid;
-        assertFalse(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.emptyList()));
-        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
+        assertThat(dpms.setPermittedCrossProfileNotificationListeners(
+                admin1, Collections.emptyList())).isFalse();
+        assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertTrue(dpms.isNotificationListenerServicePermitted(packageName, userId));
+        assertThat(dpms.isNotificationListenerServicePermitted(packageName, userId)).isTrue();
     }
 
+    @Test
     public void testIsNotificationListenerServicePermitted_onlySystemCanCall() throws Exception {
         // Set up a managed profile
         final int MANAGED_PROFILE_USER_ID = 15;
@@ -5171,8 +5348,8 @@
                 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user.
                 /*appId=*/ 12345, /*flags=*/ 0);
 
-        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.singletonList(permittedListener)));
+        assertThat(dpms.setPermittedCrossProfileNotificationListeners(
+        admin1, Collections.singletonList(permittedListener))).isTrue();
 
         // isNotificationListenerServicePermitted should throw if not called from System.
         assertExpectException(SecurityException.class, /* messageRegex= */ null,
@@ -5180,10 +5357,11 @@
                         permittedListener, MANAGED_PROFILE_USER_ID));
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                permittedListener, MANAGED_PROFILE_USER_ID));
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        permittedListener, MANAGED_PROFILE_USER_ID)).isTrue();
     }
 
+    @Test
     public void testSetPermittedCrossProfileNotificationListeners_managedProfile()
             throws Exception {
         // Set up a managed profile
@@ -5212,63 +5390,64 @@
                 ++appId, ApplicationInfo.FLAG_SYSTEM);
 
         // By default all packages are allowed
-        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
+        assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                permittedListener, MANAGED_PROFILE_USER_ID));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                notPermittedListener, MANAGED_PROFILE_USER_ID));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                systemListener, MANAGED_PROFILE_USER_ID));
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        permittedListener, MANAGED_PROFILE_USER_ID)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        notPermittedListener, MANAGED_PROFILE_USER_ID)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        systemListener, MANAGED_PROFILE_USER_ID)).isTrue();
 
         // Setting only one package in the allowlist
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
-        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.singletonList(permittedListener)));
+        assertThat(dpms.setPermittedCrossProfileNotificationListeners(
+        admin1, Collections.singletonList(permittedListener))).isTrue();
         final List<String> permittedListeners =
                 dpms.getPermittedCrossProfileNotificationListeners(admin1);
-        assertEquals(1, permittedListeners.size());
-        assertEquals(permittedListener, permittedListeners.get(0));
+        assertThat(permittedListeners.size()).isEqualTo(1);
+        assertThat(permittedListeners.get(0)).isEqualTo(permittedListener);
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                permittedListener, MANAGED_PROFILE_USER_ID));
-        assertFalse(dpms.isNotificationListenerServicePermitted(
-                notPermittedListener, MANAGED_PROFILE_USER_ID));
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        permittedListener, MANAGED_PROFILE_USER_ID)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        notPermittedListener, MANAGED_PROFILE_USER_ID)).isFalse();
         // System packages are always allowed (even if not in the allowlist)
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                systemListener, MANAGED_PROFILE_USER_ID));
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        systemListener, MANAGED_PROFILE_USER_ID)).isTrue();
 
         // Setting an empty allowlist - only system listeners allowed
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
-        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.emptyList()));
-        assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size());
+        assertThat(dpms.setPermittedCrossProfileNotificationListeners(
+                admin1, Collections.emptyList())).isTrue();
+        assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1).size()).isEqualTo(0);
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertFalse(dpms.isNotificationListenerServicePermitted(
-                permittedListener, MANAGED_PROFILE_USER_ID));
-        assertFalse(dpms.isNotificationListenerServicePermitted(
-                notPermittedListener, MANAGED_PROFILE_USER_ID));
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        permittedListener, MANAGED_PROFILE_USER_ID)).isFalse();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        notPermittedListener, MANAGED_PROFILE_USER_ID)).isFalse();
         // System packages are always allowed (even if not in the allowlist)
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                systemListener, MANAGED_PROFILE_USER_ID));
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        systemListener, MANAGED_PROFILE_USER_ID)).isTrue();
 
         // Setting a null allowlist - all listeners allowed
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
-        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(admin1, null));
-        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
+        assertThat(dpms.setPermittedCrossProfileNotificationListeners(admin1, null)).isTrue();
+        assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                permittedListener, MANAGED_PROFILE_USER_ID));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                notPermittedListener, MANAGED_PROFILE_USER_ID));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                systemListener, MANAGED_PROFILE_USER_ID));
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        permittedListener, MANAGED_PROFILE_USER_ID)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        notPermittedListener, MANAGED_PROFILE_USER_ID)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        systemListener, MANAGED_PROFILE_USER_ID)).isTrue();
     }
 
+    @Test
     public void testSetPermittedCrossProfileNotificationListeners_doesNotAffectPrimaryProfile()
             throws Exception {
         // Set up a managed profile
@@ -5291,36 +5470,37 @@
                 ++appId, ApplicationInfo.FLAG_SYSTEM);
 
         // By default all packages are allowed (for all profiles)
-        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
+        assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                nonSystemPackage, MANAGED_PROFILE_USER_ID));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                systemListener, MANAGED_PROFILE_USER_ID));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                nonSystemPackage, UserHandle.USER_SYSTEM));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                systemListener, UserHandle.USER_SYSTEM));
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        nonSystemPackage, MANAGED_PROFILE_USER_ID)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        systemListener, MANAGED_PROFILE_USER_ID)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        nonSystemPackage, UserHandle.USER_SYSTEM)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        systemListener, UserHandle.USER_SYSTEM)).isTrue();
 
         // Setting an empty allowlist - only system listeners allowed in managed profile, but
         // all allowed in primary profile
         mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
-        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
-                admin1, Collections.emptyList()));
-        assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size());
+        assertThat(dpms.setPermittedCrossProfileNotificationListeners(
+                admin1, Collections.emptyList())).isTrue();
+        assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1).size()).isEqualTo(0);
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertFalse(dpms.isNotificationListenerServicePermitted(
-                nonSystemPackage, MANAGED_PROFILE_USER_ID));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                systemListener, MANAGED_PROFILE_USER_ID));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                nonSystemPackage, UserHandle.USER_SYSTEM));
-        assertTrue(dpms.isNotificationListenerServicePermitted(
-                systemListener, UserHandle.USER_SYSTEM));
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        nonSystemPackage, MANAGED_PROFILE_USER_ID)).isFalse();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        systemListener, MANAGED_PROFILE_USER_ID)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        nonSystemPackage, UserHandle.USER_SYSTEM)).isTrue();
+        assertThat(dpms.isNotificationListenerServicePermitted(
+        systemListener, UserHandle.USER_SYSTEM)).isTrue();
     }
 
+    @Test
     public void testGetOwnerInstalledCaCertsForDeviceOwner() throws Exception {
         mServiceContext.packageName = mRealTestContext.getPackageName();
         mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -5330,6 +5510,7 @@
         verifyCanGetOwnerInstalledCaCerts(admin1, mAdmin1Context);
     }
 
+    @Test
     public void testGetOwnerInstalledCaCertsForProfileOwner() throws Exception {
         mServiceContext.packageName = mRealTestContext.getPackageName();
         mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -5340,6 +5521,7 @@
         verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(admin1, mAdmin1Context);
     }
 
+    @Test
     public void testGetOwnerInstalledCaCertsForDelegate() throws Exception {
         mServiceContext.packageName = mRealTestContext.getPackageName();
         mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
@@ -5359,6 +5541,7 @@
         verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(null, caller);
     }
 
+    @Test
     public void testDisallowSharingIntoProfileSetRestriction() {
         when(mServiceContext.resources.getString(R.string.config_managed_provisioning_package))
                 .thenReturn("com.android.managedprovisioning");
@@ -5371,6 +5554,7 @@
         verifyDataSharingChangedBroadcast();
     }
 
+    @Test
     public void testDisallowSharingIntoProfileClearRestriction() {
         when(mServiceContext.resources.getString(R.string.config_managed_provisioning_package))
                 .thenReturn("com.android.managedprovisioning");
@@ -5383,6 +5567,7 @@
         verifyDataSharingChangedBroadcast();
     }
 
+    @Test
     public void testDisallowSharingIntoProfileUnchanged() {
         RestrictionsListener listener = new RestrictionsListener(mContext);
         listener.onUserRestrictionsChanged(CALLER_USER_HANDLE, new Bundle(), new Bundle());
@@ -5399,6 +5584,7 @@
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
     }
 
+    @Test
     public void testOverrideApnAPIsFailWithPO() throws Exception {
         setupProfileOwner();
         ApnSetting apn = (new ApnSetting.Builder())
@@ -5446,13 +5632,14 @@
         runAsCaller(callerContext, dpms, (dpm) -> {
             when(getServices().keyChainConnection.getService().installCaCertificate(caCert))
                         .thenReturn(alias);
-            assertTrue(dpm.installCaCert(caller, caCert));
+            assertThat(dpm.installCaCert(caller, caCert)).isTrue();
             when(getServices().keyChainConnection.getService().getUserCaAliases())
                     .thenReturn(asSlice(new String[] {alias}));
         });
 
-        getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
+        getServices().injectBroadcast(mServiceContext,
+                new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
+                        .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
                 callerUser.getIdentifier());
         flushTasks(dpms);
 
@@ -5461,25 +5648,27 @@
         // Device Owner / Profile Owner can find out which CA certs were installed by itself.
         runAsCaller(admin1Context, dpms, (dpm) -> {
             final List<String> installedCaCerts = dpm.getOwnerInstalledCaCerts(callerUser);
-            assertEquals(Collections.singletonList(alias), installedCaCerts);
+            assertThat(installedCaCerts).isEqualTo(Collections.singletonList(alias));
             ownerInstalledCaCerts.addAll(installedCaCerts);
         });
 
         // Restarting the DPMS should not lose information.
         initializeDpms();
-        runAsCaller(admin1Context, dpms, (dpm) ->
-                assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser)));
+        runAsCaller(admin1Context, dpms,
+                (dpm) -> assertThat(dpm.getOwnerInstalledCaCerts(callerUser))
+                        .isEqualTo(ownerInstalledCaCerts));
 
         // System can find out which CA certs were installed by the Device Owner / Profile Owner.
         runAsCaller(serviceContext, dpms, (dpm) -> {
-            assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser));
+            assertThat(dpm.getOwnerInstalledCaCerts(callerUser)).isEqualTo(ownerInstalledCaCerts);
 
             // Remove the CA cert.
             reset(getServices().keyChainConnection.getService());
         });
 
-        getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
+        getServices().injectBroadcast(mServiceContext,
+                new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
+                        .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
                 callerUser.getIdentifier());
         flushTasks(dpms);
 
@@ -5516,14 +5705,15 @@
         runAsCaller(callerContext, dpms, (dpm) -> {
             when(getServices().keyChainConnection.getService().installCaCertificate(caCert))
                     .thenReturn(alias);
-            assertTrue(dpm.installCaCert(callerName, caCert));
+            assertThat(dpm.installCaCert(callerName, caCert)).isTrue();
         });
 
         // Fake the CA cert as having been installed
         when(getServices().keyChainConnection.getService().getUserCaAliases())
                 .thenReturn(asSlice(new String[] {alias}));
-        getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
+        getServices().injectBroadcast(mServiceContext,
+                new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
+                        .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()),
                 callerUser.getIdentifier());
         flushTasks(dpms);
 
@@ -5532,8 +5722,8 @@
 
         runAsCaller(serviceContext, dpms, (dpm) -> {
             final List<String> ownerInstalledCaCerts = dpm.getOwnerInstalledCaCerts(callerUser);
-            assertNotNull(ownerInstalledCaCerts);
-            assertTrue(ownerInstalledCaCerts.isEmpty());
+            assertThat(ownerInstalledCaCerts).isNotNull();
+            assertThat(ownerInstalledCaCerts.isEmpty()).isTrue();
         });
     }
 
@@ -5541,9 +5731,10 @@
         int[] gotFlags = DevicePolicyManagerService.translateIdAttestationFlags(attestationFlags);
         Arrays.sort(gotFlags);
         Arrays.sort(expectedFlags);
-        assertTrue(Arrays.equals(expectedFlags, gotFlags));
+        assertThat(Arrays.equals(expectedFlags, gotFlags)).isTrue();
     }
 
+    @Test
     public void testTranslationOfIdAttestationFlag() {
         int[] allIdTypes = new int[]{ID_TYPE_SERIAL, ID_TYPE_IMEI, ID_TYPE_MEID};
         int[] correspondingAttUtilsTypes = new int[]{
@@ -5551,7 +5742,7 @@
             AttestationUtils.ID_TYPE_MEID};
 
         // Test translation of zero flags
-        assertNull(DevicePolicyManagerService.translateIdAttestationFlags(0));
+        assertThat(DevicePolicyManagerService.translateIdAttestationFlags(0)).isNull();
 
         // Test translation of the ID_TYPE_BASE_INFO flag, which should yield an empty, but
         // non-null array
@@ -5578,39 +5769,41 @@
                     AttestationUtils.ID_TYPE_MEID});
     }
 
+    @Test
     public void testRevertDeviceOwnership_noMetadataFile() throws Exception {
         setDeviceOwner();
         initializeDpms();
-        assertFalse(getMockTransferMetadataManager().metadataFileExists());
-        assertTrue(dpms.isDeviceOwner(admin1, UserHandle.USER_SYSTEM));
-        assertTrue(dpms.isAdminActive(admin1, UserHandle.USER_SYSTEM));
+        assertThat(getMockTransferMetadataManager().metadataFileExists()).isFalse();
+        assertThat(dpms.isDeviceOwner(admin1, UserHandle.USER_SYSTEM)).isTrue();
+        assertThat(dpms.isAdminActive(admin1, UserHandle.USER_SYSTEM)).isTrue();
     }
 
-    // @FlakyTest(bugId = 148934649)
-    // public void testRevertDeviceOwnership_adminAndDeviceMigrated() throws Exception {
-    //     DpmTestUtils.writeInputStreamToFile(
-    //             getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated),
-    //             getDeviceOwnerPoliciesFile());
-    //     DpmTestUtils.writeInputStreamToFile(
-    //             getRawStream(com.android.frameworks.servicestests.R.raw.device_owner_migrated),
-    //             getDeviceOwnerFile());
-    //     assertDeviceOwnershipRevertedWithFakeTransferMetadata();
-    // }
+    @FlakyTest(bugId = 148934649)
+    @Test
+    public void testRevertDeviceOwnership_adminAndDeviceMigrated() throws Exception {
+        DpmTestUtils.writeInputStreamToFile(
+                getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated),
+                getDeviceOwnerPoliciesFile());
+        DpmTestUtils.writeInputStreamToFile(
+                getRawStream(com.android.frameworks.servicestests.R.raw.device_owner_migrated),
+                getDeviceOwnerFile());
+        assertDeviceOwnershipRevertedWithFakeTransferMetadata();
+    }
 
-    // @FlakyTest(bugId = 148934649)
-    // public void testRevertDeviceOwnership_deviceNotMigrated()
-    //         throws Exception {
-    //     DpmTestUtils.writeInputStreamToFile(
-    //             getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated),
-    //             getDeviceOwnerPoliciesFile());
-    //     DpmTestUtils.writeInputStreamToFile(
-    //             getRawStream(com.android.frameworks.servicestests.R.raw.device_owner_not_migrated),
-    //             getDeviceOwnerFile());
-    //     assertDeviceOwnershipRevertedWithFakeTransferMetadata();
-    // }
+    @FlakyTest(bugId = 148934649)
+    @Test
+    public void testRevertDeviceOwnership_deviceNotMigrated() throws Exception {
+        DpmTestUtils.writeInputStreamToFile(
+                getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated),
+                getDeviceOwnerPoliciesFile());
+        DpmTestUtils.writeInputStreamToFile(
+                getRawStream(com.android.frameworks.servicestests.R.raw.device_owner_not_migrated),
+                getDeviceOwnerFile());
+        assertDeviceOwnershipRevertedWithFakeTransferMetadata();
+    }
 
-    public void testRevertDeviceOwnership_adminAndDeviceNotMigrated()
-            throws Exception {
+    @Test
+    public void testRevertDeviceOwnership_adminAndDeviceNotMigrated() throws Exception {
         DpmTestUtils.writeInputStreamToFile(
                 getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_not_migrated),
                 getDeviceOwnerPoliciesFile());
@@ -5620,40 +5813,44 @@
         assertDeviceOwnershipRevertedWithFakeTransferMetadata();
     }
 
+    @Test
     public void testRevertProfileOwnership_noMetadataFile() throws Exception {
         setupProfileOwner();
         initializeDpms();
-        assertFalse(getMockTransferMetadataManager().metadataFileExists());
-        assertTrue(dpms.isProfileOwner(admin1, CALLER_USER_HANDLE));
-        assertTrue(dpms.isAdminActive(admin1, CALLER_USER_HANDLE));
+        assertThat(getMockTransferMetadataManager().metadataFileExists()).isFalse();
+        assertThat(dpms.isProfileOwner(admin1, CALLER_USER_HANDLE)).isTrue();
+        assertThat(dpms.isAdminActive(admin1, CALLER_USER_HANDLE)).isTrue();
     }
 
-    // @FlakyTest(bugId = 148934649)
-    // public void testRevertProfileOwnership_adminAndProfileMigrated() throws Exception {
-    //     getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0,
-    //             UserManager.USER_TYPE_PROFILE_MANAGED, UserHandle.USER_SYSTEM);
-    //     DpmTestUtils.writeInputStreamToFile(
-    //             getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated),
-    //             getProfileOwnerPoliciesFile());
-    //     DpmTestUtils.writeInputStreamToFile(
-    //             getRawStream(com.android.frameworks.servicestests.R.raw.profile_owner_migrated),
-    //             getProfileOwnerFile());
-    //     assertProfileOwnershipRevertedWithFakeTransferMetadata();
-    // }
+    @FlakyTest(bugId = 148934649)
+    @Test
+    public void testRevertProfileOwnership_adminAndProfileMigrated() throws Exception {
+        getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0,
+                UserManager.USER_TYPE_PROFILE_MANAGED, UserHandle.USER_SYSTEM);
+        DpmTestUtils.writeInputStreamToFile(
+                getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated),
+                getProfileOwnerPoliciesFile());
+        DpmTestUtils.writeInputStreamToFile(
+                getRawStream(com.android.frameworks.servicestests.R.raw.profile_owner_migrated),
+                getProfileOwnerFile());
+        assertProfileOwnershipRevertedWithFakeTransferMetadata();
+    }
 
-    // @FlakyTest(bugId = 148934649)
-    // public void testRevertProfileOwnership_profileNotMigrated() throws Exception {
-    //     getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0,
-    //             UserManager.USER_TYPE_PROFILE_MANAGED, UserHandle.USER_SYSTEM);
-    //     DpmTestUtils.writeInputStreamToFile(
-    //             getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated),
-    //             getProfileOwnerPoliciesFile());
-    //     DpmTestUtils.writeInputStreamToFile(
-    //             getRawStream(com.android.frameworks.servicestests.R.raw.profile_owner_not_migrated),
-    //             getProfileOwnerFile());
-    //     assertProfileOwnershipRevertedWithFakeTransferMetadata();
-    // }
+    @FlakyTest(bugId = 148934649)
+    @Test
+    public void testRevertProfileOwnership_profileNotMigrated() throws Exception {
+        getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0,
+                UserManager.USER_TYPE_PROFILE_MANAGED, UserHandle.USER_SYSTEM);
+        DpmTestUtils.writeInputStreamToFile(
+                getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated),
+                getProfileOwnerPoliciesFile());
+        DpmTestUtils.writeInputStreamToFile(
+                getRawStream(com.android.frameworks.servicestests.R.raw.profile_owner_not_migrated),
+                getProfileOwnerFile());
+        assertProfileOwnershipRevertedWithFakeTransferMetadata();
+    }
 
+    @Test
     public void testRevertProfileOwnership_adminAndProfileNotMigrated() throws Exception {
         getServices().addUser(CALLER_USER_HANDLE, 0,
                 UserManager.USER_TYPE_PROFILE_MANAGED, UserHandle.USER_SYSTEM);
@@ -5666,6 +5863,7 @@
         assertProfileOwnershipRevertedWithFakeTransferMetadata();
     }
 
+    @Test
     public void testGrantDeviceIdsAccess_notToProfileOwner() throws Exception {
         setupProfileOwner();
         configureContextForAccess(mContext, false);
@@ -5674,6 +5872,7 @@
                 () -> dpm.markProfileOwnerOnOrganizationOwnedDevice(admin2));
     }
 
+    @Test
     public void testGrantDeviceIdsAccess_notByAuthorizedCaller() throws Exception {
         setupProfileOwner();
         configureContextForAccess(mContext, false);
@@ -5682,6 +5881,7 @@
                 () -> dpm.markProfileOwnerOnOrganizationOwnedDevice(admin1));
     }
 
+    @Test
     public void testGrantDeviceIdsAccess_byAuthorizedSystemCaller() throws Exception {
         setupProfileOwner();
 
@@ -5700,6 +5900,7 @@
                 .thenReturn(UserHandle.SYSTEM);
     }
 
+    @Test
     public void testGrantDeviceIdsAccess_byAuthorizedManagedProvisioning() throws Exception {
         setupProfileOwner();
 
@@ -5719,6 +5920,7 @@
         }
     }
 
+    @Test
     public void testEnforceCallerCanRequestDeviceIdAttestation_deviceOwnerCaller()
             throws Exception {
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
@@ -5741,6 +5943,7 @@
                         dpms.getCallerIdentity(admin2)));
     }
 
+    @Test
     public void testEnforceCallerCanRequestDeviceIdAttestation_profileOwnerCaller()
             throws Exception {
         configureContextForAccess(mContext, false);
@@ -5781,6 +5984,7 @@
         }
     }
 
+    @Test
     public void testEnforceCallerCanRequestDeviceIdAttestation_delegateCaller() throws Exception {
         setupProfileOwner();
         markDelegatedCertInstallerAsInstalled();
@@ -5800,6 +6004,7 @@
                 dpms.getCallerIdentity(null, DpmMockContext.DELEGATE_PACKAGE_NAME)));
     }
 
+    @Test
     public void testEnforceCallerCanRequestDeviceIdAttestation_delegateCallerWithoutPermissions()
             throws Exception {
         setupProfileOwner();
@@ -5821,6 +6026,7 @@
         });
     }
 
+    @Test
     public void testGetPasswordComplexity_securityExceptionNotThrownForParentInstance() {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
@@ -5830,9 +6036,10 @@
 
         parentDpm.getPasswordComplexity();
 
-        assertEquals(PASSWORD_COMPLEXITY_NONE, dpm.getPasswordComplexity());
+        assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_NONE);
     }
 
+    @Test
     public void testGetPasswordComplexity_illegalStateExceptionIfLocked() {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
@@ -5841,6 +6048,7 @@
         assertThrows(IllegalStateException.class, () -> dpm.getPasswordComplexity());
     }
 
+    @Test
     public void testGetPasswordComplexity_securityExceptionWithoutPermissions() {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
@@ -5850,6 +6058,7 @@
     }
 
 
+    @Test
     public void testGetPasswordComplexity_currentUserNoPassword() {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
@@ -5859,9 +6068,10 @@
         when(getServices().userManager.getCredentialOwnerProfile(CALLER_USER_HANDLE))
                 .thenReturn(CALLER_USER_HANDLE);
 
-        assertEquals(PASSWORD_COMPLEXITY_NONE, dpm.getPasswordComplexity());
+        assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_NONE);
     }
 
+    @Test
     public void testGetPasswordComplexity_currentUserHasPassword() {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
@@ -5874,9 +6084,10 @@
                 .getUserPasswordMetrics(CALLER_USER_HANDLE))
                 .thenReturn(computeForPassword("asdf".getBytes()));
 
-        assertEquals(PASSWORD_COMPLEXITY_MEDIUM, dpm.getPasswordComplexity());
+        assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_MEDIUM);
     }
 
+    @Test
     public void testGetPasswordComplexity_unifiedChallengeReturnsParentUserPassword() {
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn(
@@ -5896,23 +6107,25 @@
                 .getUserPasswordMetrics(parentUser.id))
                 .thenReturn(computeForPassword("parentUser".getBytes()));
 
-        assertEquals(PASSWORD_COMPLEXITY_HIGH, dpm.getPasswordComplexity());
+        assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_HIGH);
     }
 
+    @Test
     public void testCrossProfileCalendarPackages_initiallyEmpty() {
         setAsProfileOwner(admin1);
         final Set<String> packages = dpm.getCrossProfileCalendarPackages(admin1);
         assertCrossProfileCalendarPackagesEqual(packages, Collections.emptySet());
     }
 
+    @Test
     public void testCrossProfileCalendarPackages_reopenDpms() {
         setAsProfileOwner(admin1);
         dpm.setCrossProfileCalendarPackages(admin1, null);
         Set<String> packages = dpm.getCrossProfileCalendarPackages(admin1);
-        assertTrue(packages == null);
+        assertThat(packages == null).isTrue();
         initializeDpms();
         packages = dpm.getCrossProfileCalendarPackages(admin1);
-        assertTrue(packages == null);
+        assertThat(packages == null).isTrue();
 
         dpm.setCrossProfileCalendarPackages(admin1, Collections.emptySet());
         packages = dpm.getCrossProfileCalendarPackages(admin1);
@@ -5932,21 +6145,22 @@
     }
 
     private void assertCrossProfileCalendarPackagesEqual(Set<String> expected, Set<String> actual) {
-        assertTrue(expected != null);
-        assertTrue(actual != null);
-        assertTrue(expected.containsAll(actual));
-        assertTrue(actual.containsAll(expected));
+        assertThat(expected).isNotNull();
+        assertThat(actual).isNotNull();
+        assertThat(actual).containsExactlyElementsIn(expected);
     }
 
+    @Test
     public void testIsPackageAllowedToAccessCalendar_adminNotAllowed() {
         setAsProfileOwner(admin1);
         dpm.setCrossProfileCalendarPackages(admin1, Collections.emptySet());
         when(getServices().settings.settingsSecureGetIntForUser(
                 Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED,
                 0, CALLER_USER_HANDLE)).thenReturn(1);
-        assertFalse(dpm.isPackageAllowedToAccessCalendar("TEST_PACKAGE"));
+        assertThat(dpm.isPackageAllowedToAccessCalendar("TEST_PACKAGE")).isFalse();
     }
 
+    @Test
     public void testIsPackageAllowedToAccessCalendar_settingOff() {
         final String testPackage = "TEST_PACKAGE";
         setAsProfileOwner(admin1);
@@ -5954,9 +6168,10 @@
         when(getServices().settings.settingsSecureGetIntForUser(
                 Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED,
                 0, CALLER_USER_HANDLE)).thenReturn(0);
-        assertFalse(dpm.isPackageAllowedToAccessCalendar(testPackage));
+        assertThat(dpm.isPackageAllowedToAccessCalendar(testPackage)).isFalse();
     }
 
+    @Test
     public void testIsPackageAllowedToAccessCalendar_bothAllowed() {
         final String testPackage = "TEST_PACKAGE";
         setAsProfileOwner(admin1);
@@ -5964,9 +6179,10 @@
         when(getServices().settings.settingsSecureGetIntForUser(
                 Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED,
                 0, CALLER_USER_HANDLE)).thenReturn(1);
-        assertTrue(dpm.isPackageAllowedToAccessCalendar(testPackage));
+        assertThat(dpm.isPackageAllowedToAccessCalendar(testPackage)).isTrue();
     }
 
+    @Test
     public void testSetUserControlDisabledPackages_asDO() throws Exception {
         final List<String> testPackages = new ArrayList<>();
         testPackages.add("package_1");
@@ -5979,9 +6195,10 @@
 
         verify(getServices().packageManagerInternal).setDeviceOwnerProtectedPackages(testPackages);
 
-        assertEquals(testPackages, dpm.getUserControlDisabledPackages(admin1));
+        assertThat(dpm.getUserControlDisabledPackages(admin1)).isEqualTo(testPackages);
     }
 
+    @Test
     public void testSetUserControlDisabledPackages_failingAsPO() throws Exception {
         final List<String> testPackages = new ArrayList<>();
         testPackages.add("package_1");
@@ -6008,28 +6225,32 @@
         mServiceContext.binder.restoreCallingIdentity(ident);
     }
 
+    @Test
     public void testGetCrossProfilePackages_notSet_returnsEmpty() {
         setAsProfileOwner(admin1);
-        assertTrue(dpm.getCrossProfilePackages(admin1).isEmpty());
+        assertThat(dpm.getCrossProfilePackages(admin1).isEmpty()).isTrue();
     }
 
+    @Test
     public void testGetCrossProfilePackages_notSet_dpmsReinitialized_returnsEmpty() {
         setAsProfileOwner(admin1);
 
         initializeDpms();
 
-        assertTrue(dpm.getCrossProfilePackages(admin1).isEmpty());
+        assertThat(dpm.getCrossProfilePackages(admin1).isEmpty()).isTrue();
     }
 
+    @Test
     public void testGetCrossProfilePackages_whenSet_returnsEqual() {
         setAsProfileOwner(admin1);
         Set<String> packages = Collections.singleton("TEST_PACKAGE");
 
         dpm.setCrossProfilePackages(admin1, packages);
 
-        assertEquals(packages, dpm.getCrossProfilePackages(admin1));
+        assertThat(dpm.getCrossProfilePackages(admin1)).isEqualTo(packages);
     }
 
+    @Test
     public void testGetCrossProfilePackages_whenSet_dpmsReinitialized_returnsEqual() {
         setAsProfileOwner(admin1);
         Set<String> packages = Collections.singleton("TEST_PACKAGE");
@@ -6037,9 +6258,10 @@
         dpm.setCrossProfilePackages(admin1, packages);
         initializeDpms();
 
-        assertEquals(packages, dpm.getCrossProfilePackages(admin1));
+        assertThat(dpm.getCrossProfilePackages(admin1)).isEqualTo(packages);
     }
 
+    @Test
     public void testGetAllCrossProfilePackages_notSet_returnsEmpty() throws Exception {
         addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1);
         mContext.packageName = admin1.getPackageName();
@@ -6047,9 +6269,10 @@
         setCrossProfileAppsList();
         setVendorCrossProfileAppsList();
 
-        assertTrue(dpm.getAllCrossProfilePackages().isEmpty());
+        assertThat(dpm.getAllCrossProfilePackages().isEmpty()).isTrue();
     }
 
+    @Test
     public void testGetAllCrossProfilePackages_notSet_dpmsReinitialized_returnsEmpty()
             throws Exception {
         addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1);
@@ -6059,9 +6282,10 @@
         setVendorCrossProfileAppsList();
         initializeDpms();
 
-        assertTrue(dpm.getAllCrossProfilePackages().isEmpty());
+        assertThat(dpm.getAllCrossProfilePackages().isEmpty()).isTrue();
     }
 
+    @Test
     public void testGetAllCrossProfilePackages_whenSet_returnsCombinedSet() throws Exception {
         addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1);
         final Set<String> packages = Sets.newSet("TEST_PACKAGE", "TEST_COMMON_PACKAGE");
@@ -6071,13 +6295,12 @@
         setCrossProfileAppsList("TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE");
         setVendorCrossProfileAppsList("TEST_VENDOR_DEFAULT_PACKAGE");
 
-        assertEquals(Sets.newSet(
-                        "TEST_PACKAGE", "TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE",
-                        "TEST_VENDOR_DEFAULT_PACKAGE"),
-                dpm.getAllCrossProfilePackages());
-
+        assertThat(dpm.getAllCrossProfilePackages()).containsExactly(
+                "TEST_PACKAGE", "TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE",
+                "TEST_VENDOR_DEFAULT_PACKAGE");
     }
 
+    @Test
     public void testGetAllCrossProfilePackages_whenSet_dpmsReinitialized_returnsCombinedSet()
             throws Exception {
         addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1);
@@ -6089,12 +6312,12 @@
         setVendorCrossProfileAppsList("TEST_VENDOR_DEFAULT_PACKAGE");
         initializeDpms();
 
-        assertEquals(Sets.newSet(
+        assertThat(dpm.getAllCrossProfilePackages()).containsExactly(
                 "TEST_PACKAGE", "TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE",
-                "TEST_VENDOR_DEFAULT_PACKAGE"),
-                dpm.getAllCrossProfilePackages());
+                "TEST_VENDOR_DEFAULT_PACKAGE");
     }
 
+    @Test
     public void testGetDefaultCrossProfilePackages_noPackagesSet_returnsEmpty() {
         setCrossProfileAppsList();
         setVendorCrossProfileAppsList();
@@ -6102,27 +6325,29 @@
         assertThat(dpm.getDefaultCrossProfilePackages()).isEmpty();
     }
 
+    @Test
     public void testGetDefaultCrossProfilePackages_packagesSet_returnsCombinedSet() {
         setCrossProfileAppsList("TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE");
         setVendorCrossProfileAppsList("TEST_VENDOR_DEFAULT_PACKAGE");
 
-        assertThat(dpm.getDefaultCrossProfilePackages()).isEqualTo(Sets.newSet(
-                "TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE", "TEST_VENDOR_DEFAULT_PACKAGE"
-        ));
+        assertThat(dpm.getDefaultCrossProfilePackages()).containsExactly(
+                "TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE", "TEST_VENDOR_DEFAULT_PACKAGE");
     }
 
+    @Test
     public void testSetCommonCriteriaMode_asDeviceOwner() throws Exception {
         setDeviceOwner();
 
-        assertFalse(dpm.isCommonCriteriaModeEnabled(admin1));
-        assertFalse(dpm.isCommonCriteriaModeEnabled(null));
+        assertThat(dpm.isCommonCriteriaModeEnabled(admin1)).isFalse();
+        assertThat(dpm.isCommonCriteriaModeEnabled(null)).isFalse();
 
         dpm.setCommonCriteriaModeEnabled(admin1, true);
 
-        assertTrue(dpm.isCommonCriteriaModeEnabled(admin1));
-        assertTrue(dpm.isCommonCriteriaModeEnabled(null));
+        assertThat(dpm.isCommonCriteriaModeEnabled(admin1)).isTrue();
+        assertThat(dpm.isCommonCriteriaModeEnabled(null)).isTrue();
     }
 
+    @Test
     public void testSetCommonCriteriaMode_asPoOfOrgOwnedDevice() throws Exception {
         final int managedProfileUserId = 15;
         final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436);
@@ -6130,15 +6355,16 @@
         configureProfileOwnerOfOrgOwnedDevice(admin1, managedProfileUserId);
         mContext.binder.callingUid = managedProfileAdminUid;
 
-        assertFalse(dpm.isCommonCriteriaModeEnabled(admin1));
-        assertFalse(dpm.isCommonCriteriaModeEnabled(null));
+        assertThat(dpm.isCommonCriteriaModeEnabled(admin1)).isFalse();
+        assertThat(dpm.isCommonCriteriaModeEnabled(null)).isFalse();
 
         dpm.setCommonCriteriaModeEnabled(admin1, true);
 
-        assertTrue(dpm.isCommonCriteriaModeEnabled(admin1));
-        assertTrue(dpm.isCommonCriteriaModeEnabled(null));
+        assertThat(dpm.isCommonCriteriaModeEnabled(admin1)).isTrue();
+        assertThat(dpm.isCommonCriteriaModeEnabled(null)).isTrue();
     }
 
+    @Test
     public void testCanProfileOwnerResetPasswordWhenLocked_nonDirectBootAwarePo()
             throws Exception {
         setDeviceEncryptionPerUser();
@@ -6146,30 +6372,33 @@
         setupPasswordResetToken();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertFalse("po is not direct boot aware",
-                dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE));
+        assertWithMessage("po is not direct boot aware")
+                .that(dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE)).isFalse();
     }
 
+    @Test
     public void testCanProfileOwnerResetPasswordWhenLocked_noActiveToken() throws Exception {
         setDeviceEncryptionPerUser();
         setupProfileOwner();
         makeAdmin1DirectBootAware();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertFalse("po doesn't have an active password reset token",
-                dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE));
+        assertWithMessage("po doesn't have an active password reset token")
+                .that(dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE)).isFalse();
     }
 
+    @Test
     public void testCanProfileOwnerResetPasswordWhenLocked_nonFbeDevice() throws Exception {
         setupProfileOwner();
         makeAdmin1DirectBootAware();
         setupPasswordResetToken();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertFalse("device is not FBE",
-                dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE));
+        assertWithMessage("device is not FBE")
+                .that(dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE)).isFalse();
     }
 
+    @Test
     public void testCanProfileOwnerResetPasswordWhenLocked() throws Exception {
         setDeviceEncryptionPerUser();
         setupProfileOwner();
@@ -6177,8 +6406,8 @@
         setupPasswordResetToken();
 
         mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
-        assertTrue("direct boot aware po with active password reset token",
-                dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE));
+        assertWithMessage("direct boot aware po with active password reset token")
+                .that(dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE)).isTrue();
     }
 
     private void setupPasswordResetToken() {
@@ -6196,7 +6425,8 @@
                 .isEscrowTokenActive(eq(handle), eq(CALLER_USER_HANDLE)))
                 .thenReturn(true);
 
-        assertTrue("failed to activate token", dpm.isResetPasswordTokenActive(admin1));
+        assertWithMessage("failed to activate token").that(dpm.isResetPasswordTokenActive(admin1))
+                .isTrue();
     }
 
     private void makeAdmin1DirectBootAware()
@@ -6231,6 +6461,7 @@
                 .thenReturn(packages);
     }
 
+    @Test
     public void testSetAccountTypesWithManagementDisabledOnManagedProfile() throws Exception {
         setupProfileOwner();
 
@@ -6249,6 +6480,7 @@
         assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty();
     }
 
+    @Test
     public void testSetAccountTypesWithManagementDisabledOnOrgOwnedManagedProfile()
             throws Exception {
         final int managedProfileUserId = 15;
@@ -6284,6 +6516,7 @@
      * Tests the case when the user doesn't turn the profile on in time, verifies that the user is
      * warned with a notification and then the apps get suspended.
      */
+    @Test
     public void testMaximumProfileTimeOff_profileOffTimeExceeded() throws Exception {
         prepareMocksForSetMaximumProfileTimeOff();
 
@@ -6346,6 +6579,7 @@
     /**
      * Tests the case when the user turns the profile back on long before the deadline (> 1 day).
      */
+    @Test
     public void testMaximumProfileTimeOff_turnOnBeforeWarning() throws Exception {
         prepareMocksForSetMaximumProfileTimeOff();
 
@@ -6366,6 +6600,7 @@
     /**
      * Tests the case when the user turns the profile back on after the warning notification.
      */
+    @Test
     public void testMaximumProfileTimeOff_turnOnAfterWarning() throws Exception {
         prepareMocksForSetMaximumProfileTimeOff();
 
@@ -6395,6 +6630,7 @@
     /**
      * Tests the case when the user turns the profile back on when the apps are already suspended.
      */
+    @Test
     public void testMaximumProfileTimeOff_turnOnAfterDeadline() throws Exception {
         prepareMocksForSetMaximumProfileTimeOff();
 
@@ -6482,7 +6718,7 @@
     }
 
     private static Matcher<Notification> hasExtra(String... extras) {
-        assertEquals("Odd number of extra key-values", 0, extras.length % 2);
+        assertWithMessage("Odd number of extra key-values").that(extras.length % 2).isEqualTo(0);
         return new BaseMatcher<Notification>() {
             @Override
             public boolean matches(Object item) {
@@ -6520,17 +6756,17 @@
         // To simulate a reboot, we just reinitialize dpms and call systemReady
         initializeDpms();
 
-        assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
-        assertFalse(dpm.isDeviceOwnerApp(adminAnotherPackage.getPackageName()));
-        assertFalse(dpm.isAdminActive(adminAnotherPackage));
-        assertTrue(dpm.isAdminActive(admin1));
-        assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
-        assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
+        assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue();
+        assertThat(dpm.isDeviceOwnerApp(adminAnotherPackage.getPackageName())).isFalse();
+        assertThat(dpm.isAdminActive(adminAnotherPackage)).isFalse();
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
+        assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue();
+        assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1);
 
-        assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
-        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
-        assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
-        assertFalse(getMockTransferMetadataManager().metadataFileExists());
+        assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue();
+        assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
+        assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
+        assertThat(getMockTransferMetadataManager().metadataFileExists()).isFalse();
 
         mServiceContext.binder.restoreCallingIdentity(ident);
     }
@@ -6547,12 +6783,12 @@
         // To simulate a reboot, we just reinitialize dpms and call systemReady
         initializeDpms();
 
-        assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName()));
-        assertTrue(dpm.isAdminActive(admin1));
-        assertFalse(dpm.isProfileOwnerApp(adminAnotherPackage.getPackageName()));
-        assertFalse(dpm.isAdminActive(adminAnotherPackage));
-        assertEquals(dpm.getProfileOwnerAsUser(CALLER_USER_HANDLE), admin1);
-        assertFalse(getMockTransferMetadataManager().metadataFileExists());
+        assertThat(dpm.isProfileOwnerApp(admin1.getPackageName())).isTrue();
+        assertThat(dpm.isAdminActive(admin1)).isTrue();
+        assertThat(dpm.isProfileOwnerApp(adminAnotherPackage.getPackageName())).isFalse();
+        assertThat(dpm.isAdminActive(adminAnotherPackage)).isFalse();
+        assertThat(admin1).isEqualTo(dpm.getProfileOwnerAsUser(CALLER_USER_HANDLE));
+        assertThat(getMockTransferMetadataManager().metadataFileExists()).isFalse();
     }
 
     private void writeFakeTransferMetadataFile(int callerUserHandle, String adminType) {
@@ -6597,8 +6833,8 @@
     }
 
     private void assertProvisioningAllowed(String action, boolean expected) {
-        assertEquals("isProvisioningAllowed(" + action + ") returning unexpected result", expected,
-                dpm.isProvisioningAllowed(action));
+        assertWithMessage("isProvisioningAllowed(%s) returning unexpected result", action)
+                .that(dpm.isProvisioningAllowed(action)).isEqualTo(expected);
     }
 
     private void assertProvisioningAllowed(String action, boolean expected, String packageName,
@@ -6622,9 +6858,9 @@
 
     private void assertCheckProvisioningPreCondition(
             String action, String packageName, int provisioningCondition) {
-        assertEquals("checkProvisioningPreCondition("
-                        + action + ", " + packageName + ") returning unexpected result",
-                provisioningCondition, dpm.checkProvisioningPreCondition(action, packageName));
+        assertWithMessage("checkProvisioningPreCondition(%s, %s) returning unexpected result",
+                action, packageName).that(dpm.checkProvisioningPreCondition(action, packageName))
+                        .isEqualTo(provisioningCondition);
     }
 
     /**
@@ -6642,7 +6878,7 @@
         mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
         setUpPackageManagerForFakeAdmin(admin, adminUid, copyFromAdmin);
         dpm.setActiveAdmin(admin, false, userId);
-        assertTrue(dpm.setProfileOwner(admin, null, userId));
+        assertThat(dpm.setProfileOwner(admin, null, userId)).isTrue();
         mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
index 41d54e9..81570a1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
@@ -16,6 +16,8 @@
 
 package com.android.server.devicepolicy;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -35,18 +37,28 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.UserHandle;
-import android.test.AndroidTestCase;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
 
 import java.io.InputStream;
 import java.util.List;
 
-public abstract class DpmTestBase extends AndroidTestCase {
+/**
+ * Temporary copy of DpmTestBase using JUnit 4 - once all tests extend it, it should be renamed
+ * back to DpmTestBase (with the temporary methods removed.
+ *
+ */
+public abstract class DpmTestBase {
+
     public static final String TAG = "DpmTest";
 
-    protected Context mRealTestContext;
+    protected final Context mRealTestContext = InstrumentationRegistry.getTargetContext();
     protected DpmMockContext mMockContext;
     private MockSystemServices mServices;
 
+    // Attributes below are public so they don't need to be prefixed with m
     public ComponentName admin1;
     public ComponentName admin2;
     public ComponentName admin3;
@@ -54,12 +66,8 @@
     public ComponentName adminNoPerm;
     public ComponentName delegateCertInstaller;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mRealTestContext = super.getContext();
-
+    @Before
+    public void setFixtures() throws Exception {
         mServices = new MockSystemServices(mRealTestContext, "test-data");
         mMockContext = new DpmMockContext(mServices, mRealTestContext);
 
@@ -74,8 +82,7 @@
         mockSystemPropertiesToReturnDefault();
     }
 
-    @Override
-    public DpmMockContext getContext() {
+    protected DpmMockContext getContext() {
         return mMockContext;
     }
 
@@ -136,20 +143,15 @@
         final PackageInfo pi = DpmTestUtils.cloneParcelable(
                 mRealTestContext.getPackageManager().getPackageInfo(
                         mRealTestContext.getPackageName(), 0));
-        assertTrue(pi.applicationInfo.flags != 0);
+        assertThat(pi.applicationInfo.flags).isNotEqualTo(0);
 
         if (ai != null) {
             pi.applicationInfo = ai;
         }
 
-        doReturn(pi).when(mServices.ipackageManager).getPackageInfo(
-                eq(packageName),
-                eq(0),
-                eq(userId));
+        doReturn(pi).when(mServices.ipackageManager).getPackageInfo(packageName, 0, userId);
 
-        doReturn(ai.uid).when(mServices.packageManager).getPackageUidAsUser(
-                eq(packageName),
-                eq(userId));
+        doReturn(ai.uid).when(mServices.packageManager).getPackageUidAsUser(packageName, userId);
     }
 
     protected void markDelegatedCertInstallerAsInstalled() throws Exception {
@@ -230,8 +232,8 @@
                 mRealTestContext.getPackageManager().queryBroadcastReceivers(
                         resolveIntent,
                         PackageManager.GET_META_DATA);
-        assertNotNull(realResolveInfo);
-        assertEquals(1, realResolveInfo.size());
+        assertThat(realResolveInfo).isNotNull();
+        assertThat(realResolveInfo).hasSize(1);
 
         // We need to change AI, so set a clone.
         realResolveInfo.set(0, DpmTestUtils.cloneParcelable(realResolveInfo.get(0)));
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/FactoryResetProtectionPolicyTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/FactoryResetProtectionPolicyTest.java
index e8818a3..3aa5a80 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/FactoryResetProtectionPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/FactoryResetProtectionPolicyTest.java
@@ -16,8 +16,8 @@
 
 package com.android.server.devicepolicy;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -100,7 +100,7 @@
         ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
         XmlPullParser parser = Xml.newPullParser();
         parser.setInput(new InputStreamReader(inStream));
-        assertEquals(XmlPullParser.START_TAG, parser.next());
+        assertThat(parser.next()).isEqualTo(XmlPullParser.START_TAG);
 
         assertPoliciesAreEqual(policy, policy.readFromXml(parser));
     }
@@ -114,7 +114,7 @@
         parser.setInput(new InputStreamReader(inStream));
 
         // If deserialization fails, then null is returned.
-        assertNull(policy.readFromXml(parser));
+        assertThat(policy.readFromXml(parser)).isNull();
     }
 
     private ByteArrayOutputStream serialize(FactoryResetProtectionPolicy policy)
@@ -133,17 +133,17 @@
 
     private void assertPoliciesAreEqual(FactoryResetProtectionPolicy expectedPolicy,
             FactoryResetProtectionPolicy actualPolicy) {
-        assertEquals(expectedPolicy.isFactoryResetProtectionEnabled(),
-                actualPolicy.isFactoryResetProtectionEnabled());
+        assertThat(actualPolicy.isFactoryResetProtectionEnabled())
+                .isEqualTo(expectedPolicy.isFactoryResetProtectionEnabled());
         assertAccountsAreEqual(expectedPolicy.getFactoryResetProtectionAccounts(),
                 actualPolicy.getFactoryResetProtectionAccounts());
     }
 
     private void assertAccountsAreEqual(List<String> expectedAccounts,
             List<String> actualAccounts) {
-        assertEquals(expectedAccounts.size(), actualAccounts.size());
+        assertThat(actualAccounts.size()).isEqualTo(expectedAccounts.size());
         for (int i = 0; i < expectedAccounts.size(); i++) {
-            assertEquals(expectedAccounts.get(i), actualAccounts.get(i));
+            assertThat(actualAccounts.get(i)).isEqualTo(expectedAccounts.get(i));
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
index c698312..7506dd4 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
@@ -17,6 +17,9 @@
 
 import static com.android.server.devicepolicy.NetworkLoggingHandler.LOG_NETWORK_EVENT_MSG;
 
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.spy;
@@ -37,8 +40,9 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.server.LocalServices;
-import com.android.server.SystemService;
 
+import org.junit.Before;
+import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
 import java.util.List;
@@ -50,9 +54,8 @@
     private DpmMockContext mSpiedDpmMockContext;
     private DevicePolicyManagerServiceTestable mDpmTestable;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
+    @Before
+    public void setUp() throws Exception {
         mSpiedDpmMockContext = spy(mMockContext);
         mSpiedDpmMockContext.callerPermissions.add(
                 android.Manifest.permission.MANAGE_DEVICE_ADMINS);
@@ -64,6 +67,7 @@
         mDpmTestable.setActiveAdmin(admin1, true, DpmMockContext.CALLER_USER_HANDLE);
     }
 
+    @Test
     public void testNetworkEventId_monotonicallyIncreasing() throws Exception {
         // GIVEN the handler has not processed any events.
         long startingId = 0;
@@ -72,17 +76,20 @@
         List<NetworkEvent> events = fillHandlerWithFullBatchOfEvents(startingId);
 
         // THEN the events are in a batch.
-        assertTrue("Batch not at the returned token.",
-                events != null && events.size() == MAX_EVENTS_PER_BATCH);
+        assertWithMessage("Batch not at the returned token.").that(events).isNotNull();
+        assertWithMessage("Batch not at the returned token.").that(events)
+                .hasSize(MAX_EVENTS_PER_BATCH);
+
         // THEN event ids are monotonically increasing.
         long expectedId = startingId;
         for (int i = 0; i < MAX_EVENTS_PER_BATCH; i++) {
-            assertEquals("At index " + i + ", the event has the wrong id.", expectedId,
-                    events.get(i).getId());
+            assertWithMessage("At index %s, the event has the wrong id.", i)
+                    .that(events.get(i).getId()).isEqualTo(expectedId);
             expectedId++;
         }
     }
 
+    @Test
     public void testNetworkEventId_wrapsAround() throws Exception {
         // GIVEN the handler has almost processed Long.MAX_VALUE events.
         int gap = 5;
@@ -92,24 +99,25 @@
         List<NetworkEvent> events = fillHandlerWithFullBatchOfEvents(startingId);
 
         // THEN the events are in a batch.
-        assertTrue("Batch not at the returned token.",
-                events != null && events.size() == MAX_EVENTS_PER_BATCH);
+        assertWithMessage("Batch not at the returned token.").that(events).isNotNull();
+        assertWithMessage("Batch not at the returned token.").that(events)
+                .hasSize(MAX_EVENTS_PER_BATCH);
         // THEN event ids are monotonically increasing.
         long expectedId = startingId;
         for (int i = 0; i < gap; i++) {
-            assertEquals("At index " + i + ", the event has the wrong id.", expectedId,
-                    events.get(i).getId());
+            assertWithMessage("At index %s, the event has the wrong id.", i)
+                    .that(events.get(i).getId()).isEqualTo(expectedId);
             expectedId++;
         }
         // THEN event ids are reset when the id reaches the maximum possible value.
-        assertEquals("Event was not assigned the maximum id value.", Long.MAX_VALUE,
-                events.get(gap).getId());
-        assertEquals("Event id was not reset.", 0, events.get(gap + 1).getId());
+        assertWithMessage("Event was not assigned the maximum id value.")
+                .that(events.get(gap).getId()).isEqualTo(Long.MAX_VALUE);
+        assertWithMessage("Event id was not reset.").that(events.get(gap + 1).getId()).isEqualTo(0);
         // THEN event ids are monotonically increasing.
         expectedId = 0;
         for (int i = gap + 1; i < MAX_EVENTS_PER_BATCH; i++) {
-            assertEquals("At index " + i + ", the event has the wrong id.", expectedId,
-                    events.get(i).getId());
+            assertWithMessage("At index %s, the event has the wrong id.", i)
+                    .that(events.get(i).getId()).isEqualTo(expectedId);
             expectedId++;
         }
     }
@@ -134,8 +142,8 @@
         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
         verify(mSpiedDpmMockContext).sendBroadcastAsUser(intentCaptor.capture(),
                 any(UserHandle.class));
-        assertEquals(intentCaptor.getValue().getAction(),
-                DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE);
+        assertThat(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE)
+                .isEqualTo(intentCaptor.getValue().getAction());
         long token = intentCaptor.getValue().getExtras().getLong(
                 DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, 0);
         return handler.retrieveFullLogBatch(token);
@@ -144,6 +152,7 @@
     /**
      * Test parceling and unparceling of a ConnectEvent.
      */
+    @Test
     public void testConnectEventParceling() {
         ConnectEvent event = new ConnectEvent("127.0.0.1", 80, "com.android.whateverdude", 100000);
         event.setId(5L);
@@ -152,16 +161,17 @@
         p.setDataPosition(0);
         ConnectEvent unparceledEvent = p.readParcelable(NetworkEventTest.class.getClassLoader());
         p.recycle();
-        assertEquals(event.getInetAddress(), unparceledEvent.getInetAddress());
-        assertEquals(event.getPort(), unparceledEvent.getPort());
-        assertEquals(event.getPackageName(), unparceledEvent.getPackageName());
-        assertEquals(event.getTimestamp(), unparceledEvent.getTimestamp());
-        assertEquals(event.getId(), unparceledEvent.getId());
+        assertThat(unparceledEvent.getInetAddress()).isEqualTo(event.getInetAddress());
+        assertThat(unparceledEvent.getPort()).isEqualTo(event.getPort());
+        assertThat(unparceledEvent.getPackageName()).isEqualTo(event.getPackageName());
+        assertThat(unparceledEvent.getTimestamp()).isEqualTo(event.getTimestamp());
+        assertThat(unparceledEvent.getId()).isEqualTo(event.getId());
     }
 
     /**
      * Test parceling and unparceling of a DnsEvent.
      */
+    @Test
     public void testDnsEventParceling() {
         DnsEvent event = new DnsEvent("d.android.com", new String[]{"192.168.0.1", "127.0.0.1"}, 2,
                 "com.android.whateverdude", 100000);
@@ -171,13 +181,15 @@
         p.setDataPosition(0);
         DnsEvent unparceledEvent = p.readParcelable(NetworkEventTest.class.getClassLoader());
         p.recycle();
-        assertEquals(event.getHostname(), unparceledEvent.getHostname());
-        assertEquals(event.getInetAddresses().get(0), unparceledEvent.getInetAddresses().get(0));
-        assertEquals(event.getInetAddresses().get(1), unparceledEvent.getInetAddresses().get(1));
-        assertEquals(event.getTotalResolvedAddressCount(),
-                unparceledEvent.getTotalResolvedAddressCount());
-        assertEquals(event.getPackageName(), unparceledEvent.getPackageName());
-        assertEquals(event.getTimestamp(), unparceledEvent.getTimestamp());
-        assertEquals(event.getId(), unparceledEvent.getId());
+        assertThat(unparceledEvent.getHostname()).isEqualTo(event.getHostname());
+        assertThat(unparceledEvent.getInetAddresses().get(0))
+                .isEqualTo(event.getInetAddresses().get(0));
+        assertThat(unparceledEvent.getInetAddresses().get(1))
+                .isEqualTo(event.getInetAddresses().get(1));
+        assertThat(unparceledEvent.getTotalResolvedAddressCount())
+                .isEqualTo(event.getTotalResolvedAddressCount());
+        assertThat(unparceledEvent.getPackageName()).isEqualTo(event.getPackageName());
+        assertThat(unparceledEvent.getTimestamp()).isEqualTo(event.getTimestamp());
+        assertThat(unparceledEvent.getId()).isEqualTo(event.getId());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java
index a3cc915..24e226a 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java
@@ -20,6 +20,9 @@
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
 
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
 
@@ -32,16 +35,17 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
-import android.test.AndroidTestCase;
 import android.test.mock.MockPackageManager;
 import android.view.inputmethod.InputMethodInfo;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.R;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -51,18 +55,23 @@
 import java.util.List;
 import java.util.Set;
 
-public class OverlayPackagesProviderTest extends AndroidTestCase {
+/**
+ * Run this test with:
+ *
+ * {@code atest FrameworksServicesTests:com.android.server.devicepolicy.OwnersTest}
+ *
+ */
+@RunWith(AndroidJUnit4.class)
+public class OverlayPackagesProviderTest {
     private static final String TEST_DPC_PACKAGE_NAME = "dpc.package.name";
     private static final ComponentName TEST_MDM_COMPONENT_NAME = new ComponentName(
             TEST_DPC_PACKAGE_NAME, "pc.package.name.DeviceAdmin");
     private static final int TEST_USER_ID = 123;
 
-    private @Mock
-    Resources mResources;
-    @Mock
-    private OverlayPackagesProvider.Injector mInjector;
-    private @Mock
-    Context mTestContext;
+    private @Mock Resources mResources;
+
+    private @Mock OverlayPackagesProvider.Injector mInjector;
+    private @Mock Context mTestContext;
     private Resources mRealResources;
 
     private FakePackageManager mPackageManager;
@@ -256,12 +265,12 @@
         ArrayList<String> required = getStringArrayInRealResources(requiredId);
         ArrayList<String> disallowed = getStringArrayInRealResources(disallowedId);
         required.retainAll(disallowed);
-        assertTrue(required.isEmpty());
+        assertThat(required.isEmpty()).isTrue();
     }
 
     private void verifyAppsAreNonRequired(String action, String... appArray) {
-        assertEquals(setFromArray(appArray),
-                mHelper.getNonRequiredApps(TEST_MDM_COMPONENT_NAME, TEST_USER_ID, action));
+        assertThat(mHelper.getNonRequiredApps(TEST_MDM_COMPONENT_NAME, TEST_USER_ID, action))
+                .containsExactlyElementsIn(setFromArray(appArray));
     }
 
     private void setRequiredAppsManagedDevice(String... apps) {
@@ -348,19 +357,19 @@
     class FakePackageManager extends MockPackageManager {
         @Override
         public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
-            assertTrue("Expected an intent with action ACTION_MAIN",
-                    Intent.ACTION_MAIN.equals(intent.getAction()));
-            assertEquals("Expected an intent with category CATEGORY_LAUNCHER",
-                    setFromArray(Intent.CATEGORY_LAUNCHER), intent.getCategories());
-            assertTrue("Expected the flag MATCH_UNINSTALLED_PACKAGES",
-                    (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0);
-            assertTrue("Expected the flag MATCH_DISABLED_COMPONENTS",
-                    (flags & PackageManager.MATCH_DISABLED_COMPONENTS) != 0);
-            assertTrue("Expected the flag MATCH_DIRECT_BOOT_AWARE",
-                    (flags & PackageManager.MATCH_DIRECT_BOOT_AWARE) != 0);
-            assertTrue("Expected the flag MATCH_DIRECT_BOOT_UNAWARE",
-                    (flags & PackageManager.MATCH_DIRECT_BOOT_UNAWARE) != 0);
-            assertEquals(userId, TEST_USER_ID);
+            assertWithMessage("Expected an intent with action ACTION_MAIN")
+                    .that(Intent.ACTION_MAIN.equals(intent.getAction())).isTrue();
+            assertWithMessage("Expected an intent with category CATEGORY_LAUNCHER")
+                    .that(intent.getCategories()).containsExactly(Intent.CATEGORY_LAUNCHER);
+            assertWithMessage("Expected the flag MATCH_UNINSTALLED_PACKAGES")
+                    .that((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES)).isNotEqualTo(0);
+            assertWithMessage("Expected the flag MATCH_DISABLED_COMPONENTS")
+                    .that((flags & PackageManager.MATCH_DISABLED_COMPONENTS)).isNotEqualTo(0);
+            assertWithMessage("Expected the flag MATCH_DIRECT_BOOT_AWARE")
+                    .that((flags & PackageManager.MATCH_DIRECT_BOOT_AWARE)).isNotEqualTo(0);
+            assertWithMessage("Expected the flag MATCH_DIRECT_BOOT_UNAWARE")
+                    .that((flags & PackageManager.MATCH_DIRECT_BOOT_UNAWARE)).isNotEqualTo(0);
+            assertThat(TEST_USER_ID).isEqualTo(userId);
             List<ResolveInfo> result = new ArrayList<>();
             if (mSystemAppsWithLauncher == null) {
                 return result;
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
index 5899bb0..bfe183c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java
@@ -16,25 +16,32 @@
 
 package com.android.server.devicepolicy;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.content.ComponentName;
 import android.os.UserHandle;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.server.devicepolicy.DevicePolicyManagerServiceTestable.OwnersTestable;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Tests for the DeviceOwner object that saves & loads device and policy owner information.
- * run this test with:
- m FrameworksServicesTests &&
- adb install \
-   -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
- adb shell am instrument -e class com.android.server.devicepolicy.OwnersTest \
-   -w com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
-
- (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
+ *
+ * <p>Run this test with:
+ *
+ * {@code atest FrameworksServicesTests:com.android.server.devicepolicy.OwnersTest}
+ *
  */
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class OwnersTest extends DpmTestBase {
+
+    @Test
     public void testUpgrade01() throws Exception {
         getServices().addUsers(10, 11, 20, 21);
 
@@ -48,26 +55,26 @@
             owners.load();
 
             // The legacy file should be removed.
-            assertFalse(owners.getLegacyConfigFile().exists());
+            assertThat(owners.getLegacyConfigFile().exists()).isFalse();
 
             // File was empty, so no new files should be created.
-            assertFalse(owners.getDeviceOwnerFile().exists());
+            assertThat(owners.getDeviceOwnerFile().exists()).isFalse();
 
-            assertFalse(owners.getProfileOwnerFile(10).exists());
-            assertFalse(owners.getProfileOwnerFile(11).exists());
-            assertFalse(owners.getProfileOwnerFile(20).exists());
-            assertFalse(owners.getProfileOwnerFile(21).exists());
+            assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(21).exists()).isFalse();
 
-            assertFalse(owners.hasDeviceOwner());
-            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
-            assertNull(owners.getSystemUpdatePolicy());
-            assertEquals(0, owners.getProfileOwnerKeys().size());
+            assertThat(owners.hasDeviceOwner()).isFalse();
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
+            assertThat(owners.getSystemUpdatePolicy()).isNull();
+            assertThat(owners.getProfileOwnerKeys()).isEmpty();
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
 
         // Then re-read and check.
@@ -75,19 +82,20 @@
             final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
-            assertFalse(owners.hasDeviceOwner());
-            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
-            assertNull(owners.getSystemUpdatePolicy());
-            assertEquals(0, owners.getProfileOwnerKeys().size());
+            assertThat(owners.hasDeviceOwner()).isFalse();
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
+            assertThat(owners.getSystemUpdatePolicy()).isNull();
+            assertThat(owners.getProfileOwnerKeys()).isEmpty();
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
     }
 
+    @Test
     public void testUpgrade02() throws Exception {
         getServices().addUsers(10, 11, 20, 21);
 
@@ -101,28 +109,28 @@
             owners.load();
 
             // The legacy file should be removed.
-            assertFalse(owners.getLegacyConfigFile().exists());
+            assertThat(owners.getLegacyConfigFile().exists()).isFalse();
 
-            assertTrue(owners.getDeviceOwnerFile().exists()); // TODO Check content
+            assertThat(owners.getDeviceOwnerFile().exists()).isTrue(); // TODO Check content
 
-            assertFalse(owners.getProfileOwnerFile(10).exists());
-            assertFalse(owners.getProfileOwnerFile(11).exists());
-            assertFalse(owners.getProfileOwnerFile(20).exists());
-            assertFalse(owners.getProfileOwnerFile(21).exists());
+            assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(21).exists()).isFalse();
 
-            assertTrue(owners.hasDeviceOwner());
-            assertEquals(null, owners.getDeviceOwnerName());
-            assertEquals("com.google.android.testdpc", owners.getDeviceOwnerPackageName());
-            assertEquals(UserHandle.USER_SYSTEM, owners.getDeviceOwnerUserId());
+            assertThat(owners.hasDeviceOwner()).isTrue();
+            assertThat(owners.getDeviceOwnerName()).isEqualTo(null);
+            assertThat(owners.getDeviceOwnerPackageName()).isEqualTo("com.google.android.testdpc");
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
 
-            assertNull(owners.getSystemUpdatePolicy());
-            assertEquals(0, owners.getProfileOwnerKeys().size());
+            assertThat(owners.getSystemUpdatePolicy()).isNull();
+            assertThat(owners.getProfileOwnerKeys()).isEmpty();
 
-            assertTrue(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
 
         // Then re-read and check.
@@ -130,22 +138,23 @@
             final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
-            assertTrue(owners.hasDeviceOwner());
-            assertEquals(null, owners.getDeviceOwnerName());
-            assertEquals("com.google.android.testdpc", owners.getDeviceOwnerPackageName());
-            assertEquals(UserHandle.USER_SYSTEM, owners.getDeviceOwnerUserId());
+            assertThat(owners.hasDeviceOwner()).isTrue();
+            assertThat(owners.getDeviceOwnerName()).isEqualTo(null);
+            assertThat(owners.getDeviceOwnerPackageName()).isEqualTo("com.google.android.testdpc");
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
 
-            assertNull(owners.getSystemUpdatePolicy());
-            assertEquals(0, owners.getProfileOwnerKeys().size());
+            assertThat(owners.getSystemUpdatePolicy()).isNull();
+            assertThat(owners.getProfileOwnerKeys()).isEmpty();
 
-            assertTrue(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
     }
 
+    @Test
     public void testUpgrade03() throws Exception {
         getServices().addUsers(10, 11, 20, 21);
 
@@ -159,36 +168,36 @@
             owners.load();
 
             // The legacy file should be removed.
-            assertFalse(owners.getLegacyConfigFile().exists());
+            assertThat(owners.getLegacyConfigFile().exists()).isFalse();
 
-            assertFalse(owners.getDeviceOwnerFile().exists());
+            assertThat(owners.getDeviceOwnerFile().exists()).isFalse();
 
-            assertTrue(owners.getProfileOwnerFile(10).exists());
-            assertTrue(owners.getProfileOwnerFile(11).exists());
-            assertFalse(owners.getProfileOwnerFile(20).exists());
-            assertFalse(owners.getProfileOwnerFile(21).exists());
+            assertThat(owners.getProfileOwnerFile(10).exists()).isTrue();
+            assertThat(owners.getProfileOwnerFile(11).exists()).isTrue();
+            assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(21).exists()).isFalse();
 
-            assertFalse(owners.hasDeviceOwner());
-            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
-            assertNull(owners.getSystemUpdatePolicy());
+            assertThat(owners.hasDeviceOwner()).isFalse();
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
+            assertThat(owners.getSystemUpdatePolicy()).isNull();
 
-            assertEquals(2, owners.getProfileOwnerKeys().size());
-            assertEquals(new ComponentName("com.google.android.testdpc",
-                            "com.google.android.testdpc.DeviceAdminReceiver0"),
-                    owners.getProfileOwnerComponent(10));
-            assertEquals("0", owners.getProfileOwnerName(10));
-            assertEquals("com.google.android.testdpc", owners.getProfileOwnerPackage(10));
+            assertThat(owners.getProfileOwnerKeys()).hasSize(2);
+            assertThat(owners.getProfileOwnerComponent(10))
+                    .isEqualTo(new ComponentName("com.google.android.testdpc",
+                            "com.google.android.testdpc.DeviceAdminReceiver0"));
+            assertThat(owners.getProfileOwnerName(10)).isEqualTo("0");
+            assertThat(owners.getProfileOwnerPackage(10)).isEqualTo("com.google.android.testdpc");
 
-            assertEquals(new ComponentName("com.google.android.testdpc1", ""),
-                    owners.getProfileOwnerComponent(11));
-            assertEquals("1", owners.getProfileOwnerName(11));
-            assertEquals("com.google.android.testdpc1", owners.getProfileOwnerPackage(11));
+            assertThat(owners.getProfileOwnerComponent(11))
+                    .isEqualTo(new ComponentName("com.google.android.testdpc1", ""));
+            assertThat(owners.getProfileOwnerName(11)).isEqualTo("1");
+            assertThat(owners.getProfileOwnerPackage(11)).isEqualTo("com.google.android.testdpc1");
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
 
         // Then re-read and check.
@@ -196,27 +205,27 @@
             final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
-            assertFalse(owners.hasDeviceOwner());
-            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
-            assertNull(owners.getSystemUpdatePolicy());
+            assertThat(owners.hasDeviceOwner()).isFalse();
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
+            assertThat(owners.getSystemUpdatePolicy()).isNull();
 
-            assertEquals(2, owners.getProfileOwnerKeys().size());
-            assertEquals(new ComponentName("com.google.android.testdpc",
-                            "com.google.android.testdpc.DeviceAdminReceiver0"),
-                    owners.getProfileOwnerComponent(10));
-            assertEquals("0", owners.getProfileOwnerName(10));
-            assertEquals("com.google.android.testdpc", owners.getProfileOwnerPackage(10));
+            assertThat(owners.getProfileOwnerKeys()).hasSize(2);
+            assertThat(owners.getProfileOwnerComponent(10))
+                    .isEqualTo(new ComponentName("com.google.android.testdpc",
+                            "com.google.android.testdpc.DeviceAdminReceiver0"));
+            assertThat(owners.getProfileOwnerName(10)).isEqualTo("0");
+            assertThat(owners.getProfileOwnerPackage(10)).isEqualTo("com.google.android.testdpc");
 
-            assertEquals(new ComponentName("com.google.android.testdpc1", ""),
-                    owners.getProfileOwnerComponent(11));
-            assertEquals("1", owners.getProfileOwnerName(11));
-            assertEquals("com.google.android.testdpc1", owners.getProfileOwnerPackage(11));
+            assertThat(owners.getProfileOwnerComponent(11))
+                    .isEqualTo(new ComponentName("com.google.android.testdpc1", ""));
+            assertThat(owners.getProfileOwnerName(11)).isEqualTo("1");
+            assertThat(owners.getProfileOwnerPackage(11)).isEqualTo("com.google.android.testdpc1");
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
     }
 
@@ -224,6 +233,7 @@
      * Note this also tests {@link Owners#setDeviceOwnerUserRestrictionsMigrated()}
      * and {@link  Owners#setProfileOwnerUserRestrictionsMigrated(int)}.
      */
+    @Test
     public void testUpgrade04() throws Exception {
         getServices().addUsers(10, 11, 20, 21);
 
@@ -237,40 +247,40 @@
             owners.load();
 
             // The legacy file should be removed.
-            assertFalse(owners.getLegacyConfigFile().exists());
+            assertThat(owners.getLegacyConfigFile().exists()).isFalse();
 
-            assertTrue(owners.getDeviceOwnerFile().exists());
+            assertThat(owners.getDeviceOwnerFile().exists()).isTrue();
 
-            assertTrue(owners.getProfileOwnerFile(10).exists());
-            assertTrue(owners.getProfileOwnerFile(11).exists());
-            assertFalse(owners.getProfileOwnerFile(20).exists());
-            assertFalse(owners.getProfileOwnerFile(21).exists());
+            assertThat(owners.getProfileOwnerFile(10).exists()).isTrue();
+            assertThat(owners.getProfileOwnerFile(11).exists()).isTrue();
+            assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(21).exists()).isFalse();
 
-            assertTrue(owners.hasDeviceOwner());
-            assertEquals(null, owners.getDeviceOwnerName());
-            assertEquals("com.google.android.testdpc", owners.getDeviceOwnerPackageName());
-            assertEquals(UserHandle.USER_SYSTEM, owners.getDeviceOwnerUserId());
+            assertThat(owners.hasDeviceOwner()).isTrue();
+            assertThat(owners.getDeviceOwnerName()).isEqualTo(null);
+            assertThat(owners.getDeviceOwnerPackageName()).isEqualTo("com.google.android.testdpc");
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
 
-            assertNotNull(owners.getSystemUpdatePolicy());
-            assertEquals(5, owners.getSystemUpdatePolicy().getPolicyType());
+            assertThat(owners.getSystemUpdatePolicy()).isNotNull();
+            assertThat(owners.getSystemUpdatePolicy().getPolicyType()).isEqualTo(5);
 
-            assertEquals(2, owners.getProfileOwnerKeys().size());
-            assertEquals(new ComponentName("com.google.android.testdpc",
-                            "com.google.android.testdpc.DeviceAdminReceiver0"),
-                    owners.getProfileOwnerComponent(10));
-            assertEquals("0", owners.getProfileOwnerName(10));
-            assertEquals("com.google.android.testdpc", owners.getProfileOwnerPackage(10));
+            assertThat(owners.getProfileOwnerKeys()).hasSize(2);
+            assertThat(owners.getProfileOwnerComponent(10))
+                    .isEqualTo(new ComponentName("com.google.android.testdpc",
+                            "com.google.android.testdpc.DeviceAdminReceiver0"));
+            assertThat(owners.getProfileOwnerName(10)).isEqualTo("0");
+            assertThat(owners.getProfileOwnerPackage(10)).isEqualTo("com.google.android.testdpc");
 
-            assertEquals(new ComponentName("com.google.android.testdpc1", ""),
-                    owners.getProfileOwnerComponent(11));
-            assertEquals("1", owners.getProfileOwnerName(11));
-            assertEquals("com.google.android.testdpc1", owners.getProfileOwnerPackage(11));
+            assertThat(owners.getProfileOwnerComponent(11))
+                    .isEqualTo(new ComponentName("com.google.android.testdpc1", ""));
+            assertThat(owners.getProfileOwnerName(11)).isEqualTo("1");
+            assertThat(owners.getProfileOwnerPackage(11)).isEqualTo("com.google.android.testdpc1");
 
-            assertTrue(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
 
         // Then re-read and check.
@@ -278,31 +288,31 @@
             final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
-            assertTrue(owners.hasDeviceOwner());
-            assertEquals(null, owners.getDeviceOwnerName());
-            assertEquals("com.google.android.testdpc", owners.getDeviceOwnerPackageName());
-            assertEquals(UserHandle.USER_SYSTEM, owners.getDeviceOwnerUserId());
+            assertThat(owners.hasDeviceOwner()).isTrue();
+            assertThat(owners.getDeviceOwnerName()).isEqualTo(null);
+            assertThat(owners.getDeviceOwnerPackageName()).isEqualTo("com.google.android.testdpc");
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM);
 
-            assertNotNull(owners.getSystemUpdatePolicy());
-            assertEquals(5, owners.getSystemUpdatePolicy().getPolicyType());
+            assertThat(owners.getSystemUpdatePolicy()).isNotNull();
+            assertThat(owners.getSystemUpdatePolicy().getPolicyType()).isEqualTo(5);
 
-            assertEquals(2, owners.getProfileOwnerKeys().size());
-            assertEquals(new ComponentName("com.google.android.testdpc",
-                            "com.google.android.testdpc.DeviceAdminReceiver0"),
-                    owners.getProfileOwnerComponent(10));
-            assertEquals("0", owners.getProfileOwnerName(10));
-            assertEquals("com.google.android.testdpc", owners.getProfileOwnerPackage(10));
+            assertThat(owners.getProfileOwnerKeys()).hasSize(2);
+            assertThat(owners.getProfileOwnerComponent(10))
+                    .isEqualTo(new ComponentName("com.google.android.testdpc",
+                            "com.google.android.testdpc.DeviceAdminReceiver0"));
+            assertThat(owners.getProfileOwnerName(10)).isEqualTo("0");
+            assertThat(owners.getProfileOwnerPackage(10)).isEqualTo("com.google.android.testdpc");
 
-            assertEquals(new ComponentName("com.google.android.testdpc1", ""),
-                    owners.getProfileOwnerComponent(11));
-            assertEquals("1", owners.getProfileOwnerName(11));
-            assertEquals("com.google.android.testdpc1", owners.getProfileOwnerPackage(11));
+            assertThat(owners.getProfileOwnerComponent(11))
+                    .isEqualTo(new ComponentName("com.google.android.testdpc1", ""));
+            assertThat(owners.getProfileOwnerName(11)).isEqualTo("1");
+            assertThat(owners.getProfileOwnerPackage(11)).isEqualTo("com.google.android.testdpc1");
 
-            assertTrue(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
 
             owners.setDeviceOwnerUserRestrictionsMigrated();
         }
@@ -311,11 +321,11 @@
             final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
 
             owners.setProfileOwnerUserRestrictionsMigrated(11);
         }
@@ -324,16 +334,17 @@
             final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertTrue(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isTrue();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
 
             owners.setProfileOwnerUserRestrictionsMigrated(11);
         }
     }
 
+    @Test
     public void testUpgrade05() throws Exception {
         getServices().addUsers(10, 11, 20, 21);
 
@@ -347,27 +358,27 @@
             owners.load();
 
             // The legacy file should be removed.
-            assertFalse(owners.getLegacyConfigFile().exists());
+            assertThat(owners.getLegacyConfigFile().exists()).isFalse();
 
             // Note device initializer is no longer supported.  No need to write the DO file.
-            assertFalse(owners.getDeviceOwnerFile().exists());
+            assertThat(owners.getDeviceOwnerFile().exists()).isFalse();
 
-            assertFalse(owners.getProfileOwnerFile(10).exists());
-            assertFalse(owners.getProfileOwnerFile(11).exists());
-            assertFalse(owners.getProfileOwnerFile(20).exists());
+            assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
 
-            assertFalse(owners.hasDeviceOwner());
-            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
+            assertThat(owners.hasDeviceOwner()).isFalse();
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
 
 
-            assertNull(owners.getSystemUpdatePolicy());
-            assertEquals(0, owners.getProfileOwnerKeys().size());
+            assertThat(owners.getSystemUpdatePolicy()).isNull();
+            assertThat(owners.getProfileOwnerKeys()).isEmpty();
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
 
         // Then re-read and check.
@@ -375,21 +386,22 @@
             final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
-            assertFalse(owners.hasDeviceOwner());
-            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
+            assertThat(owners.hasDeviceOwner()).isFalse();
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
 
 
-            assertNull(owners.getSystemUpdatePolicy());
-            assertEquals(0, owners.getProfileOwnerKeys().size());
+            assertThat(owners.getSystemUpdatePolicy()).isNull();
+            assertThat(owners.getProfileOwnerKeys()).isEmpty();
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
     }
 
+    @Test
     public void testUpgrade06() throws Exception {
         getServices().addUsers(10, 11, 20, 21);
 
@@ -403,26 +415,26 @@
             owners.load();
 
             // The legacy file should be removed.
-            assertFalse(owners.getLegacyConfigFile().exists());
+            assertThat(owners.getLegacyConfigFile().exists()).isFalse();
 
-            assertTrue(owners.getDeviceOwnerFile().exists());
+            assertThat(owners.getDeviceOwnerFile().exists()).isTrue();
 
-            assertFalse(owners.getProfileOwnerFile(10).exists());
-            assertFalse(owners.getProfileOwnerFile(11).exists());
-            assertFalse(owners.getProfileOwnerFile(20).exists());
+            assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
+            assertThat(owners.getProfileOwnerFile(20).exists()).isFalse();
 
-            assertFalse(owners.hasDeviceOwner());
-            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
-            assertEquals(0, owners.getProfileOwnerKeys().size());
+            assertThat(owners.hasDeviceOwner()).isFalse();
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
+            assertThat(owners.getProfileOwnerKeys()).isEmpty();
 
-            assertNotNull(owners.getSystemUpdatePolicy());
-            assertEquals(5, owners.getSystemUpdatePolicy().getPolicyType());
+            assertThat(owners.getSystemUpdatePolicy()).isNotNull();
+            assertThat(owners.getSystemUpdatePolicy().getPolicyType()).isEqualTo(5);
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
 
         // Then re-read and check.
@@ -430,21 +442,22 @@
             final OwnersTestable owners = new OwnersTestable(getServices());
             owners.load();
 
-            assertFalse(owners.hasDeviceOwner());
-            assertEquals(UserHandle.USER_NULL, owners.getDeviceOwnerUserId());
-            assertEquals(0, owners.getProfileOwnerKeys().size());
+            assertThat(owners.hasDeviceOwner()).isFalse();
+            assertThat(owners.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL);
+            assertThat(owners.getProfileOwnerKeys()).isEmpty();
 
-            assertNotNull(owners.getSystemUpdatePolicy());
-            assertEquals(5, owners.getSystemUpdatePolicy().getPolicyType());
+            assertThat(owners.getSystemUpdatePolicy()).isNotNull();
+            assertThat(owners.getSystemUpdatePolicy().getPolicyType()).isEqualTo(5);
 
-            assertFalse(owners.getDeviceOwnerUserRestrictionsNeedsMigration());
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(10));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(11));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(20));
-            assertFalse(owners.getProfileOwnerUserRestrictionsNeedsMigration(21));
+            assertThat(owners.getDeviceOwnerUserRestrictionsNeedsMigration()).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(10)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(11)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(20)).isFalse();
+            assertThat(owners.getProfileOwnerUserRestrictionsNeedsMigration(21)).isFalse();
         }
     }
 
+    @Test
     public void testRemoveExistingFiles() throws Exception {
         getServices().addUsers(10, 11, 20, 21);
 
@@ -456,11 +469,11 @@
 
         owners.load();
 
-        assertFalse(owners.getLegacyConfigFile().exists());
+        assertThat(owners.getLegacyConfigFile().exists()).isFalse();
 
-        assertTrue(owners.getDeviceOwnerFile().exists());
-        assertTrue(owners.getProfileOwnerFile(10).exists());
-        assertTrue(owners.getProfileOwnerFile(11).exists());
+        assertThat(owners.getDeviceOwnerFile().exists()).isTrue();
+        assertThat(owners.getProfileOwnerFile(10).exists()).isTrue();
+        assertThat(owners.getProfileOwnerFile(11).exists()).isTrue();
 
         // Then clear all information and save.
         owners.clearDeviceOwner();
@@ -475,8 +488,8 @@
         owners.writeProfileOwner(21);
 
         // Now all files should be removed.
-        assertFalse(owners.getDeviceOwnerFile().exists());
-        assertFalse(owners.getProfileOwnerFile(10).exists());
-        assertFalse(owners.getProfileOwnerFile(11).exists());
+        assertThat(owners.getDeviceOwnerFile().exists()).isFalse();
+        assertThat(owners.getProfileOwnerFile(10).exists()).isFalse();
+        assertThat(owners.getProfileOwnerFile(11).exists()).isFalse();
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/SecurityEventTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/SecurityEventTest.java
index 8dcf21f..6cefaeb 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/SecurityEventTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/SecurityEventTest.java
@@ -1,3 +1,18 @@
+/*
+ * 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.devicepolicy;
 
 import static android.app.admin.SecurityLog.TAG_ADB_SHELL_CMD;
@@ -11,6 +26,8 @@
 import static android.app.admin.SecurityLog.TAG_MEDIA_MOUNT;
 import static android.app.admin.SecurityLog.TAG_MEDIA_UNMOUNT;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.app.admin.SecurityLog.SecurityEvent;
 import android.os.Parcel;
 import android.os.UserHandle;
@@ -18,21 +35,37 @@
 import android.util.EventLog;
 import android.util.EventLog.Event;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import junit.framework.AssertionFailedError;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * Tests for the DeviceOwner object that saves & loads device and policy owner information.
+ *
+ * <p>Run this test with:
+ *
+ * {@code atest FrameworksServicesTests:com.android.server.devicepolicy.SecurityEventTest}
+ *
+ */
+@RunWith(AndroidJUnit4.class)
 public class SecurityEventTest extends DpmTestBase {
 
+    @Test
     public void testSecurityEventId() throws Exception {
         SecurityEvent event = createEvent(() -> {
             EventLog.writeEvent(TAG_ADB_SHELL_CMD, 0);
         }, TAG_ADB_SHELL_CMD);
         event.setId(20);
-        assertEquals(20, event.getId());
+        assertThat(event.getId()).isEqualTo(20);
     }
 
+    @Test
     public void testSecurityEventParceling() throws Exception {
         // GIVEN an event.
         SecurityEvent event = createEvent(() -> {
@@ -45,12 +78,13 @@
         SecurityEvent unparceledEvent = p.readParcelable(SecurityEventTest.class.getClassLoader());
         p.recycle();
         // THEN the event state is preserved.
-        assertEquals(event.getTag(), unparceledEvent.getTag());
-        assertEquals(event.getData(), unparceledEvent.getData());
-        assertEquals(event.getTimeNanos(), unparceledEvent.getTimeNanos());
-        assertEquals(event.getId(), unparceledEvent.getId());
+        assertThat(unparceledEvent.getTag()).isEqualTo(event.getTag());
+        assertThat(unparceledEvent.getData()).isEqualTo(event.getData());
+        assertThat(unparceledEvent.getTimeNanos()).isEqualTo(event.getTimeNanos());
+        assertThat(unparceledEvent.getId()).isEqualTo(event.getId());
     }
 
+    @Test
     public void testSecurityEventRedaction() throws Exception {
         SecurityEvent event;
 
@@ -58,75 +92,75 @@
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_ADB_SHELL_CMD, "command");
         }, TAG_ADB_SHELL_CMD);
-        assertFalse(TextUtils.isEmpty((String) event.getData()));
+        assertThat(TextUtils.isEmpty((String) event.getData())).isFalse();
 
         // TAG_MEDIA_MOUNT will have the volume label redacted (second data)
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_MEDIA_MOUNT, new Object[] {"path", "label"});
         }, TAG_MEDIA_MOUNT);
-        assertFalse(TextUtils.isEmpty(event.getStringData(1)));
-        assertTrue(TextUtils.isEmpty(event.redact(0).getStringData(1)));
+        assertThat(TextUtils.isEmpty(event.getStringData(1))).isFalse();
+        assertThat(TextUtils.isEmpty(event.redact(0).getStringData(1))).isTrue();
 
         // TAG_MEDIA_UNMOUNT will have the volume label redacted (second data)
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_MEDIA_UNMOUNT, new Object[] {"path", "label"});
         }, TAG_MEDIA_UNMOUNT);
-        assertFalse(TextUtils.isEmpty(event.getStringData(1)));
-        assertTrue(TextUtils.isEmpty(event.redact(0).getStringData(1)));
+        assertThat(TextUtils.isEmpty(event.getStringData(1))).isFalse();
+        assertThat(TextUtils.isEmpty(event.redact(0).getStringData(1))).isTrue();
 
         // TAG_APP_PROCESS_START will be fully redacted if user does not match
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_APP_PROCESS_START, new Object[] {"process", 12345L,
                     UserHandle.getUid(10, 123), 456, "seinfo", "hash"});
         }, TAG_APP_PROCESS_START);
-        assertNotNull(event.redact(10));
-        assertNull(event.redact(11));
+        assertThat(event.redact(10)).isNotNull();
+        assertThat(event.redact(11)).isNull();
 
         // TAG_CERT_AUTHORITY_INSTALLED will be fully redacted if user does not match
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_CERT_AUTHORITY_INSTALLED, new Object[] {1, "subject", 10});
         }, TAG_CERT_AUTHORITY_INSTALLED);
-        assertNotNull(event.redact(10));
-        assertNull(event.redact(11));
+        assertThat(event.redact(10)).isNotNull();
+        assertThat(event.redact(11)).isNull();
 
         // TAG_CERT_AUTHORITY_REMOVED will be fully redacted if user does not match
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_CERT_AUTHORITY_REMOVED, new Object[] {1, "subject", 20});
         }, TAG_CERT_AUTHORITY_REMOVED);
-        assertNotNull(event.redact(20));
-        assertNull(event.redact(0));
+        assertThat(event.redact(20)).isNotNull();
+        assertThat(event.redact(0)).isNull();
 
         // TAG_KEY_GENERATED will be fully redacted if user does not match
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_KEY_GENERATED,
                     new Object[] {1, "alias", UserHandle.getUid(0, 123)});
         }, TAG_KEY_GENERATED);
-        assertNotNull(event.redact(0));
-        assertNull(event.redact(10));
+        assertThat(event.redact(0)).isNotNull();
+        assertThat(event.redact(10)).isNull();
 
         // TAG_KEY_IMPORT will be fully redacted if user does not match
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_KEY_IMPORT,
                     new Object[] {1, "alias", UserHandle.getUid(1, 123)});
         }, TAG_KEY_IMPORT);
-        assertNotNull(event.redact(1));
-        assertNull(event.redact(10));
+        assertThat(event.redact(1)).isNotNull();
+        assertThat(event.redact(10)).isNull();
 
         // TAG_KEY_DESTRUCTION will be fully redacted if user does not match
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_KEY_DESTRUCTION,
                     new Object[] {1, "alias", UserHandle.getUid(2, 123)});
         }, TAG_KEY_DESTRUCTION);
-        assertNotNull(event.redact(2));
-        assertNull(event.redact(10));
+        assertThat(event.redact(2)).isNotNull();
+        assertThat(event.redact(10)).isNull();
 
         // TAG_KEY_INTEGRITY_VIOLATION will be fully redacted if user does not match
         event = createEvent(() -> {
             EventLog.writeEvent(TAG_KEY_INTEGRITY_VIOLATION,
                     new Object[] {"alias", UserHandle.getUid(2, 123)});
         }, TAG_KEY_INTEGRITY_VIOLATION);
-        assertNotNull(event.redact(2));
-        assertNull(event.redact(10));
+        assertThat(event.redact(2)).isNotNull();
+        assertThat(event.redact(10)).isNull();
 
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/SystemUpdatePolicyTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/SystemUpdatePolicyTest.java
index e51859b..0a9aad7 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/SystemUpdatePolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/SystemUpdatePolicyTest.java
@@ -21,8 +21,9 @@
 import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE;
 import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_NEW_FREEZE_PERIOD_TOO_LONG;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
 import static org.junit.Assert.fail;
 
 import android.app.admin.FreezePeriod;
@@ -53,10 +54,12 @@
 
 /**
  * Unit tests for {@link android.app.admin.SystemUpdatePolicy}.
- * Throughout this test, we use "MM-DD" format to denote dates without year.
  *
- * atest com.android.server.devicepolicy.SystemUpdatePolicyTest
- * runtest -c com.android.server.devicepolicy.SystemUpdatePolicyTest frameworks-services
+ * <p>NOTE: Throughout this test, we use {@code "MM-DD"} format to denote dates without year.
+ *
+ * <p>Run this test with:
+ *
+ * {@code atest FrameworksServicesTests:com.android.server.devicepolicy.SystemUpdatePolicyTest}
  */
 @RunWith(AndroidJUnit4.class)
 public final class SystemUpdatePolicyTest {
@@ -224,37 +227,37 @@
 
     @Test
     public void testDistanceWithoutLeapYear() {
-        assertEquals(364, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2016, 12, 31), LocalDate.of(2016, 1, 1)));
-        assertEquals(365, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2017, 1, 1), LocalDate.of(2016, 1, 1)));
-        assertEquals(365, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2017, 2, 28), LocalDate.of(2016, 2, 29)));
-        assertEquals(-365, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2016, 1, 1), LocalDate.of(2017, 1, 1)));
-        assertEquals(1, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 29)));
-        assertEquals(1, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 28)));
-        assertEquals(0, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2016, 2, 29), LocalDate.of(2016, 2, 28)));
-        assertEquals(0, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2016, 2, 28), LocalDate.of(2016, 2, 28)));
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2016, 12, 31), LocalDate.of(2016, 1, 1))).isEqualTo(364);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2017, 1, 1), LocalDate.of(2016, 1, 1))).isEqualTo(365);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2017, 2, 28), LocalDate.of(2016, 2, 29))).isEqualTo(365);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2016, 1, 1), LocalDate.of(2017, 1, 1))).isEqualTo(-365);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 29))).isEqualTo(1);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 28))).isEqualTo(1);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2016, 2, 29), LocalDate.of(2016, 2, 28))).isEqualTo(0);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2016, 2, 28), LocalDate.of(2016, 2, 28))).isEqualTo(0);
 
-        assertEquals(59, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2016, 3, 1), LocalDate.of(2016, 1, 1)));
-        assertEquals(59, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2017, 3, 1), LocalDate.of(2017, 1, 1)));
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2016, 3, 1), LocalDate.of(2016, 1, 1))).isEqualTo(59);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2017, 3, 1), LocalDate.of(2017, 1, 1))).isEqualTo(59);
 
-        assertEquals(365 * 40, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2040, 1, 1), LocalDate.of(2000, 1, 1)));
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2040, 1, 1), LocalDate.of(2000, 1, 1))).isEqualTo(365 * 40);
 
-        assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2019, 3, 1), LocalDate.of(2017, 3, 1)));
-        assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2018, 3, 1), LocalDate.of(2016, 3, 1)));
-        assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear(
-                LocalDate.of(2017, 3, 1), LocalDate.of(2015, 3, 1)));
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2019, 3, 1), LocalDate.of(2017, 3, 1))).isEqualTo(365 * 2);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2018, 3, 1), LocalDate.of(2016, 3, 1))).isEqualTo(365 * 2);
+        assertThat(FreezePeriod.distanceWithoutLeapYear(
+        LocalDate.of(2017, 3, 1), LocalDate.of(2015, 3, 1))).isEqualTo(365 * 2);
 
     }
 
@@ -395,8 +398,8 @@
 
     private void assertInstallationOption(int expectedType, long expectedTime, long now,
             SystemUpdatePolicy p) {
-        assertEquals(expectedType, p.getInstallationOptionAt(now).getType());
-        assertEquals(expectedTime, p.getInstallationOptionAt(now).getEffectiveTime());
+        assertThat(p.getInstallationOptionAt(now).getType()).isEqualTo(expectedType);
+        assertThat(p.getInstallationOptionAt(now).getEffectiveTime()).isEqualTo(expectedTime);
     }
 
     private void testFreezePeriodsSucceeds(String...dates) throws Exception {
@@ -410,8 +413,8 @@
             setFreezePeriods(p, dates);
             fail("Invalid periods (" + expectedError + ") not flagged: " + String.join(" ", dates));
         } catch (SystemUpdatePolicy.ValidationFailedException e) {
-            assertTrue("Exception not expected: " + e.getMessage(),
-                    e.getErrorCode() == expectedError);
+            assertWithMessage("Exception not expected: %s", e.getMessage()).that(e.getErrorCode())
+                    .isEqualTo(expectedError);
         }
     }
 
@@ -426,8 +429,8 @@
             createPrevFreezePeriod(prevStart, prevEnd, now, dates);
             fail("Invalid period (" + expectedError + ") not flagged: " + String.join(" ", dates));
         } catch (SystemUpdatePolicy.ValidationFailedException e) {
-            assertTrue("Exception not expected: " + e.getMessage(),
-                    e.getErrorCode() == expectedError);
+            assertWithMessage("Exception not expected: %s", e.getMessage()).that(e.getErrorCode())
+                    .isEqualTo(expectedError);
         }
     }
 
@@ -480,7 +483,7 @@
         ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
         XmlPullParser parser = Xml.newPullParser();
         parser.setInput(new InputStreamReader(inStream));
-        assertEquals(XmlPullParser.START_TAG, parser.next());
+        assertThat(parser.next()).isEqualTo(XmlPullParser.START_TAG);
         checkFreezePeriods(SystemUpdatePolicy.restoreFromXml(parser), expectedPeriods);
     }
 
@@ -488,8 +491,8 @@
             List<FreezePeriod> expectedPeriods) {
         int i = 0;
         for (FreezePeriod period : policy.getFreezePeriods()) {
-            assertEquals(expectedPeriods.get(i).getStart(), period.getStart());
-            assertEquals(expectedPeriods.get(i).getEnd(), period.getEnd());
+            assertThat(period.getStart()).isEqualTo(expectedPeriods.get(i).getStart());
+            assertThat(period.getEnd()).isEqualTo(expectedPeriods.get(i).getEnd());
             i++;
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/TransferOwnershipMetadataManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/TransferOwnershipMetadataManagerTest.java
index 2005dd9..07ea855 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/TransferOwnershipMetadataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/TransferOwnershipMetadataManagerTest.java
@@ -25,14 +25,13 @@
 import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.TAG_TARGET_COMPONENT;
 import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.TAG_USER_ID;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
 
 import android.os.Environment;
-import androidx.test.runner.AndroidJUnit4;
 import android.util.Log;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import com.android.server.devicepolicy.TransferOwnershipMetadataManager.Injector;
 import com.android.server.devicepolicy.TransferOwnershipMetadataManager.Metadata;
 
@@ -51,12 +50,14 @@
 /**
 * Unit tests for {@link TransferOwnershipMetadataManager}.
  *
- * bit FrameworksServicesTests:com.android.server.devicepolicy.TransferOwnershipMetadataManagerTest
- * runtest -x frameworks/base/services/tests/servicestests/src/com/android/server/devicepolicy/TransferOwnershipMetadataManagerTest.java
-* */
-
+ * <p>Run this test with:
+ *
+ * <pre><code>
+ atest FrameworksServicesTests:com.android.server.devicepolicy.TransferOwnershipMetadataManagerTest
+ * </code></pre>
+ */
 @RunWith(AndroidJUnit4.class)
-public class TransferOwnershipMetadataManagerTest {
+public final class TransferOwnershipMetadataManagerTest {
     private final static String TAG = TransferOwnershipMetadataManagerTest.class.getName();
     private final static String SOURCE_COMPONENT =
             "com.dummy.admin.package/com.dummy.admin.package.SourceClassName";
@@ -77,28 +78,27 @@
     @Test
     public void testSave() {
         TransferOwnershipMetadataManager paramsManager = getOwnerTransferParams();
-        assertTrue(paramsManager.saveMetadataFile(TEST_PARAMS));
-        assertTrue(paramsManager.metadataFileExists());
+        assertThat(paramsManager.saveMetadataFile(TEST_PARAMS)).isTrue();
+        assertThat(paramsManager.metadataFileExists()).isTrue();
     }
 
     @Test
     public void testFileContentValid() {
         TransferOwnershipMetadataManager paramsManager = getOwnerTransferParams();
-        assertTrue(paramsManager.saveMetadataFile(TEST_PARAMS));
+        assertThat(paramsManager.saveMetadataFile(TEST_PARAMS)).isTrue();
         Path path = Paths.get(new File(mMockInjector.getOwnerTransferMetadataDir(),
                 OWNER_TRANSFER_METADATA_XML).getAbsolutePath());
         try {
             String contents = new String(Files.readAllBytes(path), Charset.forName("UTF-8"));
-            assertEquals(
-                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
-                    + "<" + TAG_USER_ID + ">" + USER_ID + "</" + TAG_USER_ID + ">\n"
-                    + "<" + TAG_SOURCE_COMPONENT + ">" + SOURCE_COMPONENT + "</"
-                        + TAG_SOURCE_COMPONENT + ">\n"
-                    + "<" + TAG_TARGET_COMPONENT + ">" + TARGET_COMPONENT + "</"
-                        + TAG_TARGET_COMPONENT + ">\n"
-                    + "<" + TAG_ADMIN_TYPE + ">" + ADMIN_TYPE_DEVICE_OWNER + "</"
-                        + TAG_ADMIN_TYPE + ">\n",
-                contents);
+            assertThat(contents).isEqualTo(
+                    "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                            + "<" + TAG_USER_ID + ">" + USER_ID + "</" + TAG_USER_ID + ">\n"
+                            + "<" + TAG_SOURCE_COMPONENT + ">" + SOURCE_COMPONENT + "</"
+                            + TAG_SOURCE_COMPONENT + ">\n"
+                            + "<" + TAG_TARGET_COMPONENT + ">" + TARGET_COMPONENT + "</"
+                            + TAG_TARGET_COMPONENT + ">\n"
+                            + "<" + TAG_ADMIN_TYPE + ">" + ADMIN_TYPE_DEVICE_OWNER + "</"
+                            + TAG_ADMIN_TYPE + ">\n");
         } catch (IOException e) {
             e.printStackTrace();
         }
@@ -124,7 +124,7 @@
             Log.d(TAG, "testLoad: failed to get canonical file");
         }
         paramsManager.saveMetadataFile(TEST_PARAMS);
-        assertEquals(TEST_PARAMS, paramsManager.loadMetadataFile());
+        assertThat(paramsManager.loadMetadataFile()).isEqualTo(TEST_PARAMS);
     }
 
     @Test
@@ -132,7 +132,7 @@
         TransferOwnershipMetadataManager paramsManager = getOwnerTransferParams();
         paramsManager.saveMetadataFile(TEST_PARAMS);
         paramsManager.deleteMetadataFile();
-        assertFalse(paramsManager.metadataFileExists());
+        assertThat(paramsManager.metadataFileExists()).isFalse();
     }
 
     @After
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/pm/permission/PermissionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/permission/PermissionManagerServiceTest.java
index 56966776..6cea928 100644
--- a/services/tests/servicestests/src/com/android/server/pm/permission/PermissionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/permission/PermissionManagerServiceTest.java
@@ -69,8 +69,7 @@
         MockitoAnnotations.initMocks(this);
 
         mContext = InstrumentationRegistry.getContext();
-        Object lock = new Object();
-        mPermissionManagerService = new PermissionManagerService(mContext, lock, mInjector);
+        mPermissionManagerService = new PermissionManagerService(mContext, mInjector);
     }
 
     @After
diff --git a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
index af161ee..ca0270d 100644
--- a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
@@ -70,7 +70,6 @@
     private Runnable mOnUserAttention;
     private TestableAttentionDetector mAttentionDetector;
     private AttentionDetector mRealAttentionDetector;
-    private long mPreDimCheckDuration;
     private long mNextDimming;
     private int mIsSettingEnabled;
 
@@ -342,23 +341,14 @@
     public void testGetPostDimCheckDurationMillis_handlesGoodFlagValue() {
         DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                 KEY_POST_DIM_CHECK_DURATION_MILLIS, "333", false);
-        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
-                DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(333);
-    }
-
-    @Test
-    public void testGetPostDimCheckDurationMillis_capsGoodFlagValueByMaxDimDuration() {
-        DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
-                KEY_POST_DIM_CHECK_DURATION_MILLIS, "7000", false);
-        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(6500)).isEqualTo(6500);
+        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis()).isEqualTo(333);
     }
 
     @Test
     public void testGetPostDimCheckDurationMillis_rejectsNegativeValue() {
         DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                 KEY_POST_DIM_CHECK_DURATION_MILLIS, "-50", false);
-        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
-                DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(
+        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis()).isEqualTo(
                 DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
     }
 
@@ -366,8 +356,7 @@
     public void testGetPostDimCheckDurationMillis_rejectsTooBigValue() {
         DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                 KEY_POST_DIM_CHECK_DURATION_MILLIS, "20000", false);
-        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
-                DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(
+        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis()).isEqualTo(
                 DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
     }
 
@@ -375,14 +364,12 @@
     public void testGetPostDimCheckDurationMillis_handlesBadFlagValue() {
         DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                 KEY_POST_DIM_CHECK_DURATION_MILLIS, "20000k", false);
-        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
-                DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(
+        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis()).isEqualTo(
                 DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
 
         DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
                 KEY_POST_DIM_CHECK_DURATION_MILLIS, "0.25", false);
-        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
-                DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(
+        assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis()).isEqualTo(
                 DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
     }
 
@@ -423,7 +410,7 @@
     }
 
     private long registerAttention() {
-        mPreDimCheckDuration = 4000L;
+        mAttentionDetector.mPreDimCheckDurationMillis = 4000L;
         mAttentionDetector.onUserActivity(SystemClock.uptimeMillis(),
                 PowerManager.USER_ACTIVITY_EVENT_TOUCH);
         return mAttentionDetector.updateUserActivity(mNextDimming, DEFAULT_DIM_DURATION_MILLIS);
@@ -447,10 +434,5 @@
         public boolean isAttentionServiceSupported() {
             return mAttentionServiceSupported;
         }
-
-        @Override
-        public long getPreDimCheckDurationMillis() {
-            return mPreDimCheckDuration;
-        }
     }
 }
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..93666b4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -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);
@@ -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..3c5b9f9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -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 */));
@@ -676,8 +675,7 @@
                 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 */));
     }
@@ -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..3bd8c27 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -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/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
index 823aef0..5cb3ac1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
@@ -118,7 +118,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);
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/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..1879e9e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -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..4300971 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -768,7 +768,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/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java
index 8b025e3..c5c947b 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);
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/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..0b257ee 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());
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/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index b4480ae..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());
@@ -976,6 +974,21 @@
         });
     }
 
+    @Test
+    public void testReparentToOrganizedTask() {
+        final ITaskOrganizer organizer = registerMockOrganizer();
+        Task rootTask = mWm.mAtmService.mTaskOrganizerController.createRootTask(
+                mDisplayContent, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, null);
+        final Task task1 = createStack();
+        final Task task2 = createTask(rootTask, false /* fakeDraw */);
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.reparent(task1.mRemoteToken.toWindowContainerToken(),
+                rootTask.mRemoteToken.toWindowContainerToken(), true /* onTop */);
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+        assertTrue(task1.isOrganized());
+        assertTrue(task2.isOrganized());
+    }
+
     /**
      * Verifies that task vanished is called for a specific task.
      */
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..9304dc5 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;
@@ -318,8 +317,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");
 
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/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index cfc7ac1..b92d410 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -125,11 +125,7 @@
     }
 
     private static boolean isUpdatedSystemApp(ApplicationInfo ai) {
-        if ((ai.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
-            return true;
-        }
-
-        return false;
+        return (ai.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
     }
 
     /**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c982f49..425addc 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -12015,12 +12015,13 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public @NetworkTypeBitMask long getSupportedRadioAccessFamily() {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return (long) telephony.getRadioAccessFamily(getSlotIndex(), getOpPackageName());
+                return telephony.getRadioAccessFamily(getSlotIndex(), getOpPackageName());
             } else {
                 // This can happen when the ITelephony interface is not up yet.
                 return NETWORK_TYPE_BITMASK_UNKNOWN;
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/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/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/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/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl
new file mode 100644
index 0000000..a8c8329
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IOptionsResponseCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 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/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
new file mode 100644
index 0000000..481e7f8
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IPublishResponseCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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 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/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/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/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 953a292..b1700a1 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -496,6 +496,10 @@
     int RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION = 212;
     int RIL_REQUEST_ENABLE_NR_DUAL_CONNECTIVITY = 213;
     int RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED = 214;
+    int RIL_REQUEST_ALLOCATE_PDU_SESSION_ID = 215;
+    int RIL_REQUEST_RELEASE_PDU_SESSION_ID = 216;
+    int RIL_REQUEST_BEGIN_HANDOVER = 217;
+    int RIL_REQUEST_CANCEL_HANDOVER = 218;
 
     /* Responses begin */
     int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
diff --git a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
index b7d72db..c769a6f 100644
--- a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
+++ b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
@@ -16,8 +16,6 @@
 
 package com.android.tests.rollback.host;
 
-import static com.android.tests.rollback.host.WatchdogEventLogger.watchdogEventOccurred;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -31,7 +29,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -98,12 +95,11 @@
             // Verify rollback was executed after health check deadline
             runPhase("testNetworkFailedRollback_Phase3");
 
-            List<String> watchdogEvents = mLogger.getWatchdogLoggingEvents();
-            assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_INITIATE, null,
+            assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_INITIATE, null,
                     REASON_EXPLICIT_HEALTH_CHECK, null));
-            assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
+            assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_BOOT_TRIGGERED, null,
                     null, null));
-            assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
+            assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_SUCCESS, null, null, null));
         } finally {
             // Reconnect internet again so we won't break tests which assume internet available
             getDevice().executeShellCommand("svc wifi enable");
@@ -134,8 +130,7 @@
         // Verify rollback was not executed after health check deadline
         runPhase("testNetworkPassedDoesNotRollback_Phase3");
 
-        List<String> watchdogEvents = mLogger.getWatchdogLoggingEvents();
-        assertEquals(watchdogEventOccurred(watchdogEvents, null, null,
+        assertEquals(mLogger.watchdogEventOccurred(null, null,
                 REASON_EXPLICIT_HEALTH_CHECK, null), false);
     }
 }
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 725bfa9..2ebb9c1 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -16,8 +16,6 @@
 
 package com.android.tests.rollback.host;
 
-import static com.android.tests.rollback.host.WatchdogEventLogger.watchdogEventOccurred;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
@@ -158,12 +156,11 @@
 
         runPhase("testBadApkOnly_Phase4");
 
-        List<String> watchdogEvents = mLogger.getWatchdogLoggingEvents();
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_INITIATE, null,
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_INITIATE, null,
                 REASON_APP_CRASH, TESTAPP_A));
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_BOOT_TRIGGERED, null,
                 null, null));
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_SUCCESS, null, null, null));
     }
 
     @Test
@@ -192,12 +189,11 @@
         // verify rollback committed
         runPhase("testNativeWatchdogTriggersRollback_Phase3");
 
-        List<String> watchdogEvents = mLogger.getWatchdogLoggingEvents();
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_INITIATE, null,
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_INITIATE, null,
                         REASON_NATIVE_CRASH, null));
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_BOOT_TRIGGERED, null,
                 null, null));
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_SUCCESS, null, null, null));
     }
 
     @Test
@@ -233,12 +229,11 @@
         // verify all available rollbacks have been committed
         runPhase("testNativeWatchdogTriggersRollbackForAll_Phase4");
 
-        List<String> watchdogEvents = mLogger.getWatchdogLoggingEvents();
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_INITIATE, null,
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_INITIATE, null,
                         REASON_NATIVE_CRASH, null));
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_BOOT_TRIGGERED, null,
                 null, null));
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_SUCCESS, null, null, null));
     }
 
     /**
@@ -316,12 +311,11 @@
         // Verify rollback occurred due to crash of apk-in-apex
         runPhase("testRollbackApexWithApkCrashing_Phase3");
 
-        List<String> watchdogEvents = mLogger.getWatchdogLoggingEvents();
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_INITIATE, null,
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_INITIATE, null,
                 REASON_APP_CRASH, TESTAPP_A));
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_BOOT_TRIGGERED, null,
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_BOOT_TRIGGERED, null,
                 null, null));
-        assertTrue(watchdogEventOccurred(watchdogEvents, ROLLBACK_SUCCESS, null, null, null));
+        assertTrue(mLogger.watchdogEventOccurred(ROLLBACK_SUCCESS, null, null, null));
     }
 
     /**
diff --git a/tests/RollbackTest/lib/src/com/android/tests/rollback/host/WatchdogEventLogger.java b/tests/RollbackTest/lib/src/com/android/tests/rollback/host/WatchdogEventLogger.java
index 8873150..6b0d1f8 100644
--- a/tests/RollbackTest/lib/src/com/android/tests/rollback/host/WatchdogEventLogger.java
+++ b/tests/RollbackTest/lib/src/com/android/tests/rollback/host/WatchdogEventLogger.java
@@ -17,52 +17,50 @@
 package com.android.tests.rollback.host;
 
 import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.LogcatReceiver;
-import com.android.tradefed.result.InputStreamSource;
 
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
+import static com.google.common.truth.Truth.assertThat;
 
 public class WatchdogEventLogger {
-    private LogcatReceiver mReceiver;
+    private static final String[] ROLLBACK_EVENT_TYPES = {
+            "ROLLBACK_INITIATE", "ROLLBACK_BOOT_TRIGGERED", "ROLLBACK_SUCCESS"};
+    private static final String[] ROLLBACK_EVENT_ATTRS = {
+            "logPackage", "rollbackReason", "failedPackageName"};
+    private static final String PROP_PREFIX = "persist.sys.rollbacktest.";
 
-    public void start(ITestDevice device) {
-        mReceiver =  new LogcatReceiver(device, "logcat -s WatchdogRollbackLogger",
-                device.getOptions().getMaxLogcatDataSize(), 0);
-        mReceiver.start();
-    }
+    private ITestDevice mDevice;
 
-    public void stop() {
-        if (mReceiver != null) {
-            mReceiver.stop();
-            mReceiver.clear();
-        }
-    }
-
-    /**
-     * Returns a list of all Watchdog logging events which have occurred.
-     */
-    public List<String> getWatchdogLoggingEvents() throws Exception {
-        try (InputStreamSource logcatStream = mReceiver.getLogcatData()) {
-            return getWatchdogLoggingEvents(logcatStream);
-        }
-    }
-
-    private static List<String> getWatchdogLoggingEvents(InputStreamSource inputStreamSource)
-            throws Exception {
-        List<String> watchdogEvents = new ArrayList<>();
-        InputStream inputStream = inputStreamSource.createInputStream();
-        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
-        String line;
-        while ((line = reader.readLine()) != null) {
-            if (line.contains("Watchdog event occurred")) {
-                watchdogEvents.add(line);
+    private void resetProperties(boolean enabled) throws Exception {
+        try {
+            mDevice.enableAdbRoot();
+            assertThat(mDevice.setProperty(
+                    PROP_PREFIX + "enabled", String.valueOf(enabled))).isTrue();
+            for (String type : ROLLBACK_EVENT_TYPES) {
+                String key = PROP_PREFIX + type;
+                assertThat(mDevice.setProperty(key, "")).isTrue();
+                for (String attr : ROLLBACK_EVENT_ATTRS) {
+                    assertThat(mDevice.setProperty(key + "." + attr, "")).isTrue();
+                }
             }
+        } finally {
+            mDevice.disableAdbRoot();
         }
-        return watchdogEvents;
+    }
+
+    public void start(ITestDevice device) throws Exception {
+        mDevice = device;
+        resetProperties(true);
+    }
+
+    public void stop() throws Exception {
+        if (mDevice != null) {
+            resetProperties(false);
+        }
+    }
+
+    private boolean matchProperty(String type, String attr, String expectedVal) throws Exception {
+        String key = PROP_PREFIX + type + "." + attr;
+        String val = mDevice.getProperty(key);
+        return expectedVal == null || expectedVal.equals(val);
     }
 
     /**
@@ -71,33 +69,11 @@
      * Check the value of all non-null parameters against the list of Watchdog events that have
      * occurred, and return {@code true} if an event exists which matches all criteria.
      */
-    public static boolean watchdogEventOccurred(List<String> loggingEvents,
-            String type, String logPackage,
+    public boolean watchdogEventOccurred(String type, String logPackage,
             String rollbackReason, String failedPackageName) throws Exception {
-        List<String> eventCriteria = new ArrayList<>();
-        if (type != null) {
-            eventCriteria.add("type: " + type);
-        }
-        if (logPackage != null) {
-            eventCriteria.add("logPackage: " + logPackage);
-        }
-        if (rollbackReason != null) {
-            eventCriteria.add("rollbackReason: " + rollbackReason);
-        }
-        if (failedPackageName != null) {
-            eventCriteria.add("failedPackageName: " + failedPackageName);
-        }
-        for (String loggingEvent: loggingEvents) {
-            boolean matchesCriteria = true;
-            for (String criterion: eventCriteria) {
-                if (!loggingEvent.contains(criterion)) {
-                    matchesCriteria = false;
-                }
-            }
-            if (matchesCriteria) {
-                return true;
-            }
-        }
-        return false;
+        return mDevice.getBooleanProperty(PROP_PREFIX + type, false)
+                && matchProperty(type, "logPackage", logPackage)
+                && matchProperty(type, "rollbackReason", rollbackReason)
+                && matchProperty(type, "failedPackageName", failedPackageName);
     }
 }
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index fa4df4e..b47be97 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
@@ -36,6 +37,7 @@
 import android.content.res.Resources;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
+import android.os.UserHandle;
 import android.telephony.TelephonyManager;
 
 import androidx.test.filters.SmallTest;
@@ -47,6 +49,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.AdditionalAnswers;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -104,10 +107,15 @@
         when(mCtx.getResources()).thenReturn(mResources);
         when(mCtx.getPackageManager()).thenReturn(mPm);
         when(mCtx.getApplicationInfo()).thenReturn(new ApplicationInfo());
+        final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mCtx));
+        doReturn(UserHandle.ALL).when(asUserCtx).getUser();
+        when(mCtx.createContextAsUser(eq(UserHandle.ALL), anyInt())).thenReturn(asUserCtx);
+        when(mCtx.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
+                .thenReturn(mNotificationManager);
         when(mNetworkInfo.getExtraInfo()).thenReturn("extra");
         when(mResources.getColor(anyInt(), any())).thenReturn(0xFF607D8B);
 
-        mManager = new NetworkNotificationManager(mCtx, mTelephonyManager, mNotificationManager);
+        mManager = new NetworkNotificationManager(mCtx, mTelephonyManager);
     }
 
     private void verifyTitleByNetwork(final int id, final NetworkAgentInfo nai, final int title) {
diff --git a/wifi/aidl-export/android/net/wifi/aware/AwareResources.aidl b/wifi/aidl-export/android/net/wifi/aware/AwareResources.aidl
new file mode 100644
index 0000000..d0bd2dd
--- /dev/null
+++ b/wifi/aidl-export/android/net/wifi/aware/AwareResources.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.net.wifi.aware;
+
+parcelable AwareResources;
\ No newline at end of file
diff --git a/wifi/api/current.txt b/wifi/api/current.txt
index 0bc1ff2..d5ef703 100644
--- a/wifi/api/current.txt
+++ b/wifi/api/current.txt
@@ -561,6 +561,15 @@
     method public void onAttached(android.net.wifi.aware.WifiAwareSession);
   }
 
+  public final class AwareResources implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getNumOfAvailableDataPaths();
+    method public int getNumOfAvailablePublishSessions();
+    method public int getNumOfAvailableSubscribeSessions();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.aware.AwareResources> CREATOR;
+  }
+
   public final class Characteristics implements android.os.Parcelable {
     method public int describeContents();
     method public int getMaxMatchFilterLength();
@@ -663,7 +672,8 @@
   public class WifiAwareManager {
     method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @Nullable android.os.Handler);
     method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler);
-    method public android.net.wifi.aware.Characteristics getCharacteristics();
+    method @Nullable public android.net.wifi.aware.AwareResources getAvailableAwareResources();
+    method @Nullable public android.net.wifi.aware.Characteristics getCharacteristics();
     method public boolean isAvailable();
     method public boolean isDeviceAttached();
     method public boolean isInstantCommunicationModeEnabled();
diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt
index 7c592f0..edbd463 100644
--- a/wifi/api/system-current.txt
+++ b/wifi/api/system-current.txt
@@ -246,6 +246,7 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.SoftApCapability> CREATOR;
     field public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1L; // 0x1L
     field public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 2L; // 0x2L
+    field public static final long SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION = 8L; // 0x8L
     field public static final long SOFTAP_FEATURE_WPA3_SAE = 4L; // 0x4L
   }
 
@@ -427,8 +428,11 @@
     method public double getSuccessfulRxPacketsPerSecond();
     method public double getSuccessfulTxPacketsPerSecond();
     method public boolean isEphemeral();
+    method public boolean isOemPaid();
+    method public boolean isOemPrivate();
     method public boolean isOsuAp();
     method public boolean isPasspointAp();
+    method public boolean isTrusted();
     method @Nullable public static String sanitizeSsid(@Nullable String);
     field public static final String DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
     field public static final int INVALID_RSSI = -127; // 0xffffff81
@@ -617,11 +621,13 @@
   public final class WifiNetworkSuggestion implements android.os.Parcelable {
     method @NonNull public android.net.wifi.WifiConfiguration getWifiConfiguration();
     method public boolean isOemPaid();
+    method public boolean isOemPrivate();
   }
 
   public static final class WifiNetworkSuggestion.Builder {
     method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_CARRIER_PROVISIONING) public android.net.wifi.WifiNetworkSuggestion.Builder setCarrierId(int);
     method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setOemPaid(boolean);
+    method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setOemPrivate(boolean);
   }
 
   public class WifiScanner {
diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt
index b0ff4bb..ff06a18 100644
--- a/wifi/jarjar-rules.txt
+++ b/wifi/jarjar-rules.txt
@@ -36,7 +36,7 @@
 rule android.net.ipmemorystore.NetworkAttributesParcelable* com.android.wifi.x.@0
 rule android.net.ipmemorystore.SameL3NetworkResponseParcelable* com.android.wifi.x.@0
 rule android.net.ipmemorystore.StatusParcelable* com.android.wifi.x.@0
-rule android.net.networkstack.aidl.quirks.IPv6ProvisioningLossQuirk* com.android.wifi.x.@0
+rule android.net.networkstack.aidl.** com.android.wifi.x.@0
 
 # Net utils (includes Network Stack helper classes).
 rule android.net.DhcpResults* com.android.wifi.x.@0
diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java
index 6bd4211..d570b7e 100644
--- a/wifi/java/android/net/wifi/SoftApCapability.java
+++ b/wifi/java/android/net/wifi/SoftApCapability.java
@@ -46,7 +46,7 @@
      * Support for automatic channel selection in driver (ACS).
      * Driver will auto select best channel based on interference to optimize performance.
      *
-     * flag when {@link R.bool.config_wifi_softap_acs_supported)} is true.
+     * flag when {@link R.bool.config_wifi_softap_acs_supported} is true.
      *
      * <p>
      * Use {@link WifiManager.SoftApCallback#onInfoChanged(SoftApInfo)} and
@@ -57,7 +57,7 @@
 
     /**
      * Support for client force disconnect.
-     * flag when {@link R.bool.config_wifi_sofap_client_force_disconnect_supported)} is true
+     * flag when {@link R.bool.config_wifiSofapClientForceDisconnectSupported} is true
      *
      * <p>
      * Several Soft AP client control features, e.g. specifying the maximum number of
@@ -67,20 +67,32 @@
      */
     public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1;
 
-
     /**
      * Support for WPA3 Simultaneous Authentication of Equals (WPA3-SAE).
      *
-     * flag when {@link config_wifi_softap_sae_supported)} is true.
+     * flag when {@link config_wifi_softap_sae_supported} is true.
      */
     public static final long SOFTAP_FEATURE_WPA3_SAE = 1 << 2;
 
+    /**
+     * Support for MAC address customization.
+     * flag when {@link R.bool.config_wifiSoftapMacAddressCustomizationSupported} is true
+     *
+     * <p>
+     * Check feature support before invoking
+     * {@link SoftApConfiguration.Builder#setBssid(MadAddress)} or
+     * {@link SoftApConfiguration.Builder#setMacRandomizationSetting(int)} with
+     * {@link SoftApConfiguration.RANDOMIZATION_PERSISTENT}
+     */
+    public static final long SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION = 1 << 3;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @LongDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = {
             SOFTAP_FEATURE_ACS_OFFLOAD,
             SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT,
             SOFTAP_FEATURE_WPA3_SAE,
+            SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION,
     })
     public @interface HotspotFeatures {}
 
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index 2c53daaf..c0f6e7a 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -819,6 +819,11 @@
          * Derived MAC address 1: e2:c7:60:c4:0e:b7
          * Derived MAC address 2: e2:38:9f:c4:0e:b7
          *
+         * <p>
+         * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
+         * {@link SoftApCapability#areFeaturesSupported(long)}
+         * with {@link SoftApCapability.SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION} to determine
+         * whether or not this feature is supported.
          *
          * @param bssid BSSID, or null to have the BSSID chosen by the framework. The caller is
          *              responsible for avoiding collisions.
@@ -957,9 +962,9 @@
          * {@link #setBand(int)}.
          *
          * The channel auto selection will be offloaded to driver when
-         * {@link SoftApCapability#areFeaturesSupported(
-         * SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)}
-         * returns true. The driver will auto select the best channel (e.g. best performance)
+         * {@link SoftApCapability#areFeaturesSupported(long)}
+         * with {@link SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD}
+         * return true. The driver will auto select the best channel (e.g. best performance)
          * based on environment interference. Check {@link SoftApCapability} for more detail.
          *
          * The API contains (band, channel) input since the 6GHz band uses the same channel
@@ -998,8 +1003,8 @@
          * auto-select a valid channel from the band configured with {@link #setBands(int[])}.
          *
          * The channel auto selection will be offloaded to driver when
-         * {@link SoftApCapability#areFeaturesSupported(
-         * SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD)}
+         * {@link SoftApCapability#areFeaturesSupported(long)}
+         * with {@link SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD}
          * returns true. The driver will auto select the best channel (e.g. best performance)
          * based on environment interference. Check {@link SoftApCapability} for more detail.
          *
@@ -1046,14 +1051,14 @@
          * <p>
          * <li>If not set, defaults to 0.</li>
          *
-         * This method requires hardware support. If the method is used to set a
+         * This method requires HAL support. If the method is used to set a
          * non-zero {@code maxNumberOfClients} value then
          * {@link WifiManager#startTetheredHotspot} will report error code
          * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
          *
          * <p>
          * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
-         * {@link SoftApCapability#areFeaturesSupported(int)}
+         * {@link SoftApCapability#areFeaturesSupported(long)}
          * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} to determine whether
          * or not this feature is supported.
          *
@@ -1127,13 +1132,13 @@
          * {@link #setBlockedClientList(List)} and {@link #setAllowedClientList(List)}.
          *
          * <p>
-         * This method requires hardware support. Hardware support can be determined using
+         * This method requires HAL support. HAL support can be determined using
          * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
-         * {@link SoftApCapability#areFeaturesSupported(int)}
+         * {@link SoftApCapability#areFeaturesSupported(long)}
          * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT}
          *
          * <p>
-         * If the method is called on a device without hardware support then starting the soft AP
+         * If the method is called on a device without HAL support then starting the soft AP
          * using {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} will fail with
          * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
          *
@@ -1182,13 +1187,13 @@
          * to the Soft AP.
          *
          * <p>
-         * This method requires hardware support. Hardware support can be determined using
+         * This method requires HAL support. HAL support can be determined using
          * {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
-         * {@link SoftApCapability#areFeaturesSupported(int)}
+         * {@link SoftApCapability#areFeaturesSupported(long)}
          * with {@link SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT}
          *
          * <p>
-         * If the method is called on a device without hardware support then starting the soft AP
+         * If the method is called on a device without HAL support then starting the soft AP
          * using {@link WifiManager#startTetheredHotspot(SoftApConfiguration)} will fail with
          * {@link WifiManager#SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION}.
          *
@@ -1210,7 +1215,14 @@
          * <p>
          * <li>If not set, defaults to {@link #RANDOMIZATION_PERSISTENT}</li>
          *
-         * @param macRandomizationSetting One of the following setting:.
+         * <p>
+         * Requires HAL support when set to {@link #RANDOMIZATION_PERSISTENT}.
+         * Use {@link WifiManager.SoftApCallback#onCapabilityChanged(SoftApCapability)} and
+         * {@link SoftApCapability#areFeaturesSupported(long)}
+         * with {@link SoftApCapability.SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION} to determine
+         * whether or not this feature is supported.
+         *
+         * @param macRandomizationSetting One of the following setting:
          * {@link #RANDOMIZATION_NONE} or {@link #RANDOMIZATION_PERSISTENT}.
          * @return Builder for chaining.
          *
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 9ca64d2..9298c1e 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -1011,6 +1011,17 @@
      */
     public boolean oemPaid;
 
+
+    /**
+     * Indicate whether the network is oem private or not. Networks are considered oem private
+     * if the corresponding connection is only available to system apps.
+     *
+     * This bit can only be used by suggestion network, see
+     * {@link WifiNetworkSuggestion.Builder#setOemPrivate(boolean)}
+     * @hide
+     */
+    public boolean oemPrivate;
+
     /**
      * True if this Wifi configuration is created from a {@link WifiNetworkSuggestion},
      * false otherwise.
@@ -1349,36 +1360,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.
@@ -1428,6 +1429,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;
 
@@ -2249,6 +2252,7 @@
         osu = false;
         trusted = true; // Networks are considered trusted by default.
         oemPaid = false;
+        oemPrivate = false;
         fromWifiNetworkSuggestion = false;
         fromWifiNetworkSpecifier = false;
         meteredHint = false;
@@ -2372,13 +2376,14 @@
         if (this.osu) sbuf.append(" osu");
         if (this.trusted) sbuf.append(" trusted");
         if (this.oemPaid) sbuf.append(" oemPaid");
+        if (this.oemPrivate) sbuf.append(" oemPrivate");
         if (this.fromWifiNetworkSuggestion) sbuf.append(" fromWifiNetworkSuggestion");
         if (this.fromWifiNetworkSpecifier) sbuf.append(" fromWifiNetworkSpecifier");
         if (this.meteredHint) sbuf.append(" meteredHint");
         if (this.useExternalScores) sbuf.append(" useExternalScores");
         if (this.validatedInternetAccess || this.ephemeral || this.trusted || this.oemPaid
-                || this.fromWifiNetworkSuggestion || this.fromWifiNetworkSpecifier
-                || this.meteredHint || this.useExternalScores) {
+                || this.oemPrivate || this.fromWifiNetworkSuggestion
+                || this.fromWifiNetworkSpecifier || this.meteredHint || this.useExternalScores) {
             sbuf.append("\n");
         }
         if (this.meteredOverride != METERED_OVERRIDE_NONE) {
@@ -2943,6 +2948,7 @@
             osu = source.osu;
             trusted = source.trusted;
             oemPaid = source.oemPaid;
+            oemPrivate = source.oemPrivate;
             fromWifiNetworkSuggestion = source.fromWifiNetworkSuggestion;
             fromWifiNetworkSpecifier = source.fromWifiNetworkSpecifier;
             meteredHint = source.meteredHint;
@@ -3024,6 +3030,7 @@
         dest.writeInt(ephemeral ? 1 : 0);
         dest.writeInt(trusted ? 1 : 0);
         dest.writeInt(oemPaid ? 1 : 0);
+        dest.writeInt(oemPrivate ? 1 : 0);
         dest.writeInt(fromWifiNetworkSuggestion ? 1 : 0);
         dest.writeInt(fromWifiNetworkSpecifier ? 1 : 0);
         dest.writeInt(meteredHint ? 1 : 0);
@@ -3102,6 +3109,7 @@
                 config.ephemeral = in.readInt() != 0;
                 config.trusted = in.readInt() != 0;
                 config.oemPaid = in.readInt() != 0;
+                config.oemPrivate = in.readInt() != 0;
                 config.fromWifiNetworkSuggestion =  in.readInt() != 0;
                 config.fromWifiNetworkSpecifier =  in.readInt() != 0;
                 config.meteredHint = in.readInt() != 0;
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index fe5002e..774c043 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -164,6 +164,11 @@
     private boolean mOemPaid;
 
     /**
+     * Whether the network is oem private or not.
+     */
+    private boolean mOemPrivate;
+
+    /**
      * OSU (Online Sign Up) AP for Passpoint R2.
      */
     private boolean mOsuAp;
@@ -327,6 +332,9 @@
         setFrequency(-1);
         setMeteredHint(false);
         setEphemeral(false);
+        setTrusted(false);
+        setOemPaid(false);
+        setOemPrivate(false);
         setOsuAp(false);
         setRequestingPackageName(null);
         setFQDN(null);
@@ -363,7 +371,8 @@
             mMeteredHint = source.mMeteredHint;
             mEphemeral = source.mEphemeral;
             mTrusted = source.mTrusted;
-            mTrusted = source.mOemPaid;
+            mOemPaid = source.mOemPaid;
+            mOemPrivate = source.mOemPrivate;
             mRequestingPackageName =
                     source.mRequestingPackageName;
             mOsuAp = source.mOsuAp;
@@ -722,7 +731,12 @@
         mTrusted = trusted;
     }
 
-    /** {@hide} */
+    /**
+     * Returns true if the current Wifi network is a trusted network, false otherwise.
+     * @see WifiNetworkSuggestion.Builder#setUntrusted(boolean).
+     * {@hide}
+     */
+    @SystemApi
     public boolean isTrusted() {
         return mTrusted;
     }
@@ -732,12 +746,32 @@
         mOemPaid = oemPaid;
     }
 
-    /** {@hide} */
+    /**
+     * Returns true if the current Wifi network is an oem paid network, false otherwise.
+     * @see WifiNetworkSuggestion.Builder#setOemPaid(boolean).
+     * {@hide}
+     */
+    @SystemApi
     public boolean isOemPaid() {
         return mOemPaid;
     }
 
     /** {@hide} */
+    public void setOemPrivate(boolean oemPrivate) {
+        mOemPrivate = oemPrivate;
+    }
+
+    /**
+     * Returns true if the current Wifi network is an oem private network, false otherwise.
+     * @see WifiNetworkSuggestion.Builder#setOemPrivate(boolean).
+     * {@hide}
+     */
+    @SystemApi
+    public boolean isOemPrivate() {
+        return mOemPrivate;
+    }
+
+    /** {@hide} */
     public void setOsuAp(boolean osuAp) {
         mOsuAp = osuAp;
     }
@@ -975,6 +1009,7 @@
         dest.writeInt(mEphemeral ? 1 : 0);
         dest.writeInt(mTrusted ? 1 : 0);
         dest.writeInt(mOemPaid ? 1 : 0);
+        dest.writeInt(mOemPrivate ? 1 : 0);
         dest.writeInt(score);
         dest.writeLong(txSuccess);
         dest.writeDouble(mSuccessfulTxPacketsPerSecond);
@@ -1021,6 +1056,7 @@
                 info.mEphemeral = in.readInt() != 0;
                 info.mTrusted = in.readInt() != 0;
                 info.mOemPaid = in.readInt() != 0;
+                info.mOemPrivate = in.readInt() != 0;
                 info.score = in.readInt();
                 info.txSuccess = in.readLong();
                 info.mSuccessfulTxPacketsPerSecond = in.readDouble();
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index acae218..dc6ec90 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -25,6 +25,7 @@
 import android.annotation.SystemApi;
 import android.net.MacAddress;
 import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
 import android.net.wifi.hotspot2.PasspointConfiguration;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -180,6 +181,12 @@
         private boolean mIsNetworkOemPaid;
 
         /**
+         * Whether this network will be brought up as OEM private (OEM_PRIVATE capability bit
+         * added).
+         */
+        private boolean mIsNetworkOemPrivate;
+
+        /**
          * Whether this network will use enhanced MAC randomization.
          */
         private boolean mIsEnhancedMacRandomizationEnabled;
@@ -206,6 +213,7 @@
             mWapiEnterpriseConfig = null;
             mIsNetworkUntrusted = false;
             mIsNetworkOemPaid = false;
+            mIsNetworkOemPrivate = false;
             mPriorityGroup = 0;
             mIsEnhancedMacRandomizationEnabled = false;
             mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -667,6 +675,9 @@
          * reduce it). The connectivity service may use this information to influence the overall
          * network configuration of the device.
          * <p>
+         * <li> These suggestions are only considered for network selection if a
+         * {@link NetworkRequest} without {@link NetworkCapabilities#NET_CAPABILITY_TRUSTED}
+         * capability is filed.
          * <li> An untrusted network's credentials may not be shared with the user using
          * {@link #setCredentialSharedWithUser(boolean)}.</li>
          * <li> If not set, defaults to false (i.e. network is trusted).</li>
@@ -688,7 +699,7 @@
          * <li>The connectivity service may use this information to influence the overall
          * network configuration of the device. This network is typically only available to system
          * apps.
-         * <li>On devices which support only 1 concurrent connection (indicated via
+         * <li>On devices which do not support concurrent connection (indicated via
          * {@link WifiManager#isMultiStaConcurrencySupported()}, Wi-Fi network selection process may
          * use this information to influence priority of the suggested network for Wi-Fi network
          * selection (most likely to reduce it).
@@ -699,6 +710,13 @@
          * <p>
          * <li> An OEM paid network's credentials may not be shared with the user using
          * {@link #setCredentialSharedWithUser(boolean)}.</li>
+         * <li> These suggestions are only considered for network selection if a
+         * {@link NetworkRequest} with {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}
+         * capability is filed.
+         * <li> Each suggestion can have both {@link #setOemPaid(boolean)} and
+         * {@link #setOemPrivate(boolean)} set if the app wants these suggestions considered
+         * for creating either an OEM paid network or OEM private network determined based on
+         * the {@link NetworkRequest} that is active.
          * <li> If not set, defaults to false (i.e. network is not OEM paid).</li>
          *
          * @param isOemPaid Boolean indicating whether the network should be brought up as OEM paid
@@ -715,6 +733,48 @@
             return this;
         }
 
+        /**
+         * Specifies whether the system will bring up the network (if selected) as OEM private. An
+         * OEM private network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE} capability
+         * added.
+         * Note:
+         * <li>The connectivity service may use this information to influence the overall
+         * network configuration of the device. This network is typically only available to system
+         * apps.
+         * <li>On devices which do not support concurrent connection (indicated via
+         * {@link WifiManager#isMultiStaConcurrencySupported()}, Wi-Fi network selection process may
+         * use this information to influence priority of the suggested network for Wi-Fi network
+         * selection (most likely to reduce it).
+         * <li>On devices which support more than 1 concurrent connections (indicated via
+         * {@link WifiManager#isMultiStaConcurrencySupported()}, these OEM private networks will be
+         * brought up as a secondary concurrent connection (primary connection will be used
+         * for networks available to the user and all apps.
+         * <p>
+         * <li> An OEM private network's credentials may not be shared with the user using
+         * {@link #setCredentialSharedWithUser(boolean)}.</li>
+         * <li> These suggestions are only considered for network selection if a
+         * {@link NetworkRequest} with {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}
+         * capability is filed.
+         * <li> Each suggestion can have both {@link #setOemPaid(boolean)} and
+         * {@link #setOemPrivate(boolean)} set if the app wants these suggestions considered
+         * for creating either an OEM paid network or OEM private network determined based on
+         * the {@link NetworkRequest} that is active.
+         * <li> If not set, defaults to false (i.e. network is not OEM private).</li>
+         *
+         * @param isOemPrivate Boolean indicating whether the network should be brought up as OEM
+         *                     private (if true) or not OEM private (if false).
+         * @return Instance of {@link Builder} to enable chaining of the builder method.
+         * @hide
+         */
+        @SystemApi
+        public @NonNull Builder setOemPrivate(boolean isOemPrivate) {
+            if (!SdkLevel.isAtLeastS()) {
+                throw new UnsupportedOperationException();
+            }
+            mIsNetworkOemPrivate = isOemPrivate;
+            return this;
+        }
+
         private void setSecurityParamsInWifiConfiguration(
                 @NonNull WifiConfiguration configuration) {
             if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network.
@@ -786,6 +846,7 @@
             wifiConfiguration.carrierId = mCarrierId;
             wifiConfiguration.trusted = !mIsNetworkUntrusted;
             wifiConfiguration.oemPaid = mIsNetworkOemPaid;
+            wifiConfiguration.oemPrivate = mIsNetworkOemPrivate;
             wifiConfiguration.macRandomizationSetting = mIsEnhancedMacRandomizationEnabled
                     ? WifiConfiguration.RANDOMIZATION_ENHANCED
                     : WifiConfiguration.RANDOMIZATION_PERSISTENT;
@@ -819,6 +880,7 @@
             wifiConfiguration.meteredOverride = mMeteredOverride;
             wifiConfiguration.trusted = !mIsNetworkUntrusted;
             wifiConfiguration.oemPaid = mIsNetworkOemPaid;
+            wifiConfiguration.oemPrivate = mIsNetworkOemPrivate;
             wifiConfiguration.subscriptionId = mSubscriptionId;
             mPasspointConfiguration.setCarrierId(mCarrierId);
             mPasspointConfiguration.setSubscriptionId(mSubscriptionId);
@@ -938,6 +1000,14 @@
                 }
                 mIsSharedWithUser = false;
             }
+            if (mIsNetworkOemPrivate) {
+                if (mIsSharedWithUserSet && mIsSharedWithUser) {
+                    throw new IllegalStateException("Should not be both"
+                            + "setCredentialSharedWithUser and +"
+                            + "setOemPrivate to true");
+                }
+                mIsSharedWithUser = false;
+            }
             return new WifiNetworkSuggestion(
                     wifiConfiguration,
                     mPasspointConfiguration,
@@ -1105,6 +1175,7 @@
                 .append(", isInitialAutoJoinEnabled=").append(isInitialAutoJoinEnabled)
                 .append(", isUnTrusted=").append(!wifiConfiguration.trusted)
                 .append(", isOemPaid=").append(wifiConfiguration.oemPaid)
+                .append(", isOemPrivate=").append(wifiConfiguration.oemPrivate)
                 .append(", priorityGroup=").append(priorityGroup)
                 .append(" ]");
         return sb.toString();
@@ -1212,6 +1283,18 @@
     }
 
     /**
+     * @see Builder#setOemPrivate(boolean)
+     * @hide
+     */
+    @SystemApi
+    public boolean isOemPrivate() {
+        if (!SdkLevel.isAtLeastS()) {
+            throw new UnsupportedOperationException();
+        }
+        return wifiConfiguration.oemPrivate;
+    }
+
+    /**
      * Get the WifiEnterpriseConfig, or null if unset.
      * @see Builder#setWapiEnterpriseConfig(WifiEnterpriseConfig)
      * @see Builder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)
diff --git a/wifi/java/android/net/wifi/aware/AwareResources.java b/wifi/java/android/net/wifi/aware/AwareResources.java
new file mode 100644
index 0000000..cee1f40
--- /dev/null
+++ b/wifi/java/android/net/wifi/aware/AwareResources.java
@@ -0,0 +1,146 @@
+/*
+ * 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.wifi.aware;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The resources of the Aware service.
+ */
+public final class AwareResources implements Parcelable {
+    /**
+     * Number of the NDPs are available.
+     */
+    private int mNumOfAvailableNdps;
+
+    /**
+     * Number of the publish sessions are available.
+     */
+    private int mNumOfAvailablePublishSessions;
+
+    /**
+     * Number of the subscribe sessions are available.
+     */
+    private int mNumOfAvailableSubscribeSessions;
+
+    /**
+     * @hide : should not be created by apps
+     */
+    public AwareResources() {
+    }
+
+    /**
+     * Return the number of Aware data-paths (also known as NDPs - NAN Data Paths) which an app
+     * could create. Please refer to the {@link WifiAwareNetworkSpecifier} to create
+     * a Network Specifier and request a data-path.
+     * <p>
+     * Note that these resources aren't reserved - other apps could use them by the time you
+     * attempt to create a data-path.
+     * </p>
+     * @return A Non-negative integer, number of data-paths that could be created.
+     */
+    public int getNumOfAvailableDataPaths() {
+        return mNumOfAvailableNdps;
+    }
+
+    /**
+     * Return the number of Aware publish sessions which an app could create. Please refer to the
+     * {@link WifiAwareSession#publish(PublishConfig, DiscoverySessionCallback, Handler)}
+     * to create a publish session.
+     * <p>
+     * Note that these resources aren't reserved - other apps could use them by the time you
+     * attempt to create a publish session.
+     * </p>
+     * @return A Non-negative integer, number of publish sessions that could be created.
+     */
+    public int getNumOfAvailablePublishSessions() {
+        return mNumOfAvailablePublishSessions;
+    }
+
+    /**
+     * Return the number of Aware subscribe sessions which an app could create. Please refer to the
+     * {@link WifiAwareSession#subscribe(SubscribeConfig, DiscoverySessionCallback, Handler)}
+     * to create a publish session.
+     * <p>
+     * Note that these resources aren't reserved - other apps could use them by the time you
+     * attempt to create a subscribe session.
+     * </p>
+     * @return A Non-negative integer, number of subscribe sessions that could be created.
+     */
+    public int getNumOfAvailableSubscribeSessions() {
+        return mNumOfAvailableSubscribeSessions;
+    }
+
+    /**
+     * Set the number of the available NDPs.
+     * @hide
+     * @param numOfAvailableNdps Number of available NDPs.
+     */
+    public void setNumOfAvailableDataPaths(int numOfAvailableNdps) {
+        mNumOfAvailableNdps = numOfAvailableNdps;
+    }
+
+    /**
+     * Set the number of the available publish sessions.
+     * @hide
+     * @param numOfAvailablePublishSessions Number of available publish sessions.
+     */
+    public void setNumOfAvailablePublishSessions(int numOfAvailablePublishSessions) {
+        mNumOfAvailablePublishSessions = numOfAvailablePublishSessions;
+    }
+
+    /**
+     * Set the number of the available subscribe sessions.
+     * @hide
+     * @param numOfAvailableSubscribeSessions Number of available subscribe sessions.
+     */
+    public void setNumOfAvailableSubscribeSessions(int numOfAvailableSubscribeSessions) {
+        mNumOfAvailableSubscribeSessions = numOfAvailableSubscribeSessions;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mNumOfAvailableNdps);
+        dest.writeInt(mNumOfAvailablePublishSessions);
+        dest.writeInt(mNumOfAvailableSubscribeSessions);
+    }
+
+    public static final @android.annotation.NonNull Creator<AwareResources> CREATOR =
+            new Creator<AwareResources>() {
+                @Override
+                public AwareResources createFromParcel(Parcel in) {
+                    AwareResources awareResources = new AwareResources();
+                    awareResources.setNumOfAvailableDataPaths(in.readInt());
+                    awareResources.setNumOfAvailablePublishSessions(in.readInt());
+                    awareResources.setNumOfAvailableSubscribeSessions(in.readInt());
+                    return awareResources;
+                }
+
+                @Override
+                public AwareResources[] newArray(int size) {
+                    return new AwareResources[size];
+                }
+            };
+}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
index cd2ca69..c90c4d8 100644
--- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
@@ -25,6 +25,7 @@
 import android.net.wifi.aware.PublishConfig;
 import android.net.wifi.aware.SubscribeConfig;
 import android.net.wifi.aware.Characteristics;
+import android.net.wifi.aware.AwareResources;
 
 /**
  * Interface that WifiAwareService implements
@@ -36,6 +37,7 @@
     // Aware API
     boolean isUsageEnabled();
     Characteristics getCharacteristics();
+    AwareResources getAvailableAwareResources();
     boolean isDeviceAttached();
     void enableInstantCommunicationMode(in String callingPackage, boolean enable);
     boolean isInstantCommunicationModeEnabled();
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 67c6032..e19b095 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -263,7 +263,7 @@
      *
      * @return An object specifying configuration limitations of Aware.
      */
-    public Characteristics getCharacteristics() {
+    public @Nullable Characteristics getCharacteristics() {
         try {
             return mService.getCharacteristics();
         } catch (RemoteException e) {
@@ -272,6 +272,23 @@
     }
 
     /**
+     * Return the available resources of the Wi-Fi aware service: a set of parameters which specify
+     * limitations on service usage, e.g the number of data-paths which could be created..
+     *
+     * @return An object specifying the currently available resource of the Wi-Fi Aware service.
+     */
+    public @Nullable AwareResources getAvailableAwareResources() {
+        if (!SdkLevel.isAtLeastS()) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            return mService.getAvailableAwareResources();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Attach to the Wi-Fi Aware service - enabling the application to create discovery sessions or
      * create connections to peers. The device will attach to an existing cluster if it can find
      * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
index b82c67b..f09c37d 100644
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -69,6 +69,7 @@
         config.setPasspointManagementObjectTree(cookie);
         config.trusted = false;
         config.oemPaid = true;
+        config.oemPrivate = true;
         config.updateIdentifier = "1234";
         config.fromWifiNetworkSpecifier = true;
         config.fromWifiNetworkSuggestion = true;
@@ -91,8 +92,10 @@
         assertEquals(macBeforeParcel, reconfig.getRandomizedMacAddress());
         assertEquals(config.updateIdentifier, reconfig.updateIdentifier);
         assertFalse(reconfig.trusted);
-        assertTrue(config.fromWifiNetworkSpecifier);
-        assertTrue(config.fromWifiNetworkSuggestion);
+        assertTrue(reconfig.fromWifiNetworkSpecifier);
+        assertTrue(reconfig.fromWifiNetworkSuggestion);
+        assertTrue(reconfig.oemPaid);
+        assertTrue(reconfig.oemPrivate);
 
         Parcel parcelWW = Parcel.obtain();
         reconfig.writeToParcel(parcelWW, 0);
@@ -103,6 +106,32 @@
     }
 
     @Test
+    public void testWifiConfigurationCopyConstructor() {
+        WifiConfiguration config = new WifiConfiguration();
+        config.trusted = false;
+        config.oemPaid = true;
+        config.oemPrivate = true;
+        config.updateIdentifier = "1234";
+        config.fromWifiNetworkSpecifier = true;
+        config.fromWifiNetworkSuggestion = true;
+        config.setRandomizedMacAddress(MacAddressUtils.createRandomUnicastAddress());
+        MacAddress macBeforeParcel = config.getRandomizedMacAddress();
+        config.subscriptionId = 1;
+        config.carrierId = 1189;
+
+        WifiConfiguration reconfig = new WifiConfiguration(config);
+
+        // lacking a useful config.equals, check two fields near the end.
+        assertEquals(macBeforeParcel, reconfig.getRandomizedMacAddress());
+        assertEquals(config.updateIdentifier, reconfig.updateIdentifier);
+        assertFalse(reconfig.trusted);
+        assertTrue(reconfig.fromWifiNetworkSpecifier);
+        assertTrue(reconfig.fromWifiNetworkSuggestion);
+        assertTrue(reconfig.oemPaid);
+        assertTrue(reconfig.oemPrivate);
+    }
+
+    @Test
     public void testIsOpenNetwork_IsOpen_NullWepKeys() {
         WifiConfiguration config = new WifiConfiguration();
         config.allowedKeyManagement.clear();
diff --git a/wifi/tests/src/android/net/wifi/WifiInfoTest.java b/wifi/tests/src/android/net/wifi/WifiInfoTest.java
index 06ae13a..c6faf66 100644
--- a/wifi/tests/src/android/net/wifi/WifiInfoTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiInfoTest.java
@@ -17,6 +17,7 @@
 package android.net.wifi;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
@@ -62,6 +63,7 @@
         writeWifiInfo.rxSuccess = TEST_RX_SUCCESS;
         writeWifiInfo.setTrusted(true);
         writeWifiInfo.setOemPaid(true);
+        writeWifiInfo.setOemPrivate(true);
         writeWifiInfo.setOsuAp(true);
         writeWifiInfo.setFQDN(TEST_FQDN);
         writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
@@ -83,6 +85,46 @@
         assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess);
         assertTrue(readWifiInfo.isTrusted());
         assertTrue(readWifiInfo.isOemPaid());
+        assertTrue(readWifiInfo.isOemPrivate());
+        assertTrue(readWifiInfo.isOsuAp());
+        assertTrue(readWifiInfo.isPasspointAp());
+        assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName());
+        assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn());
+        assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName());
+        assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard());
+        assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS,
+                readWifiInfo.getMaxSupportedTxLinkSpeedMbps());
+        assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS,
+                readWifiInfo.getMaxSupportedRxLinkSpeedMbps());
+    }
+
+    @Test
+    public void testWifiInfoCopyConstructor() throws Exception {
+        WifiInfo writeWifiInfo = new WifiInfo();
+        writeWifiInfo.txSuccess = TEST_TX_SUCCESS;
+        writeWifiInfo.txRetries = TEST_TX_RETRIES;
+        writeWifiInfo.txBad = TEST_TX_BAD;
+        writeWifiInfo.rxSuccess = TEST_RX_SUCCESS;
+        writeWifiInfo.setTrusted(true);
+        writeWifiInfo.setOemPaid(true);
+        writeWifiInfo.setOemPrivate(true);
+        writeWifiInfo.setOsuAp(true);
+        writeWifiInfo.setFQDN(TEST_FQDN);
+        writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
+        writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME);
+        writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD);
+        writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
+        writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
+
+        WifiInfo readWifiInfo = new WifiInfo(writeWifiInfo);
+
+        assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess);
+        assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries);
+        assertEquals(TEST_TX_BAD, readWifiInfo.txBad);
+        assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess);
+        assertTrue(readWifiInfo.isTrusted());
+        assertTrue(readWifiInfo.isOemPaid());
+        assertTrue(readWifiInfo.isOemPrivate());
         assertTrue(readWifiInfo.isOsuAp());
         assertTrue(readWifiInfo.isPasspointAp());
         assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName());
@@ -110,6 +152,8 @@
         assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID());
         assertEquals(null, wifiInfo.getBSSID());
         assertEquals(-1, wifiInfo.getNetworkId());
+        assertFalse(wifiInfo.isOemPaid());
+        assertFalse(wifiInfo.isOemPrivate());
     }
 
     /**
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
index 56e7998..870ff0a 100644
--- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -223,6 +223,34 @@
 
     /**
      * Validate correctness of WifiNetworkSuggestion object created by
+     * {@link WifiNetworkSuggestion.Builder#build()} for OWE network.
+     */
+    @Test
+    public void testWifiNetworkSuggestionBuilderForOemPrivateEnhancedOpenNetworkWithBssid() {
+        assumeTrue(SdkLevel.isAtLeastS());
+
+        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+                .setSsid(TEST_SSID)
+                .setBssid(MacAddress.fromString(TEST_BSSID))
+                .setOemPrivate(true)
+                .setIsEnhancedOpen(true)
+                .build();
+
+        assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+        assertEquals(TEST_BSSID, suggestion.wifiConfiguration.BSSID);
+        assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+                .get(WifiConfiguration.KeyMgmt.OWE));
+        assertNull(suggestion.wifiConfiguration.preSharedKey);
+        assertTrue(suggestion.wifiConfiguration.requirePmf);
+        assertTrue(suggestion.wifiConfiguration.oemPrivate);
+        assertTrue(suggestion.isOemPrivate());
+        assertFalse(suggestion.isUserAllowedToManuallyConnect);
+        assertTrue(suggestion.isInitialAutoJoinEnabled);
+        assertNull(suggestion.getEnterpriseConfig());
+    }
+
+    /**
+     * Validate correctness of WifiNetworkSuggestion object created by
      * {@link WifiNetworkSuggestion.Builder#build()} for SAE network.
      */
     @Test
@@ -1285,6 +1313,41 @@
     }
 
     /**
+     * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the
+     * correct value to the WifiConfiguration.
+     */
+    @Test
+    public void testSetIsNetworkAsOemPrivate() {
+        assumeTrue(SdkLevel.isAtLeastS());
+
+        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+                .setSsid(TEST_SSID)
+                .setWpa2Passphrase(TEST_PRESHARED_KEY)
+                .setOemPrivate(true)
+                .build();
+        assertTrue(suggestion.isOemPrivate());
+        assertFalse(suggestion.isUserAllowedToManuallyConnect);
+    }
+
+    /**
+     * Validate {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} set the
+     * correct value to the WifiConfiguration.
+     * Also the {@link WifiNetworkSuggestion#isUserAllowedToManuallyConnect} should be false;
+     */
+    @Test
+    public void testSetIsNetworkAsOemPrivateOnPasspointNetwork() {
+        assumeTrue(SdkLevel.isAtLeastS());
+
+        PasspointConfiguration passpointConfiguration = PasspointTestUtils.createConfig();
+        WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
+                .setPasspointConfig(passpointConfiguration)
+                .setOemPrivate(true)
+                .build();
+        assertTrue(suggestion.isOemPrivate());
+        assertFalse(suggestion.isUserAllowedToManuallyConnect);
+    }
+
+    /**
      * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
      * when set {@link WifiNetworkSuggestion.Builder#setUntrusted(boolean)} to true and
      * set {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to true
@@ -1320,6 +1383,24 @@
 
     /**
      * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
+     * when set {@link WifiNetworkSuggestion.Builder#setOemPrivate(boolean)} to true and
+     * set {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} to true
+     * together.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testSetCredentialSharedWithUserWithSetIsNetworkAsOemPrivate() {
+        assumeTrue(SdkLevel.isAtLeastS());
+
+        new WifiNetworkSuggestion.Builder()
+                .setSsid(TEST_SSID)
+                .setWpa2Passphrase(TEST_PRESHARED_KEY)
+                .setCredentialSharedWithUser(true)
+                .setOemPrivate(true)
+                .build();
+    }
+
+    /**
+     * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception
      * when set both {@link WifiNetworkSuggestion.Builder#setIsInitialAutojoinEnabled(boolean)}
      * and {@link WifiNetworkSuggestion.Builder#setCredentialSharedWithUser(boolean)} (boolean)}
      * to false on a passpoint suggestion.
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index d0d0c57..1ecd325 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -155,6 +155,7 @@
      */
     @Test
     public void testIsAttached() throws Exception {
+        assumeTrue(SdkLevel.isAtLeastS());
         mDut.isDeviceAttached();
         verify(mockAwareService).isDeviceAttached();
     }
@@ -172,6 +173,16 @@
         verify(mockAwareService).enableInstantCommunicationMode(anyString(), eq(true));
     }
 
+    /**
+     * Validate pass-through of getAvailableAwareResources() API.
+     */
+    @Test
+    public void testGetAvailableAwareResource() throws Exception {
+        assumeTrue(SdkLevel.isAtLeastS());
+        mDut.getAvailableAwareResources();
+        verify(mockAwareService).getAvailableAwareResources();
+    }
+
     /*
      * WifiAwareEventCallbackProxy Tests
      */