Merge "MultiUserPerfTest - test restart profile"
diff --git a/Android.bp b/Android.bp
index a6745a9..5b8e6e1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -318,6 +318,7 @@
         "core/java/android/service/vr/IVrListener.aidl",
         "core/java/android/service/vr/IVrManager.aidl",
         "core/java/android/service/vr/IVrStateCallbacks.aidl",
+        "core/java/android/service/watchdog/IExplicitHealthCheckService.aidl",
         "core/java/android/print/ILayoutResultCallback.aidl",
         "core/java/android/print/IPrinterDiscoveryObserver.aidl",
         "core/java/android/print/IPrintDocumentAdapter.aidl",
@@ -374,6 +375,7 @@
         "core/java/android/view/IDisplayFoldListener.aidl",
         "core/java/android/view/IGraphicsStats.aidl",
         "core/java/android/view/IGraphicsStatsCallback.aidl",
+        "core/java/android/view/IInputMonitorHost.aidl",
         "core/java/android/view/IInputFilter.aidl",
         "core/java/android/view/IInputFilterHost.aidl",
         "core/java/android/view/IOnKeyguardExitResult.aidl",
@@ -475,7 +477,10 @@
         "media/java/android/media/IMediaHTTPConnection.aidl",
         "media/java/android/media/IMediaHTTPService.aidl",
         "media/java/android/media/IMediaResourceMonitor.aidl",
+        "media/java/android/media/IMediaRoute2Callback.aidl",
+        "media/java/android/media/IMediaRoute2Provider.aidl",
         "media/java/android/media/IMediaRouterClient.aidl",
+        "media/java/android/media/IMediaRouter2ManagerClient.aidl",
         "media/java/android/media/IMediaRouterService.aidl",
         "media/java/android/media/IMediaScannerListener.aidl",
         "media/java/android/media/IMediaScannerService.aidl",
@@ -717,6 +722,7 @@
             "frameworks/av/camera/aidl",
             "frameworks/av/media/libaudioclient/aidl",
             "frameworks/native/aidl/gui",
+            "frameworks/native/libs/incidentcompanion/binder",
             "system/core/storaged/binder",
             "system/vold/binder",
             "system/gsid/aidl",
@@ -964,7 +970,10 @@
         output_params: ["store_unknown_fields=true"],
         include_dirs: ["external/protobuf/src"],
     },
-
+    exclude_srcs: [
+        "core/proto/android/privacy.proto",
+        "core/proto/android/section.proto",
+    ],
     sdk_version: "current",
     srcs: [
         "core/proto/**/*.proto",
@@ -984,6 +993,10 @@
         "core/proto/**/*.proto",
         "libs/incident/proto/android/os/**/*.proto",
     ],
+    exclude_srcs: [
+        "core/proto/android/privacy.proto",
+        "core/proto/android/section.proto",
+    ],
     // Protos have lots of MissingOverride and similar.
     errorprone: {
         javacflags: ["-XepDisableAllChecks"],
@@ -991,9 +1004,9 @@
 }
 
 // ====  c++ proto device library  ==============================
-cc_library {
-    name: "libplatformprotos",
-    host_supported: true,
+cc_defaults {
+    name: "libplatformprotos-defaults",
+
     proto: {
         export_proto_headers: true,
         include_dirs: ["external/protobuf/src"],
@@ -1007,8 +1020,13 @@
 
     srcs: [
         "core/proto/**/*.proto",
-        "libs/incident/**/*.proto",
     ],
+}
+
+cc_library {
+    name: "libplatformprotos",
+    defaults: ["libplatformprotos-defaults"],
+    host_supported: true,
 
     target: {
         host: {
@@ -1020,6 +1038,9 @@
             proto: {
                 type: "lite",
             },
+            shared_libs: [
+                "libprotobuf-cpp-lite",
+            ],
             shared: {
                 enabled: false,
             },
@@ -1027,6 +1048,26 @@
     },
 }
 
+// This is the full proto version of libplatformprotos. It may only
+// be used by test code that is not shipped on the device.
+cc_library {
+    name: "libplatformprotos-test",
+    defaults: ["libplatformprotos-defaults"],
+    host_supported: false,
+
+    target: {
+        android: {
+            proto: {
+                type: "full",
+            },
+            shared: {
+                enabled: false,
+            },
+        },
+    },
+}
+
+
 gensrcs {
     name: "gen-platform-proto-constants",
     depfile: true,
@@ -1064,6 +1105,7 @@
     output_extension: "proto.h",
 }
 
+
 subdirs = [
     "cmds/*",
     "core/*",
diff --git a/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java b/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java
index 0c30302..da9ed6e 100644
--- a/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java
+++ b/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java
@@ -40,14 +40,14 @@
     public final PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
 
     private final KernelCpuThreadReader mKernelCpuThreadReader =
-            KernelCpuThreadReader.create(8, uid -> 1000 <= uid && uid < 2000, 0);
+            KernelCpuThreadReader.create(8, uid -> 1000 <= uid && uid < 2000);
 
     @Test
     public void timeReadCurrentProcessCpuUsage() {
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         assertNotNull(mKernelCpuThreadReader);
         while (state.keepRunning()) {
-            this.mKernelCpuThreadReader.getCurrentProcessCpuUsage();
+            this.mKernelCpuThreadReader.getProcessCpuUsage();
         }
     }
 }
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 10b07ec..c121bd9 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -27,6 +27,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.LargeTest;
@@ -130,6 +131,47 @@
         }
     }
 
+    /** Tests switching to an already-created, but no-longer-running, user. */
+    @Test
+    public void switchUser_stopped() throws Exception {
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int startUser = mAm.getCurrentUser();
+            final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ true);
+            final CountDownLatch latch = new CountDownLatch(1);
+            registerBroadcastReceiver(Intent.ACTION_USER_UNLOCKED, latch, testUser);
+            mRunner.resumeTiming();
+
+            mAm.switchUser(testUser);
+            boolean success = latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
+
+            mRunner.pauseTiming();
+            attestTrue("Failed to achieve 2nd ACTION_USER_UNLOCKED for user " + testUser, success);
+            switchUser(startUser);
+            removeUser(testUser);
+            mRunner.resumeTiming();
+        }
+    }
+
+    /** Tests switching to an already-created already-running non-owner user. */
+    @Test
+    public void switchUser_running() throws Exception {
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int startUser = mAm.getCurrentUser();
+            final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false);
+            mRunner.resumeTiming();
+
+            switchUser(testUser);
+
+            mRunner.pauseTiming();
+            attestTrue("Failed to switch to user " + testUser, mAm.isUserRunning(testUser));
+            switchUser(startUser);
+            removeUser(testUser);
+            mRunner.resumeTiming();
+        }
+    }
+
     @Test
     public void stopUser() throws Exception {
         while (mRunner.keepRunning()) {
@@ -290,6 +332,35 @@
         latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
     }
 
+    /**
+     * Creates a user and waits for its ACTION_USER_UNLOCKED.
+     * Then switches to back to the original user and waits for its switchUser() to finish.
+     *
+     * @param stopNewUser whether to stop the new user after switching to otherUser.
+     * @return userId of the newly created user.
+     */
+    private int initializeNewUserAndSwitchBack(boolean stopNewUser) throws Exception {
+        final int origUser = mAm.getCurrentUser();
+        // First, create and switch to testUser, waiting for its ACTION_USER_UNLOCKED
+        final int testUser = mUm.createUser("TestUser", 0).id;
+        final CountDownLatch latch1 = new CountDownLatch(1);
+        registerBroadcastReceiver(Intent.ACTION_USER_UNLOCKED, latch1, testUser);
+        mAm.switchUser(testUser);
+        attestTrue("Failed to achieve initial ACTION_USER_UNLOCKED for user " + testUser,
+                latch1.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS));
+
+        // Second, switch back to origUser, waiting merely for switchUser() to finish
+        switchUser(origUser);
+        attestTrue("Didn't switch back to user, " + origUser, origUser == mAm.getCurrentUser());
+
+        if (stopNewUser) {
+            stopUser(testUser, true);
+            attestFalse("Failed to stop user " + testUser, mAm.isUserRunning(testUser));
+        }
+
+        return testUser;
+    }
+
     private void registerUserSwitchObserver(final CountDownLatch switchLatch,
             final CountDownLatch bootCompleteLatch, final int userId) throws Exception {
         ActivityManager.getService().registerUserSwitchObserver(
@@ -341,4 +412,14 @@
             mUsersToRemove.add(userId);
         }
     }
+
+    private void attestTrue(String message, boolean attestion) {
+        if (!attestion) {
+            Log.w(TAG, message);
+        }
+    }
+
+    private void attestFalse(String message, boolean attestion) {
+        attestTrue(message, !attestion);
+    }
 }
diff --git a/packages/NetworkStackPermissionStub/Android.bp b/apct-tests/perftests/textclassifier/Android.bp
similarity index 65%
copy from packages/NetworkStackPermissionStub/Android.bp
copy to apct-tests/perftests/textclassifier/Android.bp
index 8cee92e..49952dc 100644
--- a/packages/NetworkStackPermissionStub/Android.bp
+++ b/apct-tests/perftests/textclassifier/Android.bp
@@ -1,4 +1,3 @@
-//
 // Copyright (C) 2019 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,17 +11,15 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-//
 
-// Stub APK to define permissions for NetworkStack
-android_app {
-    name: "NetworkStackPermissionStub",
-    // TODO: mark app as hasCode=false in manifest once soong stops complaining about apps without
-    // a classes.dex.
+android_test {
+    name: "TextClassifierPerfTests",
     srcs: ["src/**/*.java"],
+    static_libs: [
+        "androidx.test.rules",
+        "androidx.annotation_annotation",
+        "apct-perftests-utils",
+    ],
     platform_apis: true,
-    min_sdk_version: "28",
-    certificate: "networkstack",
-    privileged: true,
-    manifest: "AndroidManifest.xml",
+    test_suites: ["device-tests"],
 }
diff --git a/apct-tests/perftests/textclassifier/AndroidManifest.xml b/apct-tests/perftests/textclassifier/AndroidManifest.xml
new file mode 100644
index 0000000..7cf487f
--- /dev/null
+++ b/apct-tests/perftests/textclassifier/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.perftests.textclassifier">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.perftests.textclassifier"/>
+</manifest>
diff --git a/apct-tests/perftests/textclassifier/AndroidTest.xml b/apct-tests/perftests/textclassifier/AndroidTest.xml
new file mode 100644
index 0000000..3df51b8
--- /dev/null
+++ b/apct-tests/perftests/textclassifier/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs TextClassifierPerfTests metric instrumentation.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-metric-instrumentation" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="TextClassifierPerfTests.apk" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.perftests.textclassifier" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/apct-tests/perftests/textclassifier/run.sh b/apct-tests/perftests/textclassifier/run.sh
new file mode 100755
index 0000000..c6782d1
--- /dev/null
+++ b/apct-tests/perftests/textclassifier/run.sh
@@ -0,0 +1,4 @@
+set -e
+make TextClassifierPerfTests
+adb shell cmd package compile -m speed -f com.android.perftests.textclassifier
+adb shell am instrument -w -e class android.view.textclassifier.TextClassifierPerfTest com.android.perftests.textclassifier/androidx.test.runner.AndroidJUnitRunner
diff --git a/apct-tests/perftests/core/src/android/textclassifier/TextClassifierPerfTest.java b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassifierPerfTest.java
similarity index 93%
rename from apct-tests/perftests/core/src/android/textclassifier/TextClassifierPerfTest.java
rename to apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassifierPerfTest.java
index c5d89b2..14a121d 100644
--- a/apct-tests/perftests/core/src/android/textclassifier/TextClassifierPerfTest.java
+++ b/apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassifierPerfTest.java
@@ -13,15 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.textclassifier;
+package android.view.textclassifier;
 
 import android.content.Context;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.TextClassificationManager;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextLanguage;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.LargeTest;
diff --git a/api/current.txt b/api/current.txt
index 8192762..d4a1554 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -102,16 +102,13 @@
     field public static final String NFC_TRANSACTION_EVENT = "android.permission.NFC_TRANSACTION_EVENT";
     field public static final String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
     field @Deprecated public static final String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
-    field public static final String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
+    field @Deprecated public static final String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
     field public static final String READ_CALENDAR = "android.permission.READ_CALENDAR";
     field public static final String READ_CALL_LOG = "android.permission.READ_CALL_LOG";
     field public static final String READ_CONTACTS = "android.permission.READ_CONTACTS";
-    field @Deprecated public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
+    field public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
     field @Deprecated public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
     field public static final String READ_LOGS = "android.permission.READ_LOGS";
-    field public static final String READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO";
-    field public static final String READ_MEDIA_IMAGES = "android.permission.READ_MEDIA_IMAGES";
-    field public static final String READ_MEDIA_VIDEO = "android.permission.READ_MEDIA_VIDEO";
     field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
     field public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
     field public static final String READ_SMS = "android.permission.READ_SMS";
@@ -161,7 +158,7 @@
     field public static final String WRITE_CALENDAR = "android.permission.WRITE_CALENDAR";
     field public static final String WRITE_CALL_LOG = "android.permission.WRITE_CALL_LOG";
     field public static final String WRITE_CONTACTS = "android.permission.WRITE_CONTACTS";
-    field @Deprecated public static final String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
+    field public static final String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
     field public static final String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";
     field public static final String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
     field public static final String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";
@@ -177,13 +174,11 @@
     field public static final String CAMERA = "android.permission-group.CAMERA";
     field public static final String CONTACTS = "android.permission-group.CONTACTS";
     field public static final String LOCATION = "android.permission-group.LOCATION";
-    field public static final String MEDIA_AURAL = "android.permission-group.MEDIA_AURAL";
-    field public static final String MEDIA_VISUAL = "android.permission-group.MEDIA_VISUAL";
     field public static final String MICROPHONE = "android.permission-group.MICROPHONE";
     field public static final String PHONE = "android.permission-group.PHONE";
     field public static final String SENSORS = "android.permission-group.SENSORS";
     field public static final String SMS = "android.permission-group.SMS";
-    field @Deprecated public static final String STORAGE = "android.permission-group.STORAGE";
+    field public static final String STORAGE = "android.permission-group.STORAGE";
   }
 
   public final class R {
@@ -291,6 +286,7 @@
     field public static final int allowBackup = 16843392; // 0x1010280
     field public static final int allowClearUserData = 16842757; // 0x1010005
     field public static final int allowEmbedded = 16843765; // 0x10103f5
+    field public static final int allowExternalStorageSandbox = 16844201; // 0x10105a9
     field public static final int allowParallelSyncs = 16843570; // 0x1010332
     field public static final int allowSingleTap = 16843353; // 0x1010259
     field public static final int allowTaskReparenting = 16843268; // 0x1010204
@@ -5480,7 +5476,7 @@
     method public int describeContents();
     method public boolean getAutoExpandBubble();
     method @Nullable public android.app.PendingIntent getDeleteIntent();
-    method public int getDesiredHeight();
+    method @Dimension(unit=android.annotation.Dimension.DP) public int getDesiredHeight();
     method @DimenRes public int getDesiredHeightResId();
     method @NonNull public android.graphics.drawable.Icon getIcon();
     method @NonNull public android.app.PendingIntent getIntent();
@@ -5494,7 +5490,7 @@
     method @NonNull public android.app.Notification.BubbleMetadata build();
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean);
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(@Nullable android.app.PendingIntent);
-    method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int);
+    method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(@Dimension(unit=android.annotation.Dimension.DP) int);
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setIcon(@NonNull android.graphics.drawable.Icon);
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setIntent(@NonNull android.app.PendingIntent);
@@ -6273,7 +6269,7 @@
 
   public final class UiAutomation {
     method public void adoptShellPermissionIdentity();
-    method public void adoptShellPermissionIdentity(java.lang.String...);
+    method public void adoptShellPermissionIdentity(@Nullable java.lang.String...);
     method public void clearWindowAnimationFrameStats();
     method public boolean clearWindowContentFrameStats(int);
     method public void dropShellPermissionIdentity();
@@ -6963,7 +6959,7 @@
 
   public abstract static class DevicePolicyManager.InstallSystemUpdateCallback {
     ctor public DevicePolicyManager.InstallSystemUpdateCallback();
-    method public void onInstallUpdateError(int, String);
+    method public void onInstallUpdateError(int, @NonNull String);
     field public static final int UPDATE_ERROR_BATTERY_LOW = 5; // 0x5
     field public static final int UPDATE_ERROR_FILE_NOT_FOUND = 4; // 0x4
     field public static final int UPDATE_ERROR_INCORRECT_OS_VERSION = 2; // 0x2
@@ -8604,7 +8600,6 @@
   }
 
   @Deprecated public final class BluetoothHealth implements android.bluetooth.BluetoothProfile {
-    ctor @Deprecated public BluetoothHealth();
     method @Deprecated public boolean connectChannelToSource(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration);
     method @Deprecated public boolean disconnectChannel(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration, int);
     method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
@@ -8628,7 +8623,6 @@
   }
 
   @Deprecated public final class BluetoothHealthAppConfiguration implements android.os.Parcelable {
-    ctor @Deprecated public BluetoothHealthAppConfiguration();
     method @Deprecated public int describeContents();
     method @Deprecated public int getDataType();
     method @Deprecated public String getName();
@@ -11251,7 +11245,6 @@
   public class LauncherApps {
     method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(String, android.os.UserHandle);
     method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllPackageInstallerSessions();
-    method @Nullable public android.content.pm.LauncherApps.AppUsageLimit getAppUsageLimit(@NonNull String, @NonNull android.os.UserHandle);
     method public android.content.pm.ApplicationInfo getApplicationInfo(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
     method public java.util.List<android.os.UserHandle> getProfiles();
@@ -11282,14 +11275,6 @@
     field public static final String EXTRA_PIN_ITEM_REQUEST = "android.content.pm.extra.PIN_ITEM_REQUEST";
   }
 
-  public static final class LauncherApps.AppUsageLimit implements android.os.Parcelable {
-    method public int describeContents();
-    method public long getTotalUsageLimit();
-    method public long getUsageRemaining();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.AppUsageLimit> CREATOR;
-  }
-
   public abstract static class LauncherApps.Callback {
     ctor public LauncherApps.Callback();
     method public abstract void onPackageAdded(String, android.os.UserHandle);
@@ -11384,6 +11369,7 @@
   public class PackageInstaller {
     method public void abandonSession(int);
     method public int createSession(@NonNull android.content.pm.PackageInstaller.SessionParams) throws java.io.IOException;
+    method @Nullable public android.content.pm.PackageInstaller.SessionInfo getActiveStagedSession();
     method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllSessions();
     method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getMySessions();
     method @Nullable public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int);
@@ -11452,7 +11438,7 @@
     method @Nullable public android.graphics.Bitmap getAppIcon();
     method @Nullable public CharSequence getAppLabel();
     method @Nullable public String getAppPackageName();
-    method public int[] getChildSessionIds();
+    method @NonNull public int[] getChildSessionIds();
     method public int getInstallLocation();
     method public int getInstallReason();
     method @Nullable public String getInstallerPackageName();
@@ -11468,6 +11454,7 @@
     method @NonNull public String getStagedSessionErrorMessage();
     method @NonNull public android.os.UserHandle getUser();
     method public boolean isActive();
+    method public boolean isCommitted();
     method public boolean isMultiPackage();
     method public boolean isSealed();
     method public boolean isStaged();
@@ -11532,107 +11519,107 @@
 
   public abstract class PackageManager {
     ctor public PackageManager();
-    method @Deprecated public abstract void addPackageToPreferred(String);
-    method public abstract boolean addPermission(android.content.pm.PermissionInfo);
-    method public abstract boolean addPermissionAsync(android.content.pm.PermissionInfo);
-    method @Deprecated public abstract void addPreferredActivity(android.content.IntentFilter, int, android.content.ComponentName[], android.content.ComponentName);
+    method @Deprecated public abstract void addPackageToPreferred(@NonNull String);
+    method public abstract boolean addPermission(@NonNull android.content.pm.PermissionInfo);
+    method public abstract boolean addPermissionAsync(@NonNull android.content.pm.PermissionInfo);
+    method @Deprecated public abstract void addPreferredActivity(@NonNull android.content.IntentFilter, int, @Nullable android.content.ComponentName[], @NonNull android.content.ComponentName);
     method public abstract boolean canRequestPackageInstalls();
-    method public abstract String[] canonicalToCurrentPackageNames(String[]);
-    method @CheckResult public abstract int checkPermission(String, String);
-    method @CheckResult public abstract int checkSignatures(String, String);
+    method public abstract String[] canonicalToCurrentPackageNames(@NonNull String[]);
+    method @CheckResult public abstract int checkPermission(@NonNull String, @NonNull String);
+    method @CheckResult public abstract int checkSignatures(@NonNull String, @NonNull String);
     method @CheckResult public abstract int checkSignatures(int, int);
     method public abstract void clearInstantAppCookie();
-    method @Deprecated public abstract void clearPackagePreferredActivities(String);
-    method public abstract String[] currentToCanonicalPackageNames(String[]);
+    method @Deprecated public abstract void clearPackagePreferredActivities(@NonNull String);
+    method public abstract String[] currentToCanonicalPackageNames(@NonNull String[]);
     method public abstract void extendVerificationTimeout(int, int, long);
-    method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int);
-    method public abstract android.graphics.drawable.Drawable getApplicationBanner(android.content.pm.ApplicationInfo);
-    method public abstract android.graphics.drawable.Drawable getApplicationBanner(String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Nullable public abstract android.graphics.drawable.Drawable getActivityBanner(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Nullable public abstract android.graphics.drawable.Drawable getActivityBanner(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.graphics.drawable.Drawable getActivityIcon(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.graphics.drawable.Drawable getActivityIcon(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.content.pm.ActivityInfo getActivityInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Nullable public abstract android.graphics.drawable.Drawable getActivityLogo(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Nullable public abstract android.graphics.drawable.Drawable getActivityLogo(@NonNull android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int);
+    method @Nullable public abstract android.graphics.drawable.Drawable getApplicationBanner(@NonNull android.content.pm.ApplicationInfo);
+    method @Nullable public abstract android.graphics.drawable.Drawable getApplicationBanner(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract int getApplicationEnabledSetting(@NonNull String);
-    method public abstract android.graphics.drawable.Drawable getApplicationIcon(android.content.pm.ApplicationInfo);
-    method public abstract android.graphics.drawable.Drawable getApplicationIcon(String) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.pm.ApplicationInfo getApplicationInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract CharSequence getApplicationLabel(android.content.pm.ApplicationInfo);
-    method public abstract android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo);
-    method public abstract android.graphics.drawable.Drawable getApplicationLogo(String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.graphics.drawable.Drawable getApplicationIcon(@NonNull android.content.pm.ApplicationInfo);
+    method @NonNull public abstract android.graphics.drawable.Drawable getApplicationIcon(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.content.pm.ApplicationInfo getApplicationInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract CharSequence getApplicationLabel(@NonNull android.content.pm.ApplicationInfo);
+    method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull android.content.pm.ApplicationInfo);
+    method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
     method @Nullable public abstract android.content.pm.ChangedPackages getChangedPackages(@IntRange(from=0) int);
     method public abstract int getComponentEnabledSetting(@NonNull android.content.ComponentName);
-    method public abstract android.graphics.drawable.Drawable getDefaultActivityIcon();
-    method public abstract android.graphics.drawable.Drawable getDrawable(String, @DrawableRes int, android.content.pm.ApplicationInfo);
-    method public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
+    method @NonNull public abstract android.graphics.drawable.Drawable getDefaultActivityIcon();
+    method @Nullable public abstract android.graphics.drawable.Drawable getDrawable(@NonNull String, @DrawableRes int, @Nullable android.content.pm.ApplicationInfo);
+    method @NonNull public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
     method @NonNull public java.util.List<android.content.pm.ModuleInfo> getInstalledModules(int);
-    method public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
-    method @Nullable public abstract String getInstallerPackageName(String);
+    method @NonNull public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
+    method @Nullable public abstract String getInstallerPackageName(@NonNull String);
     method @NonNull public abstract byte[] getInstantAppCookie();
     method public abstract int getInstantAppCookieMaxBytes();
-    method public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.content.pm.InstrumentationInfo getInstrumentationInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method @Nullable public abstract android.content.Intent getLaunchIntentForPackage(@NonNull String);
     method @Nullable public abstract android.content.Intent getLeanbackLaunchIntentForPackage(@NonNull String);
-    method public android.content.pm.ModuleInfo getModuleInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public android.content.pm.ModuleInfo getModuleInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method @Nullable public abstract String getNameForUid(int);
-    method public android.content.pm.PackageInfo getPackageArchiveInfo(String, int);
+    method @Nullable public android.content.pm.PackageInfo getPackageArchiveInfo(@NonNull String, int);
     method public abstract int[] getPackageGids(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract int[] getPackageGids(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.pm.PackageInfo getPackageInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public abstract int[] getPackageGids(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public abstract android.content.pm.PackageInfo getPackageInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public abstract android.content.pm.PackageInfo getPackageInfo(@NonNull android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method @NonNull public abstract android.content.pm.PackageInstaller getPackageInstaller();
-    method public abstract int getPackageUid(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public abstract int getPackageUid(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method @Nullable public abstract String[] getPackagesForUid(int);
-    method public abstract java.util.List<android.content.pm.PackageInfo> getPackagesHoldingPermissions(String[], int);
-    method public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.pm.PermissionInfo getPermissionInfo(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @Deprecated public abstract int getPreferredActivities(@NonNull java.util.List<android.content.IntentFilter>, @NonNull java.util.List<android.content.ComponentName>, String);
-    method @Deprecated public abstract java.util.List<android.content.pm.PackageInfo> getPreferredPackages(int);
-    method public abstract android.content.pm.ProviderInfo getProviderInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.pm.ActivityInfo getReceiverInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.res.Resources getResourcesForActivity(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.res.Resources getResourcesForApplication(String) throws android.content.pm.PackageManager.NameNotFoundException;
-    method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract java.util.List<android.content.pm.PackageInfo> getPackagesHoldingPermissions(@NonNull String[], int);
+    method @NonNull public abstract android.content.pm.PermissionGroupInfo getPermissionGroupInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public abstract android.content.pm.PermissionInfo getPermissionInfo(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Deprecated public abstract int getPreferredActivities(@NonNull java.util.List<android.content.IntentFilter>, @NonNull java.util.List<android.content.ComponentName>, @Nullable String);
+    method @Deprecated @NonNull public abstract java.util.List<android.content.pm.PackageInfo> getPreferredPackages(int);
+    method @NonNull public abstract android.content.pm.ProviderInfo getProviderInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.content.pm.ActivityInfo getReceiverInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.content.res.Resources getResourcesForActivity(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.content.res.Resources getResourcesForApplication(@NonNull android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.content.res.Resources getResourcesForApplication(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull public abstract android.content.pm.ServiceInfo getServiceInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method @NonNull public abstract java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int);
     method @Nullable public android.os.Bundle getSuspendedPackageAppExtras();
     method public boolean getSyntheticAppDetailsActivityEnabled(@NonNull String);
-    method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
-    method public abstract String[] getSystemSharedLibraryNames();
-    method public abstract CharSequence getText(String, @StringRes int, android.content.pm.ApplicationInfo);
-    method public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(android.graphics.drawable.Drawable, android.os.UserHandle, android.graphics.Rect, int);
-    method public abstract android.graphics.drawable.Drawable getUserBadgedIcon(android.graphics.drawable.Drawable, android.os.UserHandle);
-    method public abstract CharSequence getUserBadgedLabel(CharSequence, android.os.UserHandle);
-    method public abstract android.content.res.XmlResourceParser getXml(String, @XmlRes int, android.content.pm.ApplicationInfo);
-    method public boolean hasSigningCertificate(String, byte[], int);
-    method public boolean hasSigningCertificate(int, byte[], int);
-    method public abstract boolean hasSystemFeature(String);
-    method public abstract boolean hasSystemFeature(String, int);
+    method @NonNull public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
+    method @Nullable public abstract String[] getSystemSharedLibraryNames();
+    method @Nullable public abstract CharSequence getText(@NonNull String, @StringRes int, @Nullable android.content.pm.ApplicationInfo);
+    method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int);
+    method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle);
+    method @NonNull public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence, @NonNull android.os.UserHandle);
+    method @Nullable public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo);
+    method public boolean hasSigningCertificate(@NonNull String, @NonNull byte[], int);
+    method public boolean hasSigningCertificate(int, @NonNull byte[], int);
+    method public abstract boolean hasSystemFeature(@NonNull String);
+    method public abstract boolean hasSystemFeature(@NonNull String, int);
     method public abstract boolean isInstantApp();
-    method public abstract boolean isInstantApp(String);
-    method public boolean isPackageSuspended(String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public abstract boolean isInstantApp(@NonNull String);
+    method public boolean isPackageSuspended(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
     method public boolean isPackageSuspended();
     method @CheckResult public abstract boolean isPermissionRevokedByPolicy(@NonNull String, @NonNull String);
     method public abstract boolean isSafeMode();
-    method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
-    method public abstract java.util.List<android.content.pm.ProviderInfo> queryContentProviders(String, int, int);
-    method public abstract java.util.List<android.content.pm.InstrumentationInfo> queryInstrumentation(String, int);
-    method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivities(android.content.Intent, int);
-    method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivityOptions(@Nullable android.content.ComponentName, @Nullable android.content.Intent[], android.content.Intent, int);
-    method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentContentProviders(android.content.Intent, int);
-    method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentServices(android.content.Intent, int);
-    method public abstract java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @Deprecated public abstract void removePackageFromPreferred(String);
-    method public abstract void removePermission(String);
-    method public abstract android.content.pm.ResolveInfo resolveActivity(android.content.Intent, int);
-    method public abstract android.content.pm.ProviderInfo resolveContentProvider(String, int);
-    method public abstract android.content.pm.ResolveInfo resolveService(android.content.Intent, int);
+    method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(@NonNull android.content.Intent, int);
+    method @NonNull public abstract java.util.List<android.content.pm.ProviderInfo> queryContentProviders(@Nullable String, int, int);
+    method @NonNull public abstract java.util.List<android.content.pm.InstrumentationInfo> queryInstrumentation(@NonNull String, int);
+    method @Nullable public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivities(@NonNull android.content.Intent, int);
+    method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentActivityOptions(@Nullable android.content.ComponentName, @Nullable android.content.Intent[], @NonNull android.content.Intent, int);
+    method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentContentProviders(@NonNull android.content.Intent, int);
+    method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentServices(@NonNull android.content.Intent, int);
+    method @NonNull public abstract java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Deprecated public abstract void removePackageFromPreferred(@NonNull String);
+    method public abstract void removePermission(@NonNull String);
+    method @Nullable public abstract android.content.pm.ResolveInfo resolveActivity(@NonNull android.content.Intent, int);
+    method @Nullable public abstract android.content.pm.ProviderInfo resolveContentProvider(@NonNull String, int);
+    method @Nullable public abstract android.content.pm.ResolveInfo resolveService(@NonNull android.content.Intent, int);
     method public abstract void setApplicationCategoryHint(@NonNull String, int);
     method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public abstract void setApplicationEnabledSetting(@NonNull String, int, int);
     method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public abstract void setComponentEnabledSetting(@NonNull android.content.ComponentName, int, int);
-    method public abstract void setInstallerPackageName(String, String);
+    method public abstract void setInstallerPackageName(@NonNull String, @Nullable String);
     method public abstract void updateInstantAppCookie(@Nullable byte[]);
     method public abstract void verifyPendingInstall(int, int);
     field public static final int CERT_INPUT_RAW_X509 = 0; // 0x0
@@ -13087,10 +13074,10 @@
     method @Deprecated public String buildUnionSubQuery(String, String[], java.util.Set<java.lang.String>, int, String, String, String[], String, String);
     method public int delete(@NonNull android.database.sqlite.SQLiteDatabase, @Nullable String, @Nullable String[]);
     method @Nullable public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
-    method public boolean getDistinct();
     method @Nullable public java.util.Map<java.lang.String,java.lang.String> getProjectionMap();
-    method public boolean getStrict();
     method @Nullable public String getTables();
+    method public boolean isDistinct();
+    method public boolean isStrict();
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String);
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String, String);
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String, String, android.os.CancellationSignal);
@@ -14098,8 +14085,9 @@
   }
 
   public class ComposeShader extends android.graphics.Shader {
-    ctor public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.Xfermode);
-    ctor public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.PorterDuff.Mode);
+    ctor @Deprecated public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.Xfermode);
+    ctor @Deprecated public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.PorterDuff.Mode);
+    ctor public ComposeShader(@NonNull android.graphics.Shader, @NonNull android.graphics.Shader, @NonNull android.graphics.BlendMode);
   }
 
   public class CornerPathEffect extends android.graphics.PathEffect {
@@ -14793,37 +14781,37 @@
     field public float y;
   }
 
-  public class PorterDuff {
-    ctor public PorterDuff();
+  @Deprecated public class PorterDuff {
+    ctor @Deprecated public PorterDuff();
   }
 
-  public enum PorterDuff.Mode {
-    enum_constant public static final android.graphics.PorterDuff.Mode ADD;
-    enum_constant public static final android.graphics.PorterDuff.Mode CLEAR;
-    enum_constant public static final android.graphics.PorterDuff.Mode DARKEN;
-    enum_constant public static final android.graphics.PorterDuff.Mode DST;
-    enum_constant public static final android.graphics.PorterDuff.Mode DST_ATOP;
-    enum_constant public static final android.graphics.PorterDuff.Mode DST_IN;
-    enum_constant public static final android.graphics.PorterDuff.Mode DST_OUT;
-    enum_constant public static final android.graphics.PorterDuff.Mode DST_OVER;
-    enum_constant public static final android.graphics.PorterDuff.Mode LIGHTEN;
-    enum_constant public static final android.graphics.PorterDuff.Mode MULTIPLY;
-    enum_constant public static final android.graphics.PorterDuff.Mode OVERLAY;
-    enum_constant public static final android.graphics.PorterDuff.Mode SCREEN;
-    enum_constant public static final android.graphics.PorterDuff.Mode SRC;
-    enum_constant public static final android.graphics.PorterDuff.Mode SRC_ATOP;
-    enum_constant public static final android.graphics.PorterDuff.Mode SRC_IN;
-    enum_constant public static final android.graphics.PorterDuff.Mode SRC_OUT;
-    enum_constant public static final android.graphics.PorterDuff.Mode SRC_OVER;
-    enum_constant public static final android.graphics.PorterDuff.Mode XOR;
+  @Deprecated public enum PorterDuff.Mode {
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode ADD;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode CLEAR;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DARKEN;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST_ATOP;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST_IN;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST_OUT;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode DST_OVER;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode LIGHTEN;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode MULTIPLY;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode OVERLAY;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SCREEN;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC_ATOP;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC_IN;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC_OUT;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode SRC_OVER;
+    enum_constant @Deprecated public static final android.graphics.PorterDuff.Mode XOR;
   }
 
   @Deprecated public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor @Deprecated public PorterDuffColorFilter(@ColorInt int, @NonNull android.graphics.PorterDuff.Mode);
   }
 
-  public class PorterDuffXfermode extends android.graphics.Xfermode {
-    ctor public PorterDuffXfermode(android.graphics.PorterDuff.Mode);
+  @Deprecated public class PorterDuffXfermode extends android.graphics.Xfermode {
+    ctor @Deprecated public PorterDuffXfermode(android.graphics.PorterDuff.Mode);
   }
 
   public interface PostProcessor {
@@ -15385,7 +15373,8 @@
     method public boolean setState(@NonNull int[]);
     method public void setTint(@ColorInt int);
     method public void setTintList(@Nullable android.content.res.ColorStateList);
-    method public void setTintMode(@NonNull android.graphics.PorterDuff.Mode);
+    method @Deprecated public void setTintMode(@Nullable android.graphics.PorterDuff.Mode);
+    method public void setTintMode(@Nullable android.graphics.BlendMode);
     method public boolean setVisible(boolean, boolean);
     method public void unscheduleSelf(@NonNull Runnable);
   }
@@ -15543,7 +15532,8 @@
     method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler);
     method public android.graphics.drawable.Icon setTint(@ColorInt int);
     method public android.graphics.drawable.Icon setTintList(android.content.res.ColorStateList);
-    method public android.graphics.drawable.Icon setTintMode(android.graphics.PorterDuff.Mode);
+    method @Deprecated @NonNull public android.graphics.drawable.Icon setTintMode(@NonNull android.graphics.PorterDuff.Mode);
+    method @NonNull public android.graphics.drawable.Icon setTintMode(@NonNull android.graphics.BlendMode);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR;
     field public static final int TYPE_ADAPTIVE_BITMAP = 5; // 0x5
@@ -17052,6 +17042,7 @@
 
   public class CaptureFailure {
     method public long getFrameNumber();
+    method @Nullable public String getPhysicalCameraId();
     method public int getReason();
     method @NonNull public android.hardware.camera2.CaptureRequest getRequest();
     method public int getSequenceId();
@@ -23039,6 +23030,9 @@
     method public int getUsage();
     method public int getVolumeControlStream();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final int ALLOW_CAPTURE_BY_ALL = 1; // 0x1
+    field public static final int ALLOW_CAPTURE_BY_NONE = 3; // 0x3
+    field public static final int ALLOW_CAPTURE_BY_SYSTEM = 2; // 0x2
     field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
     field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
     field public static final int CONTENT_TYPE_SONIFICATION = 4; // 0x4
@@ -23070,7 +23064,7 @@
     ctor public AudioAttributes.Builder();
     ctor public AudioAttributes.Builder(android.media.AudioAttributes);
     method public android.media.AudioAttributes build();
-    method @NonNull public android.media.AudioAttributes.Builder setAllowCapture(boolean);
+    method @NonNull public android.media.AudioAttributes.Builder setAllowedCapturePolicy(int);
     method public android.media.AudioAttributes.Builder setContentType(int);
     method public android.media.AudioAttributes.Builder setFlags(int);
     method public android.media.AudioAttributes.Builder setLegacyStreamType(int);
@@ -23271,6 +23265,7 @@
     method @Deprecated public boolean registerRemoteController(android.media.RemoteController);
     method @Deprecated public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
     method public int requestAudioFocus(@NonNull android.media.AudioFocusRequest);
+    method public void setAllowedCapturePolicy(int);
     method @Deprecated public void setBluetoothA2dpOn(boolean);
     method public void setBluetoothScoOn(boolean);
     method public void setMicrophoneMute(boolean);
@@ -25067,7 +25062,7 @@
     field public static final String KEY_LANGUAGE = "language";
     field public static final String KEY_LATENCY = "latency";
     field public static final String KEY_LEVEL = "level";
-    field public static final String KEY_MAX_BFRAMES = "max-bframes";
+    field public static final String KEY_MAX_B_FRAMES = "max-bframes";
     field public static final String KEY_MAX_FPS_TO_ENCODER = "max-fps-to-encoder";
     field public static final String KEY_MAX_HEIGHT = "max-height";
     field public static final String KEY_MAX_INPUT_SIZE = "max-input-size";
@@ -28710,12 +28705,12 @@
 
   public static class ConnectivityManager.NetworkCallback {
     ctor public ConnectivityManager.NetworkCallback();
-    method public void onAvailable(android.net.Network);
+    method public void onAvailable(@NonNull android.net.Network);
     method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
-    method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities);
-    method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
-    method public void onLosing(android.net.Network, int);
-    method public void onLost(android.net.Network);
+    method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities);
+    method public void onLinkPropertiesChanged(@NonNull android.net.Network, @NonNull android.net.LinkProperties);
+    method public void onLosing(@NonNull android.net.Network, int);
+    method public void onLost(@NonNull android.net.Network);
     method public void onUnavailable();
   }
 
@@ -28747,6 +28742,7 @@
     method @NonNull public static android.net.DnsResolver getInstance();
     method public <T> void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>);
     method public <T> void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback<T>);
+    method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.InetAddressAnswerCallback);
     field public static final int CLASS_IN = 1; // 0x1
     field public static final int FLAG_EMPTY = 0; // 0x0
     field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4
@@ -28781,11 +28777,11 @@
   }
 
   public final class IpPrefix implements android.os.Parcelable {
-    method public boolean contains(java.net.InetAddress);
+    method public boolean contains(@NonNull java.net.InetAddress);
     method public int describeContents();
-    method public java.net.InetAddress getAddress();
-    method public int getPrefixLength();
-    method public byte[] getRawAddress();
+    method @NonNull public java.net.InetAddress getAddress();
+    method @IntRange(from=0, to=128) public int getPrefixLength();
+    method @NonNull public byte[] getRawAddress();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
@@ -28858,7 +28854,7 @@
     method public int describeContents();
     method public java.net.InetAddress getAddress();
     method public int getFlags();
-    method public int getPrefixLength();
+    method @IntRange(from=0, to=128) public int getPrefixLength();
     method public int getScope();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkAddress> CREATOR;
@@ -29128,9 +29124,9 @@
 
   public final class RouteInfo implements android.os.Parcelable {
     method public int describeContents();
-    method public android.net.IpPrefix getDestination();
-    method public java.net.InetAddress getGateway();
-    method public String getInterface();
+    method @NonNull public android.net.IpPrefix getDestination();
+    method @Nullable public java.net.InetAddress getGateway();
+    method @Nullable public String getInterface();
     method public boolean hasGateway();
     method public boolean isDefaultRoute();
     method public boolean matches(java.net.InetAddress);
@@ -29265,7 +29261,6 @@
     method public abstract boolean isRelative();
     method public android.net.Uri normalizeScheme();
     method public static android.net.Uri parse(String);
-    method @NonNull public String toSafeString();
     method public abstract String toString();
     method public static android.net.Uri withAppendedPath(android.net.Uri, String);
     method public static void writeToParcel(android.os.Parcel, android.net.Uri);
@@ -34280,6 +34275,7 @@
     ctor public Binder(@Nullable String);
     method public void attachInterface(@Nullable android.os.IInterface, @Nullable String);
     method public static final long clearCallingIdentity();
+    method public static final long clearCallingWorkSource();
     method public void dump(@NonNull java.io.FileDescriptor, @Nullable String[]);
     method protected void dump(@NonNull java.io.FileDescriptor, @NonNull java.io.PrintWriter, @Nullable String[]);
     method public void dumpAsync(@NonNull java.io.FileDescriptor, @Nullable String[]);
@@ -34288,6 +34284,7 @@
     method public static final int getCallingUid();
     method public static final int getCallingUidOrThrow();
     method @NonNull public static final android.os.UserHandle getCallingUserHandle();
+    method public static final int getCallingWorkSourceUid();
     method @Nullable public String getInterfaceDescriptor();
     method public boolean isBinderAlive();
     method public static final void joinThreadPool();
@@ -34296,6 +34293,8 @@
     method public boolean pingBinder();
     method @Nullable public android.os.IInterface queryLocalInterface(@NonNull String);
     method public static final void restoreCallingIdentity(long);
+    method public static final void restoreCallingWorkSource(long);
+    method public static final long setCallingWorkSourceUid(int);
     method public final boolean transact(int, @NonNull android.os.Parcel, @Nullable android.os.Parcel, int) throws android.os.RemoteException;
     method public boolean unlinkToDeath(@NonNull android.os.IBinder.DeathRecipient, int);
   }
@@ -34650,9 +34649,11 @@
     method @NonNull public static java.io.File getRootDirectory();
     method @Deprecated public static String getStorageState(java.io.File);
     method public static boolean isExternalStorageEmulated();
-    method public static boolean isExternalStorageEmulated(java.io.File);
+    method public static boolean isExternalStorageEmulated(@NonNull java.io.File);
     method public static boolean isExternalStorageRemovable();
-    method public static boolean isExternalStorageRemovable(java.io.File);
+    method public static boolean isExternalStorageRemovable(@NonNull java.io.File);
+    method public static boolean isExternalStorageSandboxed();
+    method public static boolean isExternalStorageSandboxed(@NonNull java.io.File);
     field public static String DIRECTORY_ALARMS;
     field public static String DIRECTORY_AUDIOBOOKS;
     field public static String DIRECTORY_DCIM;
@@ -37072,12 +37073,6 @@
     field public static final String CACHED_NUMBER_TYPE = "numbertype";
     field public static final String CACHED_PHOTO_ID = "photo_id";
     field public static final String CACHED_PHOTO_URI = "photo_uri";
-    field public static final String CALL_ID_APP_NAME = "call_id_app_name";
-    field public static final String CALL_ID_DESCRIPTION = "call_id_description";
-    field public static final String CALL_ID_DETAILS = "call_id_details";
-    field public static final String CALL_ID_NAME = "call_id_name";
-    field public static final String CALL_ID_NUISANCE_CONFIDENCE = "call_id_nuisance_confidence";
-    field public static final String CALL_ID_PACKAGE_NAME = "call_id_package_name";
     field public static final String CALL_SCREENING_APP_NAME = "call_screening_app_name";
     field public static final String CALL_SCREENING_COMPONENT_NAME = "call_screening_component_name";
     field public static final android.net.Uri CONTENT_FILTER_URI;
@@ -38850,6 +38845,7 @@
     field public static final String ACTION_APPLICATION_DETAILS_SETTINGS = "android.settings.APPLICATION_DETAILS_SETTINGS";
     field public static final String ACTION_APPLICATION_DEVELOPMENT_SETTINGS = "android.settings.APPLICATION_DEVELOPMENT_SETTINGS";
     field public static final String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
+    field public static final String ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS = "android.settings.APP_NOTIFICATION_BUBBLE_SETTINGS";
     field public static final String ACTION_APP_NOTIFICATION_SETTINGS = "android.settings.APP_NOTIFICATION_SETTINGS";
     field public static final String ACTION_APP_SEARCH_SETTINGS = "android.settings.APP_SEARCH_SETTINGS";
     field public static final String ACTION_APP_USAGE_SETTINGS = "android.settings.action.APP_USAGE_SETTINGS";
@@ -42521,6 +42517,7 @@
     method public static int getpid();
     method public static int getppid();
     method public static java.net.SocketAddress getsockname(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method @NonNull public static android.system.StructTimeval getsockoptTimeval(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
     method public static int gettid();
     method public static int getuid();
     method public static byte[] getxattr(String, String) throws android.system.ErrnoException;
@@ -42571,6 +42568,7 @@
     method @Deprecated public static void setgid(int) throws android.system.ErrnoException;
     method public static int setsid() throws android.system.ErrnoException;
     method public static void setsockoptInt(java.io.FileDescriptor, int, int, int) throws android.system.ErrnoException;
+    method public static void setsockoptTimeval(@NonNull java.io.FileDescriptor, int, int, @NonNull android.system.StructTimeval) throws android.system.ErrnoException;
     method @Deprecated public static void setuid(int) throws android.system.ErrnoException;
     method public static void setxattr(String, String, byte[], int) throws android.system.ErrnoException;
     method public static void shutdown(java.io.FileDescriptor, int) throws android.system.ErrnoException;
@@ -42776,6 +42774,10 @@
     field public static final int F_SETOWN;
     field public static final int F_UNLCK;
     field public static final int F_WRLCK;
+    field public static final int ICMP6_ECHO_REPLY;
+    field public static final int ICMP6_ECHO_REQUEST;
+    field public static final int ICMP_ECHO;
+    field public static final int ICMP_ECHOREPLY;
     field public static final int IFA_F_DADFAILED;
     field public static final int IFA_F_DEPRECATED;
     field public static final int IFA_F_HOMEADDRESS;
@@ -43148,6 +43150,13 @@
     field public final long tv_sec;
   }
 
+  public final class StructTimeval {
+    method @NonNull public static android.system.StructTimeval fromMillis(long);
+    method public long toMillis();
+    field public final long tv_sec;
+    field public final long tv_usec;
+  }
+
   public final class StructUtsname {
     ctor public StructUtsname(String, String, String, String, String);
     field public final String machine;
@@ -43246,7 +43255,6 @@
     method public android.telecom.PhoneAccountHandle getAccountHandle();
     method public int getCallCapabilities();
     method public int getCallDirection();
-    method @Nullable public android.telecom.CallIdentification getCallIdentification();
     method public int getCallProperties();
     method public String getCallerDisplayName();
     method public int getCallerDisplayNamePresentation();
@@ -43328,34 +43336,6 @@
     field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
   }
 
-  public final class CallIdentification implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public CharSequence getCallScreeningAppName();
-    method @NonNull public String getCallScreeningPackageName();
-    method @Nullable public CharSequence getDescription();
-    method @Nullable public CharSequence getDetails();
-    method @Nullable public CharSequence getName();
-    method public int getNuisanceConfidence();
-    method @Nullable public android.graphics.drawable.Icon getPhoto();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int CONFIDENCE_LIKELY_NOT_NUISANCE = -1; // 0xffffffff
-    field public static final int CONFIDENCE_LIKELY_NUISANCE = 1; // 0x1
-    field public static final int CONFIDENCE_NOT_NUISANCE = -2; // 0xfffffffe
-    field public static final int CONFIDENCE_NUISANCE = 2; // 0x2
-    field public static final int CONFIDENCE_UNKNOWN = 0; // 0x0
-    field @NonNull public static final android.os.Parcelable.Creator<android.telecom.CallIdentification> CREATOR;
-  }
-
-  public static final class CallIdentification.Builder {
-    ctor public CallIdentification.Builder();
-    method @NonNull public android.telecom.CallIdentification build();
-    method @NonNull public android.telecom.CallIdentification.Builder setDescription(@Nullable CharSequence);
-    method @NonNull public android.telecom.CallIdentification.Builder setDetails(@Nullable CharSequence);
-    method @NonNull public android.telecom.CallIdentification.Builder setName(@Nullable CharSequence);
-    method @NonNull public android.telecom.CallIdentification.Builder setNuisanceConfidence(int);
-    method @NonNull public android.telecom.CallIdentification.Builder setPhoto(@Nullable android.graphics.drawable.Icon);
-  }
-
   public abstract class CallRedirectionService extends android.app.Service {
     ctor public CallRedirectionService();
     method public final void cancelCall();
@@ -43371,17 +43351,7 @@
     ctor public CallScreeningService();
     method public android.os.IBinder onBind(android.content.Intent);
     method public abstract void onScreenCall(@NonNull android.telecom.Call.Details);
-    method public final void provideCallIdentification(@NonNull android.telecom.Call.Details, @NonNull android.telecom.CallIdentification);
     method public final void respondToCall(@NonNull android.telecom.Call.Details, @NonNull android.telecom.CallScreeningService.CallResponse);
-    field public static final String ACTION_NUISANCE_CALL_STATUS_CHANGED = "android.telecom.action.NUISANCE_CALL_STATUS_CHANGED";
-    field public static final int CALL_DURATION_LONG = 4; // 0x4
-    field public static final int CALL_DURATION_MEDIUM = 3; // 0x3
-    field public static final int CALL_DURATION_SHORT = 2; // 0x2
-    field public static final int CALL_DURATION_VERY_SHORT = 1; // 0x1
-    field public static final String EXTRA_CALL_DURATION = "android.telecom.extra.CALL_DURATION";
-    field public static final String EXTRA_CALL_HANDLE = "android.telecom.extra.CALL_HANDLE";
-    field public static final String EXTRA_CALL_TYPE = "android.telecom.extra.CALL_TYPE";
-    field public static final String EXTRA_IS_NUISANCE = "android.telecom.extra.IS_NUISANCE";
     field public static final String SERVICE_INTERFACE = "android.telecom.CallScreeningService";
   }
 
@@ -43990,7 +43960,6 @@
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, String);
     method @RequiresPermission(anyOf={android.Manifest.permission.CALL_PHONE, android.Manifest.permission.MANAGE_OWN_CALLS}) public void placeCall(android.net.Uri, android.os.Bundle);
     method public void registerPhoneAccount(android.telecom.PhoneAccount);
-    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void reportNuisanceCallStatus(@NonNull android.net.Uri, boolean);
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void showInCallScreen(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void silenceRinger();
     method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
@@ -49717,8 +49686,9 @@
     method public default CharSequence getContentDescription();
     method public int getGroupId();
     method public android.graphics.drawable.Drawable getIcon();
+    method @Nullable public default android.graphics.BlendMode getIconTintBlendMode();
     method @Nullable public default android.content.res.ColorStateList getIconTintList();
-    method @Nullable public default android.graphics.PorterDuff.Mode getIconTintMode();
+    method @Deprecated @Nullable public default android.graphics.PorterDuff.Mode getIconTintMode();
     method public android.content.Intent getIntent();
     method public int getItemId();
     method public android.view.ContextMenu.ContextMenuInfo getMenuInfo();
@@ -49747,7 +49717,8 @@
     method public android.view.MenuItem setIcon(android.graphics.drawable.Drawable);
     method public android.view.MenuItem setIcon(@DrawableRes int);
     method public default android.view.MenuItem setIconTintList(@Nullable android.content.res.ColorStateList);
-    method public default android.view.MenuItem setIconTintMode(@Nullable android.graphics.PorterDuff.Mode);
+    method @Deprecated @NonNull public default android.view.MenuItem setIconTintMode(@Nullable android.graphics.PorterDuff.Mode);
+    method @NonNull public default android.view.MenuItem setIconTintMode(@Nullable android.graphics.BlendMode);
     method public android.view.MenuItem setIntent(android.content.Intent);
     method public android.view.MenuItem setNumericShortcut(char);
     method public default android.view.MenuItem setNumericShortcut(char, int);
@@ -50400,8 +50371,9 @@
     method public int getAutofillType();
     method @Nullable public android.view.autofill.AutofillValue getAutofillValue();
     method public android.graphics.drawable.Drawable getBackground();
+    method @Nullable public android.graphics.BlendMode getBackgroundBlendMode();
     method @Nullable public android.content.res.ColorStateList getBackgroundTintList();
-    method @Nullable public android.graphics.PorterDuff.Mode getBackgroundTintMode();
+    method @Deprecated @Nullable public android.graphics.PorterDuff.Mode getBackgroundTintMode();
     method @android.view.ViewDebug.ExportedProperty(category="layout") public int getBaseline();
     method @android.view.ViewDebug.CapturedViewProperty public final int getBottom();
     method protected float getBottomFadingEdgeStrength();
@@ -50432,9 +50404,10 @@
     method public java.util.ArrayList<android.view.View> getFocusables(int);
     method public void getFocusedRect(android.graphics.Rect);
     method public android.graphics.drawable.Drawable getForeground();
+    method @Nullable public android.graphics.BlendMode getForegroundBlendMode();
     method public int getForegroundGravity();
     method @Nullable public android.content.res.ColorStateList getForegroundTintList();
-    method @Nullable public android.graphics.PorterDuff.Mode getForegroundTintMode();
+    method @Deprecated @Nullable public android.graphics.PorterDuff.Mode getForegroundTintMode();
     method public boolean getGlobalVisibleRect(android.graphics.Rect, android.graphics.Point);
     method public final boolean getGlobalVisibleRect(android.graphics.Rect);
     method public android.os.Handler getHandler();
@@ -50750,7 +50723,8 @@
     method @Deprecated public void setBackgroundDrawable(android.graphics.drawable.Drawable);
     method public void setBackgroundResource(@DrawableRes int);
     method public void setBackgroundTintList(@Nullable android.content.res.ColorStateList);
-    method public void setBackgroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
+    method @Deprecated public void setBackgroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
+    method public void setBackgroundTintMode(@Nullable android.graphics.BlendMode);
     method public final void setBottom(int);
     method public void setCameraDistance(float);
     method public void setClickable(boolean);
@@ -50777,7 +50751,8 @@
     method public void setForeground(android.graphics.drawable.Drawable);
     method public void setForegroundGravity(int);
     method public void setForegroundTintList(@Nullable android.content.res.ColorStateList);
-    method public void setForegroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
+    method @Deprecated public void setForegroundTintMode(@Nullable android.graphics.PorterDuff.Mode);
+    method public void setForegroundTintMode(@Nullable android.graphics.BlendMode);
     method public void setHapticFeedbackEnabled(boolean);
     method public void setHasTransientState(boolean);
     method public void setHorizontalFadingEdgeEnabled(boolean);
@@ -52297,7 +52272,7 @@
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction> getActionList();
     method @Deprecated public int getActions();
     method public java.util.List<java.lang.String> getAvailableExtraData();
-    method public void getBoundsInParent(android.graphics.Rect);
+    method @Deprecated public void getBoundsInParent(android.graphics.Rect);
     method public void getBoundsInScreen(android.graphics.Rect);
     method public android.view.accessibility.AccessibilityNodeInfo getChild(int);
     method public int getChildCount();
@@ -52366,7 +52341,7 @@
     method public boolean removeChild(android.view.View, int);
     method public void setAccessibilityFocused(boolean);
     method public void setAvailableExtraData(java.util.List<java.lang.String>);
-    method public void setBoundsInParent(android.graphics.Rect);
+    method @Deprecated public void setBoundsInParent(android.graphics.Rect);
     method public void setBoundsInScreen(android.graphics.Rect);
     method public void setCanOpenPopup(boolean);
     method public void setCheckable(boolean);
@@ -53046,6 +53021,16 @@
 
 package android.view.contentcapture {
 
+  public final class ContentCaptureCondition implements android.os.Parcelable {
+    ctor public ContentCaptureCondition(@NonNull android.content.LocusId, int);
+    method public int describeContents();
+    method public int getFlags();
+    method @NonNull public android.content.LocusId getLocusId();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureCondition> CREATOR;
+    field public static final int FLAG_IS_REGEX = 2; // 0x2
+  }
+
   public final class ContentCaptureContext implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public static android.view.contentcapture.ContentCaptureContext forLocusId(@NonNull String);
@@ -53062,6 +53047,7 @@
   }
 
   public final class ContentCaptureManager {
+    method @Nullable public java.util.Set<android.view.contentcapture.ContentCaptureCondition> getContentCaptureConditions();
     method @Nullable public android.content.ComponentName getServiceComponentName();
     method public boolean isContentCaptureEnabled();
     method public void removeUserData(@NonNull android.view.contentcapture.UserDataRemovalRequest);
diff --git a/api/system-current.txt b/api/system-current.txt
index 6317ae0..d1018be 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -49,6 +49,7 @@
     field @Deprecated public static final String BROADCAST_NETWORK_PRIVILEGED = "android.permission.BROADCAST_NETWORK_PRIVILEGED";
     field public static final String CAMERA_DISABLE_TRANSMIT_LED = "android.permission.CAMERA_DISABLE_TRANSMIT_LED";
     field public static final String CAPTURE_AUDIO_HOTWORD = "android.permission.CAPTURE_AUDIO_HOTWORD";
+    field public static final String CAPTURE_MEDIA_OUTPUT = "android.permission.CAPTURE_MEDIA_OUTPUT";
     field public static final String CAPTURE_TV_INPUT = "android.permission.CAPTURE_TV_INPUT";
     field public static final String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
     field public static final String CHANGE_DEVICE_IDLE_TEMP_WHITELIST = "android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST";
@@ -76,6 +77,7 @@
     field public static final String HDMI_CEC = "android.permission.HDMI_CEC";
     field public static final String HIDE_NON_SYSTEM_OVERLAY_WINDOWS = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS";
     field public static final String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
+    field public static final String INSTALL_DYNAMIC_SYSTEM = "android.permission.INSTALL_DYNAMIC_SYSTEM";
     field public static final String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS";
     field public static final String INSTALL_PACKAGE_UPDATES = "android.permission.INSTALL_PACKAGE_UPDATES";
     field public static final String INSTALL_SELF_UPDATES = "android.permission.INSTALL_SELF_UPDATES";
@@ -117,9 +119,11 @@
     field public static final String MODIFY_PARENTAL_CONTROLS = "android.permission.MODIFY_PARENTAL_CONTROLS";
     field public static final String MODIFY_QUIET_MODE = "android.permission.MODIFY_QUIET_MODE";
     field public static final String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE";
+    field public static final String NETWORK_CARRIER_PROVISIONING = "android.permission.NETWORK_CARRIER_PROVISIONING";
     field public static final String NETWORK_MANAGED_PROVISIONING = "android.permission.NETWORK_MANAGED_PROVISIONING";
     field public static final String NETWORK_SCAN = "android.permission.NETWORK_SCAN";
     field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
+    field public static final String NETWORK_SIGNAL_STRENGTH_WAKEUP = "android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP";
     field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -402,9 +406,9 @@
     method public int describeContents();
     method public long getBeginTimeMillis();
     method public long getEndTimeMillis();
-    method public int getUidCount();
+    method @IntRange(from=0) public int getUidCount();
     method @Nullable public android.app.AppOpsManager.HistoricalUidOps getUidOps(int);
-    method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(int);
+    method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(@IntRange(from=0) int);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalOps> CREATOR;
   }
@@ -424,8 +428,8 @@
   public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String);
-    method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(int);
-    method public int getOpCount();
+    method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getOpCount();
     method @NonNull public String getPackageName();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalPackageOps> CREATOR;
@@ -433,9 +437,9 @@
 
   public static final class AppOpsManager.HistoricalUidOps implements android.os.Parcelable {
     method public int describeContents();
-    method public int getPackageCount();
+    method @IntRange(from=0) public int getPackageCount();
     method @Nullable public android.app.AppOpsManager.HistoricalPackageOps getPackageOps(@NonNull String);
-    method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(int);
+    method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(@IntRange(from=0) int);
     method public int getUid();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalUidOps> CREATOR;
@@ -491,12 +495,12 @@
     ctor public InstantAppResolverService();
     method public final void attachBaseContext(android.content.Context);
     method public final android.os.IBinder onBind(android.content.Intent);
-    method @Deprecated public void onGetInstantAppIntentFilter(int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method @Deprecated public void onGetInstantAppIntentFilter(android.content.Intent, int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method public void onGetInstantAppIntentFilter(android.content.Intent, int[], android.os.UserHandle, String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method @Deprecated public void onGetInstantAppResolveInfo(int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method @Deprecated public void onGetInstantAppResolveInfo(android.content.Intent, int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method public void onGetInstantAppResolveInfo(android.content.Intent, int[], android.os.UserHandle, String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method @Deprecated public void onGetInstantAppIntentFilter(@Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method @Deprecated public void onGetInstantAppIntentFilter(@NonNull android.content.Intent, @Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method public void onGetInstantAppIntentFilter(@NonNull android.content.Intent, @Nullable int[], @NonNull android.os.UserHandle, @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method @Deprecated public void onGetInstantAppResolveInfo(@Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method @Deprecated public void onGetInstantAppResolveInfo(@NonNull android.content.Intent, @Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method public void onGetInstantAppResolveInfo(@NonNull android.content.Intent, @Nullable int[], @NonNull android.os.UserHandle, @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
   }
 
   public static final class InstantAppResolverService.InstantAppResolutionCallback {
@@ -563,7 +567,7 @@
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
     method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
-    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
+    method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @NonNull public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
     method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setBroadcastSubscriber(android.app.PendingIntent, long, long) throws android.app.StatsManager.StatsUnavailableException;
     method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
     method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
@@ -1256,9 +1260,9 @@
   public final class BluetoothDevice implements android.os.Parcelable {
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean cancelBondProcess();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public String getMetadata(int);
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean getSilenceMode();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isConnected();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, String);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int);
@@ -1267,7 +1271,6 @@
     field public static final int ACCESS_REJECTED = 2; // 0x2
     field public static final int ACCESS_UNKNOWN = 0; // 0x0
     field public static final String ACTION_SILENCE_MODE_CHANGED = "android.bluetooth.device.action.SILENCE_MODE_CHANGED";
-    field public static final String EXTRA_SILENCE_ENABLED = "android.bluetooth.device.extra.SILENCE_ENABLED";
     field public static final int METADATA_COMPANION_APP = 4; // 0x4
     field public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16; // 0x10
     field public static final int METADATA_HARDWARE_VERSION = 3; // 0x3
@@ -1456,14 +1459,14 @@
 
   public final class OverlayInfo implements android.os.Parcelable {
     method public int describeContents();
+    method @Nullable public String getCategory();
+    method @NonNull public String getPackageName();
+    method @Nullable public String getTargetOverlayableName();
+    method @NonNull public String getTargetPackageName();
+    method public int getUserId();
     method public boolean isEnabled();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.content.om.OverlayInfo> CREATOR;
-    field public final String category;
-    field public final String packageName;
-    field public final String targetOverlayableName;
-    field public final String targetPackageName;
-    field public final int userId;
   }
 
   public class OverlayManager {
@@ -1548,6 +1551,18 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.IntentFilterVerificationInfo> CREATOR;
   }
 
+  public class LauncherApps {
+    method @Nullable public android.content.pm.LauncherApps.AppUsageLimit getAppUsageLimit(@NonNull String, @NonNull android.os.UserHandle);
+  }
+
+  public static final class LauncherApps.AppUsageLimit implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getTotalUsageLimit();
+    method public long getUsageRemaining();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.AppUsageLimit> CREATOR;
+  }
+
   public class PackageInstaller {
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
   }
@@ -1591,53 +1606,52 @@
   }
 
   public abstract class PackageManager {
-    method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
+    method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
     method public abstract boolean arePermissionsIndividuallyControlled();
-    method public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(String);
+    method @NonNull public abstract java.util.List<android.content.IntentFilter> getAllIntentFilters(@NonNull String);
     method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.pm.ApplicationInfo getApplicationInfoAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
     method @NonNull public android.content.pm.dex.ArtManager getArtManager();
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_SHARED_LIBRARIES) public java.util.List<android.content.pm.SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String, int);
-    method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int);
+    method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int);
     method @Nullable @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public CharSequence getHarmfulAppWarning(@NonNull String);
-    method public String getIncidentReportApproverPackageName();
-    method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int);
+    method @Nullable public String getIncidentReportApproverPackageName();
+    method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int);
     method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_INSTANT_APPS) public abstract android.graphics.drawable.Drawable getInstantAppIcon(String);
-    method public abstract android.content.ComponentName getInstantAppInstallerComponent();
-    method public abstract android.content.ComponentName getInstantAppResolverSettingsComponent();
+    method @Nullable public abstract android.content.ComponentName getInstantAppInstallerComponent();
+    method @Nullable public abstract android.content.ComponentName getInstantAppResolverSettingsComponent();
     method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_INSTANT_APPS) public abstract java.util.List<android.content.pm.InstantAppInfo> getInstantApps();
-    method public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(String);
-    method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract int getIntentVerificationStatusAsUser(String, int);
-    method @android.content.pm.PackageManager.PermissionFlags @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS}) public abstract int getPermissionFlags(String, String, @NonNull android.os.UserHandle);
+    method @NonNull public abstract java.util.List<android.content.pm.IntentFilterVerificationInfo> getIntentFilterVerifications(@NonNull String);
+    method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract int getIntentVerificationStatusAsUser(@NonNull String, int);
+    method @android.content.pm.PackageManager.PermissionFlags @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
     method @NonNull @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] getUnsuspendablePackages(@NonNull String[]);
     method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
-    method @Deprecated public abstract int installExistingPackage(String) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @Deprecated public abstract int installExistingPackage(String, int) throws android.content.pm.PackageManager.NameNotFoundException;
-    method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(android.content.Intent, int, android.os.UserHandle);
+    method @Deprecated public abstract int installExistingPackage(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @Deprecated public abstract int installExistingPackage(@NonNull String, int) throws android.content.pm.PackageManager.NameNotFoundException;
+    method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceiversAsUser(@NonNull android.content.Intent, int, android.os.UserHandle);
     method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentActivitiesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
     method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentContentProvidersAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
     method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public java.util.List<android.content.pm.ResolveInfo> queryIntentServicesAsUser(@NonNull android.content.Intent, int, @NonNull android.os.UserHandle);
-    method public abstract void registerDexModule(String, @Nullable android.content.pm.PackageManager.DexModuleRegisterCallback);
-    method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
+    method public abstract void registerDexModule(@NonNull String, @Nullable android.content.pm.PackageManager.DexModuleRegisterCallback);
+    method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
     method @Deprecated public void replacePreferredActivity(@NonNull android.content.IntentFilter, int, @NonNull java.util.List<android.content.ComponentName>, @NonNull android.content.ComponentName);
     method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
     method public void sendDeviceCustomizationReadyBroadcast();
-    method @RequiresPermission(allOf={android.Manifest.permission.SET_PREFERRED_APPLICATIONS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public abstract boolean setDefaultBrowserPackageNameAsUser(String, int);
+    method @RequiresPermission(allOf={android.Manifest.permission.SET_PREFERRED_APPLICATIONS, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}) public abstract boolean setDefaultBrowserPackageNameAsUser(@Nullable String, int);
     method @NonNull @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setDistractingPackageRestrictions(@NonNull String[], int);
     method @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public void setHarmfulAppWarning(@NonNull String, @Nullable CharSequence);
     method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable String);
     method @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable android.content.pm.SuspendDialogInfo);
     method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public void setSyntheticAppDetailsActivityEnabled(@NonNull String, boolean);
-    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public abstract void setUpdateAvailable(String, boolean);
-    method @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public abstract boolean updateIntentVerificationStatusAsUser(String, int, int);
-    method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(String, String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle);
-    method @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, java.util.List<java.lang.String>);
+    method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public abstract void setUpdateAvailable(@NonNull String, boolean);
+    method @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS) public abstract boolean updateIntentVerificationStatusAsUser(@NonNull String, int, int);
+    method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle);
+    method @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT) public abstract void verifyIntentFilter(int, int, @NonNull java.util.List<java.lang.String>);
     field public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS";
     field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES";
     field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
     field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
     field public static final String FEATURE_TELEPHONY_CARRIERLOCK = "android.hardware.telephony.carrierlock";
     field public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 32; // 0x20
-    field public static final int FLAG_PERMISSION_HIDDEN = 1024; // 0x400
     field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
     field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40
     field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8
@@ -1708,7 +1722,7 @@
     method public void onPermissionsChanged(int);
   }
 
-  @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags {
+  @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags {
   }
 
   public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -1740,7 +1754,7 @@
   }
 
   public class ShortcutManager {
-    method @NonNull public java.util.List<android.content.pm.ShortcutManager.ShareShortcutInfo> getShareTargets(@NonNull android.content.IntentFilter);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS) public java.util.List<android.content.pm.ShortcutManager.ShareShortcutInfo> getShareTargets(@NonNull android.content.IntentFilter);
     method public boolean hasShareTargets(@NonNull String);
   }
 
@@ -3376,19 +3390,19 @@
 
   public class LocationManager {
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void flushGnssBatch();
+    method @Nullable public String getExtraLocationControllerPackage();
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int getGnssBatchSize();
     method @Nullable public android.location.GnssCapabilities getGnssCapabilities();
-    method @Nullable public String getLocationControllerExtraPackage();
     method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void injectGnssMeasurementCorrections(@NonNull android.location.GnssMeasurementCorrections);
-    method public boolean isLocationControllerExtraPackageEnabled();
+    method public boolean isExtraLocationControllerPackageEnabled();
     method public boolean isLocationEnabledForUser(@NonNull android.os.UserHandle);
     method public boolean isProviderEnabledForUser(@NonNull String, @NonNull android.os.UserHandle);
     method public boolean isProviderPackage(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerGnssBatchedLocationCallback(long, boolean, @NonNull android.location.BatchedLocationCallback, @Nullable android.os.Handler);
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
     method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackage(@NonNull String);
-    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackageEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackage(@Nullable String);
+    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackageEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
     method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser(@NonNull String, boolean, @NonNull android.os.UserHandle);
     method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean unregisterGnssBatchedLocationCallback(@NonNull android.location.BatchedLocationCallback);
@@ -3601,6 +3615,7 @@
     ctor public AudioMixingRule.Builder();
     method public android.media.audiopolicy.AudioMixingRule.Builder addMixRule(int, Object) throws java.lang.IllegalArgumentException;
     method public android.media.audiopolicy.AudioMixingRule.Builder addRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
+    method @NonNull public android.media.audiopolicy.AudioMixingRule.Builder allowPrivilegedPlaybackCapture(boolean);
     method public android.media.audiopolicy.AudioMixingRule build();
     method public android.media.audiopolicy.AudioMixingRule.Builder excludeMixRule(int, Object) throws java.lang.IllegalArgumentException;
     method public android.media.audiopolicy.AudioMixingRule.Builder excludeRule(android.media.AudioAttributes, int) throws java.lang.IllegalArgumentException;
@@ -4058,7 +4073,7 @@
   }
 
   public final class IpPrefix implements android.os.Parcelable {
-    ctor public IpPrefix(@NonNull java.net.InetAddress, int);
+    ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
     ctor public IpPrefix(@NonNull String);
   }
 
@@ -4079,8 +4094,8 @@
   }
 
   public class LinkAddress implements android.os.Parcelable {
-    ctor public LinkAddress(java.net.InetAddress, int, int, int);
-    ctor public LinkAddress(@NonNull java.net.InetAddress, int);
+    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int);
+    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
     ctor public LinkAddress(@NonNull String);
     ctor public LinkAddress(@NonNull String, int, int);
     method public boolean isGlobalPreferred();
@@ -4144,7 +4159,7 @@
   }
 
   public static class NetworkRequest.Builder {
-    method @NonNull public android.net.NetworkRequest.Builder setSignalStrength(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
   }
 
   public class NetworkScoreManager {
@@ -4217,13 +4232,19 @@
     method @Nullable public java.net.InetAddress getGateway();
     method @Nullable public android.net.LinkAddress getIpAddress();
     method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
-    method public void setDomains(@Nullable String);
-    method public void setGateway(@Nullable java.net.InetAddress);
-    method public void setIpAddress(@Nullable android.net.LinkAddress);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.StaticIpConfiguration> CREATOR;
   }
 
+  public static final class StaticIpConfiguration.Builder {
+    ctor public StaticIpConfiguration.Builder();
+    method @NonNull public android.net.StaticIpConfiguration build();
+    method @NonNull public android.net.StaticIpConfiguration.Builder setDnsServers(@NonNull Iterable<java.net.InetAddress>);
+    method @NonNull public android.net.StaticIpConfiguration.Builder setDomains(@Nullable String);
+    method @NonNull public android.net.StaticIpConfiguration.Builder setGateway(@Nullable java.net.InetAddress);
+    method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@Nullable android.net.LinkAddress);
+  }
+
   public class TrafficStats {
     method public static void setThreadStatsTagApp();
     method public static void setThreadStatsTagBackup();
@@ -4233,6 +4254,10 @@
     field public static final int TAG_SYSTEM_PROBE = -190; // 0xffffff42
   }
 
+  public abstract class Uri implements java.lang.Comparable<android.net.Uri> android.os.Parcelable {
+    method @NonNull public String toSafeString();
+  }
+
   public class VpnService extends android.app.Service {
     method @RequiresPermission(android.Manifest.permission.CONTROL_VPN) public static void prepareAndAuthorize(android.content.Context);
   }
@@ -4257,8 +4282,8 @@
   public final class ApfCapabilities implements android.os.Parcelable {
     ctor public ApfCapabilities(int, int, int);
     method public int describeContents();
-    method public static boolean getApfDrop8023Frames(@NonNull android.content.Context);
-    method @NonNull public static int[] getApfEthTypeBlackList(@NonNull android.content.Context);
+    method public static boolean getApfDrop8023Frames();
+    method @NonNull public static int[] getApfEtherTypeBlackList();
     method public boolean hasDataAccess();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.apf.ApfCapabilities> CREATOR;
@@ -4269,37 +4294,6 @@
 
 }
 
-package android.net.captiveportal {
-
-  public final class CaptivePortalProbeResult {
-    ctor public CaptivePortalProbeResult(int);
-    ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String);
-    ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String, @Nullable android.net.captiveportal.CaptivePortalProbeSpec);
-    method public boolean isFailed();
-    method public boolean isPartialConnectivity();
-    method public boolean isPortal();
-    method public boolean isSuccessful();
-    field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult FAILED;
-    field public static final int FAILED_CODE = 599; // 0x257
-    field public static final android.net.captiveportal.CaptivePortalProbeResult PARTIAL;
-    field public static final int PORTAL_CODE = 302; // 0x12e
-    field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult SUCCESS;
-    field public static final int SUCCESS_CODE = 204; // 0xcc
-    field @Nullable public final String detectUrl;
-    field @Nullable public final android.net.captiveportal.CaptivePortalProbeSpec probeSpec;
-    field @Nullable public final String redirectUrl;
-  }
-
-  public abstract class CaptivePortalProbeSpec {
-    method @NonNull public String getEncodedSpec();
-    method @NonNull public abstract android.net.captiveportal.CaptivePortalProbeResult getResult(int, @Nullable String);
-    method @NonNull public java.net.URL getUrl();
-    method @NonNull public static java.util.Collection<android.net.captiveportal.CaptivePortalProbeSpec> parseCaptivePortalProbeSpecs(@NonNull String);
-    method @Nullable public static android.net.captiveportal.CaptivePortalProbeSpec parseSpecOrNull(@Nullable String);
-  }
-
-}
-
 package android.net.metrics {
 
   public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event {
@@ -5149,10 +5143,6 @@
   }
 
   public class Binder implements android.os.IBinder {
-    method public static final long clearCallingWorkSource();
-    method public static final int getCallingWorkSourceUid();
-    method public static final void restoreCallingWorkSource(long);
-    method public static final long setCallingWorkSourceUid(int);
     method public static void setProxyTransactListener(@Nullable android.os.Binder.ProxyTransactListener);
   }
 
@@ -5643,12 +5633,12 @@
 
   public class DynamicSystemClient {
     ctor public DynamicSystemClient(@NonNull android.content.Context);
-    method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void bind();
+    method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void bind();
     method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
     method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
-    method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long);
-    method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long, long);
-    method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void unbind();
+    method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void start(@NonNull android.net.Uri, long);
+    method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void start(@NonNull android.net.Uri, long, long);
+    method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void unbind();
     field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6
     field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4
     field public static final int CAUSE_ERROR_IO = 3; // 0x3
@@ -5664,7 +5654,7 @@
   }
 
   public static interface DynamicSystemClient.OnStatusChangedListener {
-    method public void onStatusChanged(int, int, long);
+    method public void onStatusChanged(int, int, long, @Nullable Throwable);
   }
 
 }
@@ -6048,6 +6038,7 @@
     field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS";
     field public static final String ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS = "android.settings.LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS";
     field public static final String ACTION_MANAGE_DOMAIN_URLS = "android.settings.MANAGE_DOMAIN_URLS";
+    field public static final String ACTION_MANAGE_MORE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_MORE_DEFAULT_APPS_SETTINGS";
     field public static final String ACTION_NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS";
     field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE";
     field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS";
@@ -6444,6 +6435,7 @@
     method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
     method public void onDisconnected();
     method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
+    method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set<android.view.contentcapture.ContentCaptureCondition>);
     method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
     field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
     field public static final String SERVICE_META_DATA = "android.content_capture";
@@ -6895,6 +6887,22 @@
 
 }
 
+package android.service.watchdog {
+
+  public abstract class ExplicitHealthCheckService extends android.app.Service {
+    ctor public ExplicitHealthCheckService();
+    method public final void notifyHealthCheckPassed(@NonNull String);
+    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public abstract void onCancelHealthCheck(@NonNull String);
+    method @NonNull public abstract java.util.List<java.lang.String> onGetRequestedPackages();
+    method @NonNull public abstract java.util.List<java.lang.String> onGetSupportedPackages();
+    method public abstract void onRequestHealthCheck(@NonNull String);
+    field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
+    field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService";
+  }
+
+}
+
 package android.telecom {
 
   @Deprecated public class AudioState implements android.os.Parcelable {
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 9780d43..162f212 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -67,6 +67,8 @@
     method @Deprecated public boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
     method @Deprecated public void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
     method @Deprecated public void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackage(String);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackageEnabled(boolean);
   }
 
 }
diff --git a/api/test-current.txt b/api/test-current.txt
index d3ec216..67a26f3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -238,9 +238,9 @@
     method public int describeContents();
     method public long getBeginTimeMillis();
     method public long getEndTimeMillis();
-    method public int getUidCount();
+    method @IntRange(from=0) public int getUidCount();
     method @Nullable public android.app.AppOpsManager.HistoricalUidOps getUidOps(int);
-    method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(int);
+    method @NonNull public android.app.AppOpsManager.HistoricalUidOps getUidOpsAt(@IntRange(from=0) int);
     method public void increaseAccessCount(int, int, @NonNull String, int, int, long);
     method public void increaseAccessDuration(int, int, @NonNull String, int, int, long);
     method public void increaseRejectCount(int, int, @NonNull String, int, int, long);
@@ -264,8 +264,8 @@
   public static final class AppOpsManager.HistoricalPackageOps implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public android.app.AppOpsManager.HistoricalOp getOp(@NonNull String);
-    method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(int);
-    method public int getOpCount();
+    method @NonNull public android.app.AppOpsManager.HistoricalOp getOpAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getOpCount();
     method @NonNull public String getPackageName();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalPackageOps> CREATOR;
@@ -273,9 +273,9 @@
 
   public static final class AppOpsManager.HistoricalUidOps implements android.os.Parcelable {
     method public int describeContents();
-    method public int getPackageCount();
+    method @IntRange(from=0) public int getPackageCount();
     method @Nullable public android.app.AppOpsManager.HistoricalPackageOps getPackageOps(@NonNull String);
-    method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(int);
+    method @NonNull public android.app.AppOpsManager.HistoricalPackageOps getPackageOpsAt(@IntRange(from=0) int);
     method public int getUid();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalUidOps> CREATOR;
@@ -315,7 +315,9 @@
   }
 
   public final class NotificationChannel implements android.os.Parcelable {
+    method public boolean isImportanceLockedByCriticalDeviceFunction();
     method public boolean isImportanceLockedByOEM();
+    method public void setImportanceLockedByCriticalDeviceFunction(boolean);
     method public void setImportanceLockedByOEM(boolean);
   }
 
@@ -661,26 +663,27 @@
 
   public abstract class PackageManager {
     method public abstract boolean arePermissionsIndividuallyControlled();
-    method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int);
-    method public String getIncidentReportApproverPackageName();
-    method public abstract int getInstallReason(String, @NonNull android.os.UserHandle);
-    method public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int);
-    method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int);
+    method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int);
+    method @Nullable public String getIncidentReportApproverPackageName();
+    method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle);
+    method @NonNull public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int);
+    method @NonNull @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int);
     method @Nullable public abstract String[] getNamesForUids(int[]);
-    method public abstract String getPermissionControllerPackageName();
-    method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS", "android.permission.GET_RUNTIME_PERMISSIONS"}) public abstract int getPermissionFlags(String, String, @NonNull android.os.UserHandle);
+    method @NonNull public abstract String getPermissionControllerPackageName();
+    method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS", "android.permission.GET_RUNTIME_PERMISSIONS"}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
     method @NonNull public abstract String getServicesSystemSharedLibraryPackageName();
     method @NonNull public abstract String getSharedSystemSharedLibraryPackageName();
-    method public String getWellbeingPackageName();
+    method @Nullable public String getWellbeingPackageName();
     method @RequiresPermission("android.permission.GRANT_RUNTIME_PERMISSIONS") public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
     method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle);
-    method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(String, String, int, int, @NonNull android.os.UserHandle);
+    method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, int, int, @NonNull android.os.UserHandle);
     field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage";
     field public static final String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption";
-    field public static final int FLAG_PERMISSION_HIDDEN = 1024; // 0x400
+    field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
     field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40
     field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8
     field public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED = 128; // 0x80
+    field public static final int FLAG_PERMISSION_SYSTEM_FIXED = 16; // 0x10
     field public static final int FLAG_PERMISSION_USER_FIXED = 2; // 0x2
     field public static final int FLAG_PERMISSION_USER_SET = 1; // 0x1
     field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
@@ -713,6 +716,11 @@
 
 package android.content.res {
 
+  public final class AssetManager implements java.lang.AutoCloseable {
+    method @NonNull public String[] getApkPaths();
+    method @Nullable public java.util.Map<java.lang.String,java.lang.String> getOverlayableMap(String);
+  }
+
   public final class Configuration implements java.lang.Comparable<android.content.res.Configuration> android.os.Parcelable {
     field public int assetsSeq;
     field public final android.app.WindowConfiguration windowConfiguration;
@@ -1237,7 +1245,7 @@
   }
 
   public final class IpPrefix implements android.os.Parcelable {
-    ctor public IpPrefix(@NonNull java.net.InetAddress, int);
+    ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
     ctor public IpPrefix(@NonNull String);
   }
 
@@ -1246,8 +1254,8 @@
   }
 
   public class LinkAddress implements android.os.Parcelable {
-    ctor public LinkAddress(java.net.InetAddress, int, int, int);
-    ctor public LinkAddress(@NonNull java.net.InetAddress, int);
+    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int);
+    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
     ctor public LinkAddress(@NonNull String);
     ctor public LinkAddress(@NonNull String, int, int);
     method public boolean isGlobalPreferred();
@@ -1317,13 +1325,19 @@
     method @Nullable public java.net.InetAddress getGateway();
     method @Nullable public android.net.LinkAddress getIpAddress();
     method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
-    method public void setDomains(@Nullable String);
-    method public void setGateway(@Nullable java.net.InetAddress);
-    method public void setIpAddress(@Nullable android.net.LinkAddress);
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.StaticIpConfiguration> CREATOR;
   }
 
+  public static final class StaticIpConfiguration.Builder {
+    ctor public StaticIpConfiguration.Builder();
+    method @NonNull public android.net.StaticIpConfiguration build();
+    method @NonNull public android.net.StaticIpConfiguration.Builder setDnsServers(@NonNull Iterable<java.net.InetAddress>);
+    method @NonNull public android.net.StaticIpConfiguration.Builder setDomains(@Nullable String);
+    method @NonNull public android.net.StaticIpConfiguration.Builder setGateway(@Nullable java.net.InetAddress);
+    method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@Nullable android.net.LinkAddress);
+  }
+
   public final class TestNetworkInterface implements android.os.Parcelable {
     ctor public TestNetworkInterface(android.os.ParcelFileDescriptor, String);
     method public int describeContents();
@@ -1356,8 +1370,8 @@
   public final class ApfCapabilities implements android.os.Parcelable {
     ctor public ApfCapabilities(int, int, int);
     method public int describeContents();
-    method public static boolean getApfDrop8023Frames(@NonNull android.content.Context);
-    method @NonNull public static int[] getApfEthTypeBlackList(@NonNull android.content.Context);
+    method public static boolean getApfDrop8023Frames();
+    method @NonNull public static int[] getApfEtherTypeBlackList();
     method public boolean hasDataAccess();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.net.apf.ApfCapabilities> CREATOR;
@@ -1368,37 +1382,6 @@
 
 }
 
-package android.net.captiveportal {
-
-  public final class CaptivePortalProbeResult {
-    ctor public CaptivePortalProbeResult(int);
-    ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String);
-    ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String, @Nullable android.net.captiveportal.CaptivePortalProbeSpec);
-    method public boolean isFailed();
-    method public boolean isPartialConnectivity();
-    method public boolean isPortal();
-    method public boolean isSuccessful();
-    field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult FAILED;
-    field public static final int FAILED_CODE = 599; // 0x257
-    field public static final android.net.captiveportal.CaptivePortalProbeResult PARTIAL;
-    field public static final int PORTAL_CODE = 302; // 0x12e
-    field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult SUCCESS;
-    field public static final int SUCCESS_CODE = 204; // 0xcc
-    field @Nullable public final String detectUrl;
-    field @Nullable public final android.net.captiveportal.CaptivePortalProbeSpec probeSpec;
-    field @Nullable public final String redirectUrl;
-  }
-
-  public abstract class CaptivePortalProbeSpec {
-    method @NonNull public String getEncodedSpec();
-    method @NonNull public abstract android.net.captiveportal.CaptivePortalProbeResult getResult(int, @Nullable String);
-    method @NonNull public java.net.URL getUrl();
-    method @NonNull public static java.util.Collection<android.net.captiveportal.CaptivePortalProbeSpec> parseCaptivePortalProbeSpecs(@NonNull String);
-    method @Nullable public static android.net.captiveportal.CaptivePortalProbeSpec parseSpecOrNull(@Nullable String);
-  }
-
-}
-
 package android.net.metrics {
 
   public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event {
@@ -2150,9 +2133,9 @@
     method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static long getContributedMediaSize(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
     method @NonNull public static java.io.File getVolumePath(@NonNull String) throws java.io.FileNotFoundException;
     method @NonNull public static java.util.Collection<java.io.File> getVolumeScanPaths(@NonNull String) throws java.io.FileNotFoundException;
-    field public static final String EXTRA_ORIGINATED_FROM_SHELL = "android.intent.extra.originated_from_shell";
-    field public static final String SCAN_FILE_CALL = "scan_file";
-    field public static final String SCAN_VOLUME_CALL = "scan_volume";
+    method public static android.net.Uri scanFile(android.content.Context, java.io.File);
+    method public static android.net.Uri scanFileFromShell(android.content.Context, java.io.File);
+    method public static void scanVolume(android.content.Context, java.io.File);
   }
 
   public final class Settings {
@@ -2457,6 +2440,7 @@
     method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
     method public void onDisconnected();
     method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
+    method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set<android.view.contentcapture.ContentCaptureCondition>);
     method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
     field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
     field public static final String SERVICE_META_DATA = "android.content_capture";
@@ -2662,6 +2646,15 @@
     method public void setVoiceRoamingType(int);
   }
 
+  public final class SmsManager {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
+    field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
+    field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
+    field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
+    field public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4; // 0x4
+    field public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2; // 0x2
+  }
+
   public class TelephonyManager {
     method public int checkCarrierPrivilegesForPackage(String);
     method public int getCarrierIdListVersion();
diff --git a/cmds/bmgr/Android.bp b/cmds/bmgr/Android.bp
new file mode 100644
index 0000000..b64923b
--- /dev/null
+++ b/cmds/bmgr/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2007 The Android Open Source Project
+//
+
+java_binary {
+    name: "bmgr",
+    wrapper: "bmgr",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/bmgr/Android.mk b/cmds/bmgr/Android.mk
deleted file mode 100644
index d520cf2..0000000
--- a/cmds/bmgr/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := bmgrlib
-LOCAL_MODULE_STEM := bmgr
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := bmgr
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_SRC_FILES := bmgr
-LOCAL_REQUIRED_MODULES := bmgrlib
-include $(BUILD_PREBUILT)
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 98ab666..680ccfc 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -112,6 +112,11 @@
             return;
         }
 
+        if ("activated".equals(op)) {
+            doActivated(userId);
+            return;
+        }
+
         if (!isBackupActive(userId)) {
             return;
         }
@@ -200,6 +205,21 @@
         return true;
     }
 
+    private String activatedToString(boolean activated) {
+        return activated ? "activated" : "deactivated";
+    }
+
+    private void doActivated(@UserIdInt int userId) {
+        try {
+            System.out.println("Backup Manager currently "
+                    + activatedToString(mBmgr.isBackupServiceActive(userId)));
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(BMGR_NOT_RUNNING_ERR);
+        }
+
+    }
+
     private String enableToString(boolean enabled) {
         return enabled ? "enabled" : "disabled";
     }
@@ -907,6 +927,7 @@
         System.err.println("       bmgr cancel backups");
         System.err.println("       bmgr init TRANSPORT...");
         System.err.println("       bmgr activate BOOL");
+        System.err.println("       bmgr activated");
         System.err.println("");
         System.err.println("The '--user' option specifies the user on which the operation is run.");
         System.err.println("It must be the first argument before the operation.");
@@ -978,6 +999,9 @@
         System.err.println("If the argument is 'true' it will be activated, otherwise it will be");
         System.err.println("deactivated. When deactivated, the service will not be running and no");
         System.err.println("operations can be performed until activation.");
+        System.err.println("");
+        System.err.println("The 'activated' command reports the current activated/deactivated");
+        System.err.println("state of the backup mechanism.");
     }
 
     private static class BackupMonitor extends IBackupManagerMonitor.Stub {
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index a6c7cae..8e7277c 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -101,7 +101,7 @@
 
 BootAnimation::BootAnimation(sp<Callbacks> callbacks)
         : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
-        mTimeFormat12Hour(false), mTimeCheckThread(NULL), mCallbacks(callbacks) {
+        mTimeFormat12Hour(false), mTimeCheckThread(nullptr), mCallbacks(callbacks) {
     mSession = new SurfaceComposerClient();
 
     std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
@@ -156,7 +156,7 @@
 status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
         const char* name) {
     Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
-    if (asset == NULL)
+    if (asset == nullptr)
         return NO_INIT;
     SkBitmap bitmap;
     sk_sp<SkData> data = SkData::MakeWithoutCopy(asset->getBuffer(false),
@@ -234,7 +234,7 @@
         case kN32_SkColorType:
             if (!mUseNpotTextures && (tw != w || th != h)) {
                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
-                        GL_UNSIGNED_BYTE, 0);
+                        GL_UNSIGNED_BYTE, nullptr);
                 glTexSubImage2D(GL_TEXTURE_2D, 0,
                         0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
             } else {
@@ -246,7 +246,7 @@
         case kRGB_565_SkColorType:
             if (!mUseNpotTextures && (tw != w || th != h)) {
                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
-                        GL_UNSIGNED_SHORT_5_6_5, 0);
+                        GL_UNSIGNED_SHORT_5_6_5, nullptr);
                 glTexSubImage2D(GL_TEXTURE_2D, 0,
                         0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
             } else {
@@ -304,10 +304,10 @@
 
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
 
-    eglInitialize(display, 0, 0);
+    eglInitialize(display, nullptr, nullptr);
     eglChooseConfig(display, attribs, &config, 1, &numConfigs);
-    surface = eglCreateWindowSurface(display, config, s.get(), NULL);
-    context = eglCreateContext(display, config, NULL, NULL);
+    surface = eglCreateWindowSurface(display, config, s.get(), nullptr);
+    context = eglCreateContext(display, config, nullptr, nullptr);
     eglQuerySurface(display, surface, EGL_WIDTH, &w);
     eglQuerySurface(display, surface, EGL_HEIGHT, &h);
 
@@ -671,7 +671,7 @@
     // Parse the description file
     for (;;) {
         const char* endl = strstr(s, "\n");
-        if (endl == NULL) break;
+        if (endl == nullptr) break;
         String8 line(s, endl - s);
         const char* l = line.string();
         int fps = 0;
@@ -699,8 +699,8 @@
             part.count = count;
             part.pause = pause;
             part.path = path;
-            part.audioData = NULL;
-            part.animation = NULL;
+            part.audioData = nullptr;
+            part.animation = nullptr;
             if (!parseColor(color, part.backgroundColor)) {
                 SLOGE("> invalid color '#%s'", color);
                 part.backgroundColor[0] = 0.0f;
@@ -716,9 +716,9 @@
             part.playUntilComplete = false;
             part.count = 1;
             part.pause = 0;
-            part.audioData = NULL;
+            part.audioData = nullptr;
             part.animation = loadAnimation(String8(SYSTEM_BOOTANIMATION_FILE));
-            if (part.animation != NULL)
+            if (part.animation != nullptr)
                 animation.parts.add(part);
         }
         s = ++endl;
@@ -731,7 +731,7 @@
 {
     // read all the data structures
     const size_t pcount = animation.parts.size();
-    void *cookie = NULL;
+    void *cookie = nullptr;
     ZipFileRO* zip = animation.zip;
     if (!zip->startIteration(&cookie)) {
         return false;
@@ -739,7 +739,7 @@
 
     ZipEntryRO entry;
     char name[ANIM_ENTRY_NAME_MAX];
-    while ((entry = zip->nextEntry(cookie)) != NULL) {
+    while ((entry = zip->nextEntry(cookie)) != nullptr) {
         const int foundEntryName = zip->getEntryFileName(entry, name, ANIM_ENTRY_NAME_MAX);
         if (foundEntryName > ANIM_ENTRY_NAME_MAX || foundEntryName == -1) {
             SLOGE("Error fetching entry file name");
@@ -762,7 +762,7 @@
                 if (path == animation.parts[j].path) {
                     uint16_t method;
                     // supports only stored png files
-                    if (zip->getEntryInfo(entry, &method, NULL, NULL, NULL, NULL, NULL)) {
+                    if (zip->getEntryInfo(entry, &method, nullptr, nullptr, nullptr, nullptr, nullptr)) {
                         if (method == ZipFileRO::kCompressStored) {
                             FileMap* map = zip->createEntryFileMap(entry);
                             if (map) {
@@ -800,7 +800,7 @@
         for (size_t frameIdx = 0; frameIdx < part.frames.size(); frameIdx++) {
             const char* endl = strstr(trimDataStr, "\n");
             // No more trimData for this part.
-            if (endl == NULL) {
+            if (endl == nullptr) {
                 break;
             }
             String8 line(trimDataStr, endl - trimDataStr);
@@ -927,7 +927,7 @@
         glBindTexture(GL_TEXTURE_2D, 0);
 
         // Handle animation package
-        if (part.animation != NULL) {
+        if (part.animation != nullptr) {
             playAnimation(*part.animation);
             if (exitPending())
                 break;
@@ -1001,7 +1001,7 @@
                     spec.tv_nsec = (now + delay) % 1000000000;
                     int err;
                     do {
-                        err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
+                        err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, nullptr);
                     } while (err<0 && errno == EINTR);
                 }
 
@@ -1090,13 +1090,13 @@
     if (mLoadedFiles.indexOf(fn) >= 0) {
         SLOGE("File \"%s\" is already loaded. Cyclic ref is not allowed",
             fn.string());
-        return NULL;
+        return nullptr;
     }
     ZipFileRO *zip = ZipFileRO::open(fn);
-    if (zip == NULL) {
+    if (zip == nullptr) {
         SLOGE("Failed to open animation zip \"%s\": %s",
             fn.string(), strerror(errno));
-        return NULL;
+        return nullptr;
     }
 
     Animation *animation =  new Animation;
@@ -1107,7 +1107,7 @@
 
     parseAnimationDesc(*animation);
     if (!preloadZip(*animation)) {
-        return NULL;
+        return nullptr;
     }
 
 
@@ -1135,7 +1135,7 @@
     }
 
     FILE* file = fopen(LAST_TIME_CHANGED_FILE_PATH, "r");
-    if (file != NULL) {
+    if (file != nullptr) {
       long long lastChangedTime = 0;
       fscanf(file, "%lld", &lastChangedTime);
       fclose(file);
diff --git a/cmds/bootanimation/audioplay.cpp b/cmds/bootanimation/audioplay.cpp
index 874aab0..c5e16c6 100644
--- a/cmds/bootanimation/audioplay.cpp
+++ b/cmds/bootanimation/audioplay.cpp
@@ -39,14 +39,14 @@
 using namespace android;
 
 // engine interfaces
-static SLObjectItf engineObject = NULL;
+static SLObjectItf engineObject = nullptr;
 static SLEngineItf engineEngine;
 
 // output mix interfaces
-static SLObjectItf outputMixObject = NULL;
+static SLObjectItf outputMixObject = nullptr;
 
 // buffer queue player interfaces
-static SLObjectItf bqPlayerObject = NULL;
+static SLObjectItf bqPlayerObject = nullptr;
 static SLPlayItf bqPlayerPlay;
 static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
 static SLMuteSoloItf bqPlayerMuteSolo;
@@ -89,7 +89,7 @@
 }
 
 bool hasPlayer() {
-    return (engineObject != NULL && bqPlayerObject != NULL);
+    return (engineObject != nullptr && bqPlayerObject != nullptr);
 }
 
 // create the engine and output mix objects
@@ -97,7 +97,7 @@
     SLresult result;
 
     // create engine
-    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
+    result = slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
     if (result != SL_RESULT_SUCCESS) {
         ALOGE("slCreateEngine failed with result %d", result);
         return false;
@@ -121,7 +121,7 @@
     (void)result;
 
     // create output mix
-    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
+    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, nullptr, nullptr);
     if (result != SL_RESULT_SUCCESS) {
         ALOGE("sl engine CreateOutputMix failed with result %d", result);
         return false;
@@ -173,7 +173,7 @@
 
     // configure audio sink
     SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
-    SLDataSink audioSnk = {&loc_outmix, NULL};
+    SLDataSink audioSnk = {&loc_outmix, nullptr};
 
     // create audio player
     const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME, SL_IID_ANDROIDCONFIGURATION};
@@ -236,7 +236,7 @@
     (void)result;
 
     // register callback on the buffer queue
-    result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
+    result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, nullptr);
     if (result != SL_RESULT_SUCCESS) {
         ALOGE("sl bqPlayerBufferQueue RegisterCallback failed with result %d", result);
         return false;
@@ -261,7 +261,7 @@
                   const uint8_t** oSoundBuf, unsigned* oSoundBufSize) {
     *oSoundBuf = clipBuf;
     *oSoundBufSize = clipBufSize;
-    *oChunkFormat = NULL;
+    *oChunkFormat = nullptr;
     const RiffWaveHeader* wavHeader = (const RiffWaveHeader*)*oSoundBuf;
     if (*oSoundBufSize < sizeof(*wavHeader) || (wavHeader->riff_id != ID_RIFF) ||
         (wavHeader->wave_id != ID_WAVE)) {
@@ -303,7 +303,7 @@
         }
     }
 
-    if (*oChunkFormat == NULL) {
+    if (*oChunkFormat == nullptr) {
         ALOGE("format not found in WAV file");
         return false;
     }
@@ -435,7 +435,7 @@
 
     SLresult result;
 
-    if (NULL != bqPlayerPlay) {
+    if (nullptr != bqPlayerPlay) {
         // set the player's state
         result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay,
             isPlaying ? SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_STOPPED);
@@ -445,28 +445,28 @@
 
 void destroy() {
     // destroy buffer queue audio player object, and invalidate all associated interfaces
-    if (bqPlayerObject != NULL) {
+    if (bqPlayerObject != nullptr) {
         CHATTY("destroying audio player");
         (*bqPlayerObject)->Destroy(bqPlayerObject);
-        bqPlayerObject = NULL;
-        bqPlayerPlay = NULL;
-        bqPlayerBufferQueue = NULL;
-        bqPlayerMuteSolo = NULL;
-        bqPlayerVolume = NULL;
+        bqPlayerObject = nullptr;
+        bqPlayerPlay = nullptr;
+        bqPlayerBufferQueue = nullptr;
+        bqPlayerMuteSolo = nullptr;
+        bqPlayerVolume = nullptr;
     }
 
     // destroy output mix object, and invalidate all associated interfaces
-    if (outputMixObject != NULL) {
+    if (outputMixObject != nullptr) {
         (*outputMixObject)->Destroy(outputMixObject);
-        outputMixObject = NULL;
+        outputMixObject = nullptr;
     }
 
     // destroy engine object, and invalidate all associated interfaces
-    if (engineObject != NULL) {
+    if (engineObject != nullptr) {
         CHATTY("destroying audio engine");
         (*engineObject)->Destroy(engineObject);
-        engineObject = NULL;
-        engineEngine = NULL;
+        engineObject = nullptr;
+        engineEngine = nullptr;
     }
 }
 
diff --git a/cmds/bootanimation/iot/iotbootanimation_main.cpp b/cmds/bootanimation/iot/iotbootanimation_main.cpp
index 2a3d376..ae35297 100644
--- a/cmds/bootanimation/iot/iotbootanimation_main.cpp
+++ b/cmds/bootanimation/iot/iotbootanimation_main.cpp
@@ -60,7 +60,7 @@
 
         mBootAction = new BootAction();
         if (!mBootAction->init(library_path, mBootParameters)) {
-            mBootAction = NULL;
+            mBootAction = nullptr;
         }
     };
 
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index d757e46..18d56fa 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -84,6 +84,7 @@
         "-readability-magic-numbers",
     ],
     host_supported: true,
+    test_suites: ["general-tests"],
     srcs: [
         "tests/BinaryStreamVisitorTests.cpp",
         "tests/CommandLineOptionsTests.cpp",
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index 6d5fe7b..49470b4 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -269,12 +269,10 @@
 std::string ConcatPolicies(const std::vector<std::string>& policies) {
   std::string message;
   for (const std::string& policy : policies) {
-    if (message.empty()) {
-      message.append(policy);
-    } else {
-      message.append(policy);
+    if (!message.empty()) {
       message.append("|");
     }
+    message.append(policy);
   }
 
   return message;
diff --git a/cmds/incident/Android.bp b/cmds/incident/Android.bp
index 2a5ec5b..f56f101 100644
--- a/cmds/incident/Android.bp
+++ b/cmds/incident/Android.bp
@@ -29,6 +29,10 @@
         "libincident",
     ],
 
+    static_libs: [
+        "libplatformprotos",
+    ],
+
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/cmds/incident/main.cpp b/cmds/incident/main.cpp
index cdec6a0..93e592c 100644
--- a/cmds/incident/main.cpp
+++ b/cmds/incident/main.cpp
@@ -68,6 +68,7 @@
 StatusListener::onReportSectionStatus(int32_t section, int32_t status)
 {
     fprintf(stderr, "section %d status %d\n", section, status);
+    ALOGD("section %d status %d\n", section, status);
     return Status::ok();
 }
 
@@ -75,6 +76,7 @@
 StatusListener::onReportServiceStatus(const String16& service, int32_t status)
 {
     fprintf(stderr, "service '%s' status %d\n", String8(service).string(), status);
+    ALOGD("service '%s' status %d\n", String8(service).string(), status);
     return Status::ok();
 }
 
@@ -82,6 +84,7 @@
 StatusListener::onReportFinished()
 {
     fprintf(stderr, "done\n");
+    ALOGD("done\n");
     exit(0);
     return Status::ok();
 }
@@ -90,6 +93,7 @@
 StatusListener::onReportFailed()
 {
     fprintf(stderr, "failed\n");
+    ALOGD("failed\n");
     exit(1);
     return Status::ok();
 }
@@ -146,25 +150,50 @@
 
 // ================================================================================
 static int
-get_dest(const char* arg)
+get_privacy_policy(const char* arg)
 {
     if (strcmp(arg, "L") == 0
         || strcmp(arg, "LOCAL") == 0) {
-      return DEST_LOCAL;
+      return PRIVACY_POLICY_LOCAL;
     }
     if (strcmp(arg, "E") == 0
         || strcmp(arg, "EXPLICIT") == 0) {
-      return DEST_EXPLICIT;
+      return PRIVACY_POLICY_EXPLICIT;
     }
     if (strcmp(arg, "A") == 0
         || strcmp(arg, "AUTO") == 0
         || strcmp(arg, "AUTOMATIC") == 0) {
-      return DEST_AUTOMATIC;
+      return PRIVACY_POLICY_AUTOMATIC;
     }
     return -1; // return the default value
 }
 
 // ================================================================================
+static bool
+parse_receiver_arg(const string& arg, string* pkg, string* cls)
+{
+    if (arg.length() == 0) {
+        return true;
+    }
+    size_t slash = arg.find('/');
+    if (slash == string::npos) {
+        return false;
+    }
+    if (slash == 0 || slash == arg.length() - 1) {
+        return false;
+    }
+    if (arg.find('/', slash+1) != string::npos) {
+        return false;
+    }
+    pkg->assign(arg, 0, slash);
+    cls->assign(arg, slash+1);
+    if ((*cls)[0] == '.') {
+        *cls = (*pkg) + (*cls);
+    }
+    return true;
+}
+
+// ================================================================================
 static void
 usage(FILE* out)
 {
@@ -173,10 +202,13 @@
     fprintf(out, "Takes an incident report.\n");
     fprintf(out, "\n");
     fprintf(out, "OPTIONS\n");
+    fprintf(out, "  -l           list available sections\n");
+    fprintf(out, "  -p           privacy spec, LOCAL, EXPLICIT or AUTOMATIC. Default AUTOMATIC.\n");
+    fprintf(out, "\n");
+    fprintf(out, "and one of these destinations:\n");
     fprintf(out, "  -b           (default) print the report to stdout (in proto format)\n");
     fprintf(out, "  -d           send the report into dropbox\n");
-    fprintf(out, "  -l           list available sections\n");
-    fprintf(out, "  -p           privacy spec, LOCAL, EXPLICIT or AUTOMATIC\n");
+    fprintf(out, "  -s PKG/CLS   send broadcast to the broadcast receiver.\n");
     fprintf(out, "\n");
     fprintf(out, "  SECTION     the field numbers of the incident report fields to include\n");
     fprintf(out, "\n");
@@ -187,12 +219,13 @@
 {
     Status status;
     IncidentReportArgs args;
-    enum { DEST_DROPBOX, DEST_STDOUT } destination = DEST_STDOUT;
-    int dest = -1; // default
+    enum { DEST_UNSET, DEST_DROPBOX, DEST_STDOUT, DEST_BROADCAST } destination = DEST_UNSET;
+    int privacyPolicy = PRIVACY_POLICY_AUTOMATIC;
+    string receiverArg;
 
     // Parse the args
     int opt;
-    while ((opt = getopt(argc, argv, "bhdlp:")) != -1) {
+    while ((opt = getopt(argc, argv, "bhdlp:s:")) != -1) {
         switch (opt) {
             case 'h':
                 usage(stdout);
@@ -201,13 +234,29 @@
                 section_list(stdout);
                 return 0;
             case 'b':
+                if (!(destination == DEST_UNSET || destination == DEST_STDOUT)) {
+                    usage(stderr);
+                    return 1;
+                }
                 destination = DEST_STDOUT;
                 break;
             case 'd':
+                if (!(destination == DEST_UNSET || destination == DEST_DROPBOX)) {
+                    usage(stderr);
+                    return 1;
+                }
                 destination = DEST_DROPBOX;
                 break;
             case 'p':
-                dest = get_dest(optarg);
+                privacyPolicy = get_privacy_policy(optarg);
+                break;
+            case 's':
+                if (destination != DEST_UNSET) {
+                    usage(stderr);
+                    return 1;
+                }
+                destination = DEST_BROADCAST;
+                receiverArg = optarg;
                 break;
             default:
                 usage(stderr);
@@ -215,6 +264,17 @@
         }
     }
 
+    string pkg;
+    string cls;
+    if (parse_receiver_arg(receiverArg, &pkg, &cls)) {
+        args.setReceiverPkg(pkg);
+        args.setReceiverCls(cls);
+    } else {
+        fprintf(stderr, "badly formatted -s package/class option: %s\n\n", receiverArg.c_str());
+        usage(stderr);
+        return 1;
+    }
+
     if (optind == argc) {
         args.setAll(true);
     } else {
@@ -236,7 +296,7 @@
             }
         }
     }
-    args.setDest(dest);
+    args.setPrivacyPolicy(privacyPolicy);
 
     // Start the thread pool.
     sp<ProcessState> ps(ProcessState::self());
@@ -272,12 +332,17 @@
         //IPCThreadState::self()->joinThreadPool();
 
         while (true) {
-            int amt = splice(fds[0], NULL, STDOUT_FILENO, NULL, 4096, 0);
-            fprintf(stderr, "spliced %d bytes\n", amt);
+            uint8_t buf[4096];
+            ssize_t amt = TEMP_FAILURE_RETRY(read(fds[0], buf, sizeof(buf)));
             if (amt < 0) {
-                return errno;
+                break;
             } else if (amt == 0) {
-                return 0;
+                break;
+            }
+
+            ssize_t wamt = TEMP_FAILURE_RETRY(write(STDOUT_FILENO, buf, amt));
+            if (wamt != amt) {
+                return errno;
             }
         }
     } else {
diff --git a/cmds/incidentd/Android.bp b/cmds/incidentd/Android.bp
index 3dc1093..8f9a5f8 100644
--- a/cmds/incidentd/Android.bp
+++ b/cmds/incidentd/Android.bp
@@ -21,6 +21,7 @@
 
     srcs: [
         "src/**/*.cpp",
+        "src/**/*.proto",
         ":incidentd_section_list",
     ],
 
@@ -43,6 +44,10 @@
     local_include_dirs: ["src"],
     generated_headers: ["gen-platform-proto-constants"],
 
+    proto: {
+        type: "lite",
+    },
+
     shared_libs: [
         "libbase",
         "libbinder",
@@ -56,6 +61,18 @@
         "libprotobuf-cpp-lite",
     ],
 
+    static_libs: [
+        "libincidentcompanion",
+        "libplatformprotos",
+    ],
+
+    product_variables: {
+        debuggable: {
+            cflags: ["-DALLOW_RESTRICTED_SECTIONS=1"],
+        },
+    },
+
+
     init_rc: ["incidentd.rc"],
 }
 
@@ -72,6 +89,7 @@
         "-Wall",
         "-Wno-unused-variable",
         "-Wunused-parameter",
+        "-g",
 
         // Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed.
         "-Wno-error=implicit-fallthrough",
@@ -82,21 +100,26 @@
 
     srcs: [
         "tests/**/*.cpp",
-        "src/PrivacyBuffer.cpp",
+        "tests/**/*.proto",
         "src/FdBuffer.cpp",
         "src/Privacy.cpp",
+        "src/PrivacyFilter.cpp",
         "src/Reporter.cpp",
         "src/Section.cpp",
         "src/Throttler.cpp",
+        "src/WorkDirectory.cpp",
         "src/incidentd_util.cpp",
+        "src/proto_util.cpp",
         "src/report_directory.cpp",
+        "src/**/*.proto",
     ],
 
     data: ["testdata/**/*"],
 
     static_libs: [
         "libgmock",
-        "libplatformprotos",
+        "libincidentcompanion",
+        "libplatformprotos-test",
     ],
     shared_libs: [
         "libbase",
@@ -105,11 +128,19 @@
         "libdumputils",
         "libincident",
         "liblog",
-        "libprotobuf-cpp-lite",
+        "libprotobuf-cpp-full",
         "libprotoutil",
         "libservices",
         "libutils",
     ],
+
+    target: {
+        android: {
+            proto: {
+                type: "full",
+            },
+        },
+    },
 }
 
 genrule {
diff --git a/cmds/incidentd/src/Broadcaster.cpp b/cmds/incidentd/src/Broadcaster.cpp
new file mode 100644
index 0000000..63464f2
--- /dev/null
+++ b/cmds/incidentd/src/Broadcaster.cpp
@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Log.h"
+
+#include "Broadcaster.h"
+
+#include "IncidentService.h"
+
+#include <android/os/DropBoxManager.h>
+#include <binder/IServiceManager.h>
+#include <thread>
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using android::os::IIncidentCompanion;
+using binder::Status;
+
+// ============================================================
+Broadcaster::ConsentListener::ConsentListener(const sp<Broadcaster>& broadcaster,
+        const ReportId& reportId)
+    :mBroadcaster(broadcaster),
+     mId(reportId) {
+}
+
+Broadcaster::ConsentListener::~ConsentListener() {
+}
+
+Status Broadcaster::ConsentListener::onReportApproved() {
+    mBroadcaster->report_approved(mId);
+    return Status::ok();
+}
+
+Status Broadcaster::ConsentListener::onReportDenied() {
+    mBroadcaster->report_denied(mId);
+    return Status::ok();
+}
+
+// ============================================================
+Broadcaster::ReportId::ReportId()
+    :id(),
+     pkg(),
+     cls() {
+}
+
+Broadcaster::ReportId::ReportId(const ReportId& that)
+    :id(that.id),
+     pkg(that.pkg),
+     cls(that.cls) {
+}
+
+Broadcaster::ReportId::ReportId(const string& i, const string& p, const string& c)
+    :id(i),
+     pkg(p),
+     cls(c) {
+}
+
+Broadcaster::ReportId::~ReportId() {
+}
+
+bool Broadcaster::ReportId::operator<(const ReportId& that) const {
+    if (id < that.id) {
+        return true;
+    }
+    if (id > that.id) {
+        return false;
+    }
+    if (pkg < that.pkg) {
+        return true;
+    }
+    if (pkg > that.pkg) {
+        return false;
+    }
+    if (cls < that.cls) {
+        return true;
+    }
+    return false;
+}
+
+// ============================================================
+Broadcaster::ReportStatus::ReportStatus()
+    :approval_sent(false),
+     ready_sent(false),
+     listener(nullptr) {
+}
+
+Broadcaster::ReportStatus::ReportStatus(const ReportStatus& that)
+    :approval_sent(that.approval_sent),
+     ready_sent(that.ready_sent),
+     listener(that.listener) {
+}
+
+Broadcaster::ReportStatus::~ReportStatus() {
+}
+
+// ============================================================
+Broadcaster::Broadcaster(const sp<WorkDirectory>& workDirectory)
+        :mReportHandler(),
+         mWorkDirectory(workDirectory) {
+}
+
+void Broadcaster::setHandler(const sp<ReportHandler>& handler) {
+    mReportHandler = handler;
+}
+
+void Broadcaster::reset() {
+    unique_lock<mutex> lock(mLock);
+    mLastSent = 0;
+    mHistory.clear();
+    // Could cancel the listeners, but this happens when
+    // the system process crashes, so don't bother.
+}
+
+void Broadcaster::clearBroadcasts(const string& pkg, const string& cls, const string& id) {
+    unique_lock<mutex> lock(mLock);
+
+    map<ReportId,ReportStatus>::const_iterator found = mHistory.find(ReportId(id, pkg, cls));
+    if (found != mHistory.end()) {
+        if (found->second.listener != nullptr) {
+            sp<IIncidentCompanion> ics = get_incident_companion();
+            if (ics != nullptr) {
+                ics->cancelAuthorization(found->second.listener);
+            }
+        }
+        mHistory.erase(found);
+    }
+}
+
+void Broadcaster::clearPackageBroadcasts(const string& pkg) {
+    unique_lock<mutex> lock(mLock);
+
+    map<ReportId,ReportStatus>::iterator it = mHistory.begin();
+    while (it != mHistory.end()) {
+        if (it->first.pkg == pkg) {
+            if (it->second.listener != nullptr) {
+                sp<IIncidentCompanion> ics = get_incident_companion();
+                if (ics != nullptr) {
+                    ics->cancelAuthorization(it->second.listener);
+                }
+            }
+            it = mHistory.erase(it);
+        } else {
+            it++;
+        }
+    }
+}
+
+Broadcaster::broadcast_status_t Broadcaster::sendBroadcasts() {
+    int err;
+    int64_t lastSent = get_last_sent();
+
+    vector<sp<ReportFile>> files;
+    mWorkDirectory->getReports(&files, 0); //lastSent);
+
+    // Don't send multiple broadcasts to the same receiver.
+    set<ReportId> reportReadyBroadcasts;
+
+    for (const sp<ReportFile>& file: files) {
+        err = file->loadEnvelope();
+        if (err != NO_ERROR) {
+            ALOGW("Error (%s) loading envelope from %s", strerror(-err),
+                    file->getEnvelopeFileName().c_str());
+            continue;
+        }
+
+        const ReportFileProto& envelope = file->getEnvelope();
+
+        if (!envelope.completed()) {
+            ALOGI("Incident report not completed skipping it: %s",
+                    file->getEnvelopeFileName().c_str());
+            continue;
+        }
+
+        // When one of the broadcast functions in this loop fails, it's almost
+        // certainly because the system process is crashing or has crashed.  Rather
+        // than continuing to pound on the system process and potentially make things
+        // worse, we bail right away, return BROADCASTS_BACKOFF, and we will try
+        // again later.  In the meantime, if the system process did crash, it might
+        // clear out mHistory, which means we'll be back here again to send the
+        // backlog.
+        size_t reportCount = envelope.report_size();
+        bool hasApprovalPending = false;
+        for (int reportIndex = 0; reportIndex < reportCount; reportIndex++) {
+
+            const ReportFileProto_Report& report = envelope.report(reportIndex);
+            status_t err;
+            if (report.privacy_policy() == PRIVACY_POLICY_AUTOMATIC || report.share_approved()) {
+                // It's privacy policy is AUTO, or it's been approved,
+                // so send the actual broadcast.
+                if (!was_ready_sent(file->getId(), report.pkg(), report.cls())) {
+                    if (report.pkg() == DROPBOX_SENTINEL.getPackageName()
+                            && report.cls() == DROPBOX_SENTINEL.getClassName()) {
+                        IncidentReportArgs args;
+                        get_args_from_report(&args, report);
+                        err = send_to_dropbox(file, args);
+                        if (err != NO_ERROR) {
+                            return BROADCASTS_BACKOFF;
+                        }
+                    } else {
+                        reportReadyBroadcasts.insert(ReportId(file->getId(), report.pkg(),
+                                    report.cls()));
+                    }
+                }
+            } else {
+                // It's not approved yet, so send the approval.
+                if (!was_approval_sent(file->getId(), report.pkg(), report.cls())) {
+                    err = send_approval_broadcasts(file->getId(), report.pkg(), report.cls());
+                    if (err != NO_ERROR) {
+                        return BROADCASTS_BACKOFF;
+                    }
+                    hasApprovalPending = true;
+                }
+            }
+        }
+
+        lastSent = file->getTimestampNs();
+        if (!hasApprovalPending) {
+            set_last_sent(lastSent);
+        }
+    }
+
+    for (const ReportId& report: reportReadyBroadcasts) {
+        err = send_report_ready_broadcasts(report.id, report.pkg, report.cls);
+        if (err != NO_ERROR) {
+            return BROADCASTS_BACKOFF;
+        }
+    }
+
+    return mWorkDirectory->hasMore(lastSent) ? BROADCASTS_REPEAT : BROADCASTS_FINISHED;
+}
+
+void Broadcaster::set_last_sent(int64_t timestamp) {
+    unique_lock<mutex> lock(mLock);
+    mLastSent = timestamp;
+}
+
+int64_t Broadcaster::get_last_sent() {
+    unique_lock<mutex> lock(mLock);
+    return mLastSent;
+}
+
+/*
+void Broadcaster::printReportStatuses() const {
+    ALOGD("mHistory {");
+    for (map<ReportId,ReportStatus>::const_iterator it = mHistory.begin();
+            it != mHistory.end(); it++) {
+        ALOGD("   [%s %s] --> [%d %d]", it->first.id.c_str(), it->first.pkg.c_str(),
+                it->second.approval_sent, it->second.ready_sent);
+    }
+    ALOGD("}");
+}
+*/
+
+bool Broadcaster::was_approval_sent(const string& id, const string& pkg, const string& cls) {
+    unique_lock<mutex> lock(mLock);
+    map<ReportId,ReportStatus>::const_iterator found = mHistory.find(ReportId(id, pkg, cls));
+    if (found != mHistory.end()) {
+        return found->second.approval_sent;
+    }
+    return false;
+}
+
+void Broadcaster::set_approval_sent(const string& id, const string& pkg, const string& cls,
+        const sp<ConsentListener>& listener) {
+    unique_lock<mutex> lock(mLock);
+    ReportStatus& reportStatus = mHistory[ReportId(id, pkg, cls)];
+    reportStatus.approval_sent = true;
+    reportStatus.listener = listener;
+}
+
+bool Broadcaster::was_ready_sent(const string& id, const string& pkg, const string& cls) {
+    unique_lock<mutex> lock(mLock);
+    map<ReportId,ReportStatus>::const_iterator found = mHistory.find(ReportId(id, pkg, cls));
+    if (found != mHistory.end()) {
+        return found->second.ready_sent;
+    }
+    return false;
+}
+
+void Broadcaster::set_ready_sent(const string& id, const string& pkg, const string& cls) {
+    unique_lock<mutex> lock(mLock);
+    mHistory[ReportId(id, pkg, cls)].ready_sent = true;
+}
+
+status_t Broadcaster::send_approval_broadcasts(const string& id, const string& pkg,
+        const string& cls) {
+    sp<IIncidentCompanion> ics = get_incident_companion();
+    if (ics == nullptr) {
+        return NAME_NOT_FOUND;
+    }
+
+    sp<ConsentListener> listener = new ConsentListener(this, ReportId(id, pkg, cls));
+
+    ALOGI("send_approval_broadcasts for %s %s/%s", id.c_str(), pkg.c_str(), cls.c_str());
+
+    Status status = ics->authorizeReport(0, String16(pkg.c_str()),
+            String16(cls.c_str()), String16(id.c_str()), 0, listener);
+
+    if (!status.isOk()) {
+        // authorizeReport is oneway, so any error is a transaction error.
+        return status.transactionError();
+    }
+
+    set_approval_sent(id, pkg, cls, listener);
+
+    return NO_ERROR;
+}
+
+void Broadcaster::report_approved(const ReportId& reportId) {
+    status_t err;
+
+    // Kick off broadcaster to do send the ready broadcasts.
+    ALOGI("The user approved the report, so kicking off another broadcast pass. %s %s/%s",
+            reportId.id.c_str(), reportId.pkg.c_str(), reportId.cls.c_str());
+    sp<ReportFile> file = mWorkDirectory->getReport(reportId.pkg, reportId.cls, reportId.id,
+            nullptr);
+    if (file != nullptr) {
+        err = file->loadEnvelope();
+        if (err != NO_ERROR) {
+            return;
+        }
+
+        err = file->markApproved(reportId.pkg, reportId.cls);
+        if (err != NO_ERROR) {
+            ALOGI("Couldn't find report that was just approved: %s %s/%s",
+                    reportId.id.c_str(), reportId.pkg.c_str(), reportId.cls.c_str());
+            return;
+        }
+
+        file->saveEnvelope();
+        if (err != NO_ERROR) {
+            return;
+        }
+    }
+    mReportHandler->scheduleSendBacklog();
+}
+
+void Broadcaster::report_denied(const ReportId& reportId) {
+    // The user didn't approve the report, so remove it from the WorkDirectory.
+    ALOGI("The user denied the report, so deleting it. %s %s/%s",
+            reportId.id.c_str(), reportId.pkg.c_str(), reportId.cls.c_str());
+    sp<ReportFile> file = mWorkDirectory->getReport(reportId.pkg, reportId.cls, reportId.id,
+            nullptr);
+    if (file != nullptr) {
+        mWorkDirectory->commit(file, reportId.pkg, reportId.cls);
+    }
+}
+
+status_t Broadcaster::send_report_ready_broadcasts(const string& id, const string& pkg,
+        const string& cls) {
+    sp<IIncidentCompanion> ics = get_incident_companion();
+    if (ics == nullptr) {
+        return NAME_NOT_FOUND;
+    }
+
+    ALOGI("send_report_ready_broadcasts for %s %s/%s", id.c_str(), pkg.c_str(), cls.c_str());
+
+    Status status = ics->sendReportReadyBroadcast(String16(pkg.c_str()), String16(cls.c_str()));
+
+    if (!status.isOk()) {
+        // sendReportReadyBroadcast is oneway, so any error is a transaction error.
+        return status.transactionError();
+    }
+
+    set_ready_sent(id, pkg, cls);
+
+    return NO_ERROR;
+}
+
+status_t Broadcaster::send_to_dropbox(const sp<ReportFile>& file,
+        const IncidentReportArgs& args) {
+    status_t err;
+
+    sp<DropBoxManager> dropbox = new DropBoxManager();
+    if (dropbox == nullptr) {
+        ALOGW("Can't reach dropbox now, so we won't be able to write the incident report to there");
+        return NO_ERROR;
+    }
+
+    int fds[2];
+    if (pipe(fds) != 0) {
+        ALOGW("Error opening pipe to filter incident report: %s", file->getDataFileName().c_str());
+        return NO_ERROR;
+    }
+
+    int readFd = fds[0];
+    int writeFd = fds[1];
+
+    // spawn a thread to write the data. Release the writeFd ownership to the thread.
+    thread th([file, writeFd, args]() { file->startFilteringData(writeFd, args); });
+
+    th.detach();
+
+    // Takes ownership of readFd.
+    Status status = dropbox->addFile(String16("incident"), readFd, 0);
+    if (!status.isOk()) {
+        // TODO: This may or may not leak the readFd, depending on where it failed.
+        // Not sure how to fix this given the dropbox API.
+        ALOGW("Error sending incident report to dropbox.");
+        return -errno;
+    }
+
+    // On successful write, tell the working directory that this file is done.
+    mWorkDirectory->commit(file, DROPBOX_SENTINEL.getPackageName(),
+            DROPBOX_SENTINEL.getClassName());
+
+    // Don't need to call set_ready_sent, because we just removed it from the ReportFile,
+    // so we'll never hear about it again.
+
+    return NO_ERROR;
+}
+
+sp<IIncidentCompanion> Broadcaster::get_incident_companion() {
+    sp<IBinder> binder = defaultServiceManager()->getService(String16("incidentcompanion"));
+    if (binder == nullptr) {
+        ALOGI("Can not find IIncidentCompanion service to send broadcast. Will try again later.");
+        return nullptr;
+    }
+
+    sp<IIncidentCompanion> ics = interface_cast<IIncidentCompanion>(binder);
+    if (ics == nullptr) {
+        ALOGI("The incidentcompanion service is not an IIncidentCompanion. Will try again later.");
+        return nullptr;
+    }
+
+    return ics;
+}
+
+}  // namespace incidentd
+}  // namespace os
+}  // namespace android
+
+
diff --git a/cmds/incidentd/src/Broadcaster.h b/cmds/incidentd/src/Broadcaster.h
new file mode 100644
index 0000000..9330297
--- /dev/null
+++ b/cmds/incidentd/src/Broadcaster.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "WorkDirectory.h"
+
+#include <android/os/BnIncidentAuthListener.h>
+#include <android/os/IIncidentCompanion.h>
+#include <frameworks/base/cmds/incidentd/src/report_file.pb.h>
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using android::binder::Status;
+using android::os::BnIncidentAuthListener;
+using android::os::IIncidentCompanion;
+
+class ReportHandler;
+
+class Broadcaster : public virtual RefBase {
+public:
+    enum broadcast_status_t {
+        BROADCASTS_FINISHED = 0,
+        BROADCASTS_REPEAT = 1,
+        BROADCASTS_BACKOFF = 2
+    };
+
+    Broadcaster(const sp<WorkDirectory>& workDirectory);
+
+    void setHandler(const sp<ReportHandler>& handler);
+
+    /**
+     * Reset the beginning timestamp for broadcasts.  Call this when
+     * the system_server restarts.
+     */
+    void reset();
+
+    /**
+     * Remove the history record for the broadcasts, including pending authorizations
+     * if necessary.
+     */
+    void clearBroadcasts(const string& pkg, const string& cls, const string& id);
+    void clearPackageBroadcasts(const string& pkg);
+
+    /**
+     * Send whichever broadcasts have been pending.
+     */
+    broadcast_status_t sendBroadcasts();
+
+private:
+    struct ReportId {
+        ReportId();
+        ReportId(const ReportId& that);
+        ReportId(const string& i, const string& p, const string& c);
+        ~ReportId();
+
+        bool operator<(const ReportId& that) const;
+
+        string id;
+        string pkg;
+        string cls;
+    };
+
+    class ConsentListener : public BnIncidentAuthListener {
+      public:
+        ConsentListener(const sp<Broadcaster>& broadcaster, const ReportId& reportId);
+        virtual ~ConsentListener();
+        virtual Status onReportApproved();
+        virtual Status onReportDenied();
+      private:
+        sp<Broadcaster> mBroadcaster;
+        ReportId mId;
+    };
+    
+    struct ReportStatus {
+        ReportStatus();
+        ReportStatus(const ReportStatus& that);
+        ~ReportStatus();
+
+        bool approval_sent;
+        bool ready_sent;
+        sp<ConsentListener> listener;
+    };
+
+    sp<ReportHandler> mReportHandler;
+    sp<WorkDirectory> mWorkDirectory;
+
+    // protected by mLock
+    mutex mLock;
+    map<ReportId,ReportStatus> mHistory; // what we sent so we don't send it again
+    int64_t mLastSent;
+
+    void set_last_sent(int64_t timestamp);
+    int64_t get_last_sent();
+    void print_report_statuses() const;
+    status_t send_approval_broadcasts(const string& id, const string& pkg, const string& cls);
+    void report_approved(const ReportId& reportId);
+    void report_denied(const ReportId& reportId);
+    status_t send_report_ready_broadcasts(const string& id, const string& pkg, const string& cls);
+    status_t send_to_dropbox(const sp<ReportFile>& file, const IncidentReportArgs& args);
+    bool was_approval_sent(const string& id, const string& pkg, const string& cls);
+    void set_approval_sent(const string& id, const string& pkg, const string& cls,
+            const sp<ConsentListener>& listener);
+    bool was_ready_sent(const string& id, const string& pkg, const string& cls);
+    void set_ready_sent(const string& id, const string& pkg, const string& cls);
+    sp<IIncidentCompanion> get_incident_companion();
+};
+
+
+}  // namespace incidentd
+}  // namespace os
+}  // namespace android
+
diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp
index 04819ec..b46c9e3 100644
--- a/cmds/incidentd/src/FdBuffer.cpp
+++ b/cmds/incidentd/src/FdBuffer.cpp
@@ -31,12 +31,18 @@
 namespace incidentd {
 
 const ssize_t BUFFER_SIZE = 16 * 1024;  // 16 KB
-const ssize_t MAX_BUFFER_COUNT = 256;   // 4 MB max
+const ssize_t MAX_BUFFER_COUNT = 1536;   // 24 MB max
 
 FdBuffer::FdBuffer()
-    : mBuffer(BUFFER_SIZE), mStartTime(-1), mFinishTime(-1), mTimedOut(false), mTruncated(false) {}
+        :mBuffer(new EncodedBuffer(BUFFER_SIZE)),
+         mStartTime(-1),
+         mFinishTime(-1),
+         mTimedOut(false),
+         mTruncated(false) {
+}
 
-FdBuffer::~FdBuffer() {}
+FdBuffer::~FdBuffer() {
+}
 
 status_t FdBuffer::read(int fd, int64_t timeout) {
     struct pollfd pfds = {.fd = fd, .events = POLLIN};
@@ -45,12 +51,12 @@
     fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
 
     while (true) {
-        if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
+        if (mBuffer->size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
             mTruncated = true;
             VLOG("Truncating data");
             break;
         }
-        if (mBuffer.writeBuffer() == NULL) {
+        if (mBuffer->writeBuffer() == NULL) {
             VLOG("No memory");
             return NO_MEMORY;
         }
@@ -76,7 +82,7 @@
                 return errno != 0 ? -errno : UNKNOWN_ERROR;
             } else {
                 ssize_t amt = TEMP_FAILURE_RETRY(
-                        ::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite()));
+                        ::read(fd, mBuffer->writeBuffer(), mBuffer->currentToWrite()));
                 if (amt < 0) {
                     if (errno == EAGAIN || errno == EWOULDBLOCK) {
                         continue;
@@ -88,7 +94,7 @@
                     VLOG("Reached EOF of fd=%d", fd);
                     break;
                 }
-                mBuffer.wp()->move(amt);
+                mBuffer->wp()->move(amt);
             }
         }
     }
@@ -100,28 +106,28 @@
     mStartTime = uptimeMillis();
 
     while (true) {
-        if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
+        if (mBuffer->size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
             // Don't let it get too big.
             mTruncated = true;
             VLOG("Truncating data");
             break;
         }
-        if (mBuffer.writeBuffer() == NULL) {
+        if (mBuffer->writeBuffer() == NULL) {
             VLOG("No memory");
             return NO_MEMORY;
         }
 
         ssize_t amt =
-                TEMP_FAILURE_RETRY(::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite()));
+                TEMP_FAILURE_RETRY(::read(fd, mBuffer->writeBuffer(), mBuffer->currentToWrite()));
         if (amt < 0) {
             VLOG("Fail to read %d: %s", fd, strerror(errno));
             return -errno;
         } else if (amt == 0) {
-            VLOG("Done reading %zu bytes", mBuffer.size());
+            VLOG("Done reading %zu bytes", mBuffer->size());
             // We're done.
             break;
         }
-        mBuffer.wp()->move(amt);
+        mBuffer->wp()->move(amt);
     }
 
     mFinishTime = uptimeMillis();
@@ -150,12 +156,12 @@
 
     // This is the buffer used to store processed data
     while (true) {
-        if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
+        if (mBuffer->size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
             VLOG("Truncating data");
             mTruncated = true;
             break;
         }
-        if (mBuffer.writeBuffer() == NULL) {
+        if (mBuffer->writeBuffer() == NULL) {
             VLOG("No memory");
             return NO_MEMORY;
         }
@@ -248,7 +254,7 @@
 
         // read from parsing process
         ssize_t amt = TEMP_FAILURE_RETRY(
-                ::read(fromFd.get(), mBuffer.writeBuffer(), mBuffer.currentToWrite()));
+                ::read(fromFd.get(), mBuffer->writeBuffer(), mBuffer->currentToWrite()));
         if (amt < 0) {
             if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
                 VLOG("Fail to read fromFd %d: %s", fromFd.get(), strerror(errno));
@@ -258,7 +264,7 @@
             VLOG("Reached EOF of fromFd %d", fromFd.get());
             break;
         } else {
-            mBuffer.wp()->move(amt);
+            mBuffer->wp()->move(amt);
         }
     }
 
@@ -266,9 +272,25 @@
     return NO_ERROR;
 }
 
-size_t FdBuffer::size() const { return mBuffer.size(); }
+status_t FdBuffer::write(uint8_t const* buf, size_t size) {
+    return mBuffer->writeRaw(buf, size);
+}
 
-EncodedBuffer::iterator FdBuffer::data() const { return mBuffer.begin(); }
+status_t FdBuffer::write(const sp<ProtoReader>& reader) {
+    return mBuffer->writeRaw(reader);
+}
+
+status_t FdBuffer::write(const sp<ProtoReader>& reader, size_t size) {
+    return mBuffer->writeRaw(reader, size);
+}
+
+size_t FdBuffer::size() const {
+    return mBuffer->size();
+}
+
+sp<EncodedBuffer> FdBuffer::data() const {
+    return mBuffer;
+}
 
 }  // namespace incidentd
 }  // namespace os
diff --git a/cmds/incidentd/src/FdBuffer.h b/cmds/incidentd/src/FdBuffer.h
index 20deefd..a349360 100644
--- a/cmds/incidentd/src/FdBuffer.h
+++ b/cmds/incidentd/src/FdBuffer.h
@@ -64,6 +64,21 @@
                                        const bool isSysfs = false);
 
     /**
+     * Write by hand into the buffer.
+     */
+    status_t write(uint8_t const* buf, size_t size);
+
+    /**
+     * Write all the data from a ProtoReader into our internal buffer.
+     */
+    status_t write(const sp<ProtoReader>& data);
+
+    /**
+     * Write size bytes of data from a ProtoReader into our internal buffer.
+     */
+    status_t write(const sp<ProtoReader>& data, size_t size);
+
+    /**
      * Whether we timed out.
      */
     bool timedOut() const { return mTimedOut; }
@@ -89,17 +104,12 @@
     int64_t durationMs() const { return mFinishTime - mStartTime; }
 
     /**
-     * Reader API for data stored in FdBuffer
+     * Get the EncodedBuffer inside.
      */
-    EncodedBuffer::iterator data() const;
-
-    /**
-     * Return the internal buffer, don't call unless you are familiar with EncodedBuffer.
-     */
-    EncodedBuffer* getInternalBuffer() { return &mBuffer; }
+    sp<EncodedBuffer> data() const;
 
 private:
-    EncodedBuffer mBuffer;
+    sp<EncodedBuffer> mBuffer;
     int64_t mStartTime;
     int64_t mFinishTime;
     bool mTimedOut;
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index f8fb4a6..b4021d1 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -19,7 +19,7 @@
 #include "IncidentService.h"
 
 #include "FdBuffer.h"
-#include "PrivacyBuffer.h"
+#include "PrivacyFilter.h"
 #include "Reporter.h"
 #include "incidentd_util.h"
 #include "section_list.h"
@@ -32,12 +32,16 @@
 #include <log/log.h>
 #include <private/android_filesystem_config.h>
 #include <utils/Looper.h>
+#include <thread>
 
 #include <unistd.h>
 
-enum { WHAT_RUN_REPORT = 1, WHAT_SEND_BACKLOG_TO_DROPBOX = 2 };
+enum {
+    WHAT_TAKE_REPORT = 1,
+    WHAT_SEND_BROADCASTS = 2
+};
 
-#define DEFAULT_BACKLOG_DELAY_NS (1000000000LL)
+#define DEFAULT_DELAY_NS (1000000000LL)
 
 #define DEFAULT_BYTES_SIZE_LIMIT (20 * 1024 * 1024)        // 20MB
 #define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000)  // 1 Day
@@ -53,6 +57,7 @@
 namespace os {
 namespace incidentd {
 
+String16 const APPROVE_INCIDENT_REPORTS("android.permission.APPROVE_INCIDENT_REPORTS");
 String16 const DUMP_PERMISSION("android.permission.DUMP");
 String16 const USAGE_STATS_PERMISSION("android.permission.PACKAGE_USAGE_STATS");
 
@@ -60,7 +65,14 @@
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     pid_t callingPid = IPCThreadState::self()->getCallingPid();
     if (callingUid == AID_ROOT || callingUid == AID_SHELL) {
-        // root doesn't have permission.DUMP if don't do this!
+        // Root and shell are ok.
+        return Status::ok();
+    }
+
+    if (checkCallingPermission(APPROVE_INCIDENT_REPORTS)) {
+        // Permission controller (this is a singleton permission that is always granted
+        // exactly for PermissionController) is allowed to access incident reports
+        // so it can show the user info about what they are approving.
         return Status::ok();
     }
 
@@ -81,8 +93,8 @@
     }
 
     // checking calling request uid permission.
-    switch (args.dest()) {
-        case DEST_LOCAL:
+    switch (args.getPrivacyPolicy()) {
+        case PRIVACY_POLICY_LOCAL:
             if (callingUid != AID_SHELL && callingUid != AID_ROOT) {
                 ALOGW("Calling pid %d and uid %d does not have permission to get local data.",
                       callingPid, callingUid);
@@ -91,7 +103,7 @@
                         "Calling process does not have permission to get local data.");
             }
             break;
-        case DEST_EXPLICIT:
+        case PRIVACY_POLICY_EXPLICIT:
             if (callingUid != AID_SHELL && callingUid != AID_ROOT && callingUid != AID_STATSD &&
                     callingUid != AID_SYSTEM) {
                 ALOGW("Calling pid %d and uid %d does not have permission to get explicit data.",
@@ -105,78 +117,80 @@
     return Status::ok();
 }
 
-// ================================================================================
-ReportRequestQueue::ReportRequestQueue() {}
-
-ReportRequestQueue::~ReportRequestQueue() {}
-
-void ReportRequestQueue::addRequest(const sp<ReportRequest>& request) {
-    unique_lock<mutex> lock(mLock);
-    mQueue.push_back(request);
-}
-
-sp<ReportRequest> ReportRequestQueue::getNextRequest() {
-    unique_lock<mutex> lock(mLock);
-    if (mQueue.empty()) {
-        return NULL;
-    } else {
-        sp<ReportRequest> front(mQueue.front());
-        mQueue.pop_front();
-        return front;
-    }
+static string build_uri(const string& pkg, const string& cls, const string& id) {
+    return "content://android.os.IncidentManager/pending?pkg="
+        + pkg + "&receiver=" + cls + "&r=" + id;
 }
 
 // ================================================================================
-ReportHandler::ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
-                             const sp<Throttler>& throttler)
-    : mBacklogDelay(DEFAULT_BACKLOG_DELAY_NS),
-      mHandlerLooper(handlerLooper),
-      mQueue(queue),
-      mThrottler(throttler) {}
+ReportHandler::ReportHandler(const sp<WorkDirectory>& workDirectory,
+            const sp<Broadcaster>& broadcaster, const sp<Looper>& handlerLooper,
+            const sp<Throttler>& throttler)
+        :mLock(),
+         mWorkDirectory(workDirectory),
+         mBroadcaster(broadcaster),
+         mHandlerLooper(handlerLooper),
+         mBacklogDelay(DEFAULT_DELAY_NS),
+         mThrottler(throttler),
+         mBatch(new ReportBatch()) {
+}
 
-ReportHandler::~ReportHandler() {}
+ReportHandler::~ReportHandler() {
+}
 
 void ReportHandler::handleMessage(const Message& message) {
     switch (message.what) {
-        case WHAT_RUN_REPORT:
-            run_report();
+        case WHAT_TAKE_REPORT:
+            take_report();
             break;
-        case WHAT_SEND_BACKLOG_TO_DROPBOX:
-            send_backlog_to_dropbox();
+        case WHAT_SEND_BROADCASTS:
+            send_broadcasts();
             break;
     }
 }
 
-void ReportHandler::scheduleRunReport(const sp<ReportRequest>& request) {
-    mQueue->addRequest(request);
-    mHandlerLooper->removeMessages(this, WHAT_RUN_REPORT);
-    mHandlerLooper->sendMessage(this, Message(WHAT_RUN_REPORT));
+void ReportHandler::schedulePersistedReport(const IncidentReportArgs& args) {
+    mBatch->addPersistedReport(args);
+    mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
+    mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
 }
 
-void ReportHandler::scheduleSendBacklogToDropbox() {
+void ReportHandler::scheduleStreamingReport(const IncidentReportArgs& args,
+        const sp<IIncidentReportStatusListener>& listener, int streamFd) {
+    mBatch->addStreamingReport(args, listener, streamFd);
+    mHandlerLooper->removeMessages(this, WHAT_TAKE_REPORT);
+    mHandlerLooper->sendMessage(this, Message(WHAT_TAKE_REPORT));
+}
+
+void ReportHandler::scheduleSendBacklog() {
     unique_lock<mutex> lock(mLock);
-    mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
-    schedule_send_backlog_to_dropbox_locked();
+    mBacklogDelay = DEFAULT_DELAY_NS;
+    schedule_send_broadcasts_locked();
 }
 
-void ReportHandler::schedule_send_backlog_to_dropbox_locked() {
-    mHandlerLooper->removeMessages(this, WHAT_SEND_BACKLOG_TO_DROPBOX);
-    mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BACKLOG_TO_DROPBOX));
+void ReportHandler::schedule_send_broadcasts_locked() {
+    mHandlerLooper->removeMessages(this, WHAT_SEND_BROADCASTS);
+    mHandlerLooper->sendMessageDelayed(mBacklogDelay, this, Message(WHAT_SEND_BROADCASTS));
 }
 
-void ReportHandler::run_report() {
-    sp<Reporter> reporter = new Reporter();
-
-    // Merge all of the requests into one that has all of the
-    // requested fields.
-    while (true) {
-        sp<ReportRequest> request = mQueue->getNextRequest();
-        if (request == NULL) {
-            break;
-        }
-        reporter->batch.add(request);
+void ReportHandler::take_report() {
+    // Cycle the batch
+    sp<ReportBatch> batch;
+    {
+        unique_lock<mutex> lock(mLock);
+        batch = mBatch;
+        mBatch = new ReportBatch();
     }
 
+    if (batch->empty()) {
+        // Nothing to do.
+        return;
+    }
+
+    sp<Reporter> reporter = new Reporter(mWorkDirectory, batch);
+
+    // TODO: Do we really want to clear the reports if we throttle?  Should we only throttle
+    // requests going to dropbox?  How do we reconcile throttling with testing?
     if (mThrottler->shouldThrottle()) {
         ALOGW("RunReport got throttled.");
         return;
@@ -185,46 +199,76 @@
     // Take the report, which might take a while. More requests might queue
     // up while we're doing this, and we'll handle them in their next batch.
     // TODO: We should further rate-limit the reports to no more than N per time-period.
+    // TODO: Move this inside reporter.
     size_t reportByteSize = 0;
-    Reporter::run_report_status_t reportStatus = reporter->runReport(&reportByteSize);
+    reporter->runReport(&reportByteSize);
+
     mThrottler->addReportSize(reportByteSize);
-    if (reportStatus == Reporter::REPORT_NEEDS_DROPBOX) {
+
+    // Kick off the next steps, one of which is to send any new or otherwise remaining
+    // approvals, and one of which is to send any new or remaining broadcasts.
+    {
         unique_lock<mutex> lock(mLock);
-        schedule_send_backlog_to_dropbox_locked();
+        schedule_send_broadcasts_locked();
     }
 }
 
-void ReportHandler::send_backlog_to_dropbox() {
-    if (Reporter::upload_backlog() == Reporter::REPORT_NEEDS_DROPBOX) {
+void ReportHandler::send_broadcasts() {
+    Broadcaster::broadcast_status_t result = mBroadcaster->sendBroadcasts();
+    if (result == Broadcaster::BROADCASTS_FINISHED) {
+        // We're done.
+        unique_lock<mutex> lock(mLock);
+        mBacklogDelay = DEFAULT_DELAY_NS;
+    } else if (result == Broadcaster::BROADCASTS_REPEAT) {
+        // It worked, but there are more.
+        unique_lock<mutex> lock(mLock);
+        mBacklogDelay = DEFAULT_DELAY_NS;
+        schedule_send_broadcasts_locked();
+    } else if (result == Broadcaster::BROADCASTS_BACKOFF) {
         // There was a failure. Exponential backoff.
         unique_lock<mutex> lock(mLock);
         mBacklogDelay *= 2;
         ALOGI("Error sending to dropbox. Trying again in %lld minutes",
               (mBacklogDelay / (1000000000LL * 60)));
-        schedule_send_backlog_to_dropbox_locked();
-    } else {
-        mBacklogDelay = DEFAULT_BACKLOG_DELAY_NS;
+        schedule_send_broadcasts_locked();
     }
 }
 
 // ================================================================================
-IncidentService::IncidentService(const sp<Looper>& handlerLooper)
-    : mQueue(new ReportRequestQueue()),
-      mThrottler(new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS)) {
-    mHandler = new ReportHandler(handlerLooper, mQueue, mThrottler);
+IncidentService::IncidentService(const sp<Looper>& handlerLooper) {
+    mThrottler = new Throttler(DEFAULT_BYTES_SIZE_LIMIT, DEFAULT_REFACTORY_PERIOD_MS);
+    mWorkDirectory = new WorkDirectory();
+    mBroadcaster = new Broadcaster(mWorkDirectory);
+    mHandler = new ReportHandler(mWorkDirectory, mBroadcaster, handlerLooper,
+            mThrottler);
+    mBroadcaster->setHandler(mHandler);
 }
 
 IncidentService::~IncidentService() {}
 
 Status IncidentService::reportIncident(const IncidentReportArgs& args) {
-    ALOGI("reportIncident");
+    // TODO: Validate that the privacy policy is one of the real ones.
+    // If it isn't, clamp it to the next more restrictive real one.
 
+    // TODO: This function should reject the LOCAL privacy policy.
+    // Those have to stream.
+
+    // TODO: Check that the broadcast recevier has the proper permissions
+    // TODO: Maybe we should consider relaxing the permissions if it's going to
+    // dropbox, but definitely not if it's going to the broadcaster.
     Status status = checkIncidentPermissions(args);
     if (!status.isOk()) {
         return status;
     }
 
-    mHandler->scheduleRunReport(new ReportRequest(args, NULL, -1));
+    // If they didn't specify a component, use dropbox.
+    IncidentReportArgs argsCopy(args);
+    if (argsCopy.receiverPkg().length() == 0 && argsCopy.receiverCls().length() == 0) {
+        argsCopy.setReceiverPkg(DROPBOX_SENTINEL.getPackageName());
+        argsCopy.setReceiverCls(DROPBOX_SENTINEL.getClassName());
+    }
+
+    mHandler->schedulePersistedReport(argsCopy);
 
     return Status::ok();
 }
@@ -232,19 +276,29 @@
 Status IncidentService::reportIncidentToStream(const IncidentReportArgs& args,
                                                const sp<IIncidentReportStatusListener>& listener,
                                                const unique_fd& stream) {
-    ALOGI("reportIncidentToStream");
+    // TODO: Validate that the privacy policy is one of the real ones.
+    // If it isn't, clamp it to the next more restrictive real one.
 
-    Status status = checkIncidentPermissions(args);
+    // TODO: Only shell should be able to do a LOCAL privacy policy report.
+
+    // Streaming reports can not also be broadcast.
+    IncidentReportArgs argsCopy(args);
+    argsCopy.setReceiverPkg("");
+    argsCopy.setReceiverCls("");
+
+    Status status = checkIncidentPermissions(argsCopy);
     if (!status.isOk()) {
         return status;
     }
 
+
+    // The ReportRequest takes ownership of the fd, so we need to dup it.
     int fd = dup(stream.get());
     if (fd < 0) {
         return Status::fromStatusT(-errno);
     }
 
-    mHandler->scheduleRunReport(new ReportRequest(args, listener, fd));
+    mHandler->scheduleStreamingReport(argsCopy, listener, fd);
 
     return Status::ok();
 }
@@ -256,7 +310,96 @@
     }
 
     // When system_server is up and running, schedule the dropbox task to run.
-    mHandler->scheduleSendBacklogToDropbox();
+    mBroadcaster->reset();
+    mHandler->scheduleSendBacklog();
+
+    return Status::ok();
+}
+
+Status IncidentService::getIncidentReportList(const String16& pkg16, const String16& cls16,
+            vector<String16>* result) {
+    status_t err;
+    const string pkg(String8(pkg16).string());
+    const string cls(String8(cls16).string());
+
+    // List the reports
+    vector<sp<ReportFile>> all;
+    err = mWorkDirectory->getReports(&all, 0);
+    if (err != NO_ERROR) {
+        return Status::fromStatusT(err);
+    }
+
+    // Find the ones that match pkg and cls.
+    for (sp<ReportFile>& file: all) {
+        err = file->loadEnvelope();
+        if (err != NO_ERROR) {
+            continue;
+        }
+        const ReportFileProto& envelope = file->getEnvelope();
+        size_t reportCount = envelope.report_size();
+        for (int reportIndex = 0; reportIndex < reportCount; reportIndex++) {
+            const ReportFileProto_Report& report = envelope.report(reportIndex);
+            if (pkg == report.pkg() && cls == report.cls()) {
+                result->push_back(String16(build_uri(pkg, cls, file->getId()).c_str()));
+                break;
+            }
+        }
+    }
+
+    return Status::ok();
+}
+
+Status IncidentService::getIncidentReport(const String16& pkg16, const String16& cls16,
+            const String16& id16, IncidentManager::IncidentReport* result) {
+    status_t err;
+
+    const string pkg(String8(pkg16).string());
+    const string cls(String8(cls16).string());
+    const string id(String8(id16).string());
+
+    IncidentReportArgs args;
+    sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, &args);
+    if (file != nullptr) {
+        // Create pipe
+        int fds[2];
+        if (pipe(fds) != 0) {
+            ALOGW("Error opening pipe to filter incident report: %s",
+                  file->getDataFileName().c_str());
+            return Status::ok();
+        }
+        result->setTimestampNs(file->getTimestampNs());
+        result->setPrivacyPolicy(file->getEnvelope().privacy_policy());
+        result->takeFileDescriptor(fds[0]);
+        int writeFd = fds[1];
+        // spawn a thread to write the data. Release the writeFd ownership to the thread.
+        thread th([file, writeFd, args]() { file->startFilteringData(writeFd, args); });
+
+        th.detach();
+    }
+
+    return Status::ok();
+}
+
+Status IncidentService::deleteIncidentReports(const String16& pkg16, const String16& cls16,
+            const String16& id16) {
+    const string pkg(String8(pkg16).string());
+    const string cls(String8(cls16).string());
+    const string id(String8(id16).string());
+
+    sp<ReportFile> file = mWorkDirectory->getReport(pkg, cls, id, nullptr);
+    if (file != nullptr) {
+        mWorkDirectory->commit(file, pkg, cls);
+    }
+    mBroadcaster->clearBroadcasts(pkg, cls, id);
+
+    return Status::ok();
+}
+
+Status IncidentService::deleteAllIncidentReports(const String16& pkg16) {
+    const string pkg(String8(pkg16).string());
+
+    mWorkDirectory->commitAll(pkg);
+    mBroadcaster->clearPackageBroadcasts(pkg);
 
     return Status::ok();
 }
@@ -354,7 +497,7 @@
 
 static void printPrivacy(const Privacy* p, FILE* out, String8 indent) {
     if (p == NULL) return;
-    fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->dest);
+    fprintf(out, "%sid:%d, type:%d, dest:%d\n", indent.string(), p->field_id, p->type, p->policy);
     if (p->children == NULL) return;
     for (int i = 0; p->children[i] != NULL; i++) {  // NULL-terminated.
         printPrivacy(p->children[i], out, indent + "  ");
@@ -362,6 +505,8 @@
 }
 
 status_t IncidentService::cmd_privacy(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
+    (void)in;
+
     const int argCount = args.size();
     if (argCount >= 3) {
         String8 opt = args[1];
@@ -376,6 +521,7 @@
         if (opt == "print") {
             printPrivacy(p, out, String8(""));
         } else if (opt == "parse") {
+            /*
             FdBuffer buf;
             status_t error = buf.read(fileno(in), 60000);
             if (error != NO_ERROR) {
@@ -383,15 +529,17 @@
                 return error;
             }
             fprintf(err, "Read %zu bytes\n", buf.size());
-            PrivacyBuffer pBuf(p, buf.data());
+            PrivacyFilter pBuf(p, buf.data());
 
             PrivacySpec spec = PrivacySpec::new_spec(argCount > 3 ? atoi(args[3]) : -1);
             error = pBuf.strip(spec);
             if (error != NO_ERROR) {
-                fprintf(err, "Error strip pii fields with spec %d\n", spec.dest);
+                fprintf(err, "Error strip pii fields with spec %d\n", spec.policy);
                 return error;
             }
             return pBuf.flush(fileno(out));
+            */
+            return -1;
         }
     } else {
         return cmd_help(out);
@@ -408,7 +556,7 @@
 
     ALOGD("Dump incident proto");
     IncidentReportArgs incidentArgs;
-    incidentArgs.setDest(DEST_EXPLICIT);
+    incidentArgs.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT);
     int skipped[] = SKIPPED_SECTIONS;
     for (const Section** section = SECTION_LIST; *section; section++) {
         const int id = (*section)->id;
@@ -421,12 +569,16 @@
         return PERMISSION_DENIED;
     }
 
+    // The ReportRequest takes ownership of the fd, so we need to dup it.
     int fd1 = dup(fd);
     if (fd1 < 0) {
         return -errno;
     }
 
-    mHandler->scheduleRunReport(new ReportRequest(incidentArgs, NULL, fd1));
+    // TODO: Remove this.  Someone even dumpstate, wanting to get an incident report
+    // should use the API.  That will take making dumpstated call the API, which is a
+    // good thing.  It also means it won't be subject to the timeout.
+    mHandler->scheduleStreamingReport(incidentArgs, NULL, fd1);
 
     return NO_ERROR;
 }
diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h
index c63a183..6481321 100644
--- a/cmds/incidentd/src/IncidentService.h
+++ b/cmds/incidentd/src/IncidentService.h
@@ -20,13 +20,16 @@
 
 #include "Reporter.h"
 
+#include "Broadcaster.h"
+#include "Throttler.h"
+#include "WorkDirectory.h"
+
 #include <android/os/BnIncidentManager.h>
 #include <utils/Looper.h>
 
-#include <deque>
+#include <vector>
 #include <mutex>
 
-#include "Throttler.h"
 
 namespace android {
 namespace os {
@@ -38,60 +41,74 @@
 using namespace android::os;
 
 // ================================================================================
-class ReportRequestQueue : public virtual RefBase {
-public:
-    ReportRequestQueue();
-    virtual ~ReportRequestQueue();
-
-    void addRequest(const sp<ReportRequest>& request);
-    sp<ReportRequest> getNextRequest();
-
-private:
-    mutex mLock;
-    deque<sp<ReportRequest> > mQueue;
-};
-
-// ================================================================================
 class ReportHandler : public MessageHandler {
 public:
-    ReportHandler(const sp<Looper>& handlerLooper, const sp<ReportRequestQueue>& queue,
-                  const sp<Throttler>& throttler);
+    ReportHandler(const sp<WorkDirectory>& workDirectory,
+            const sp<Broadcaster>& broadcaster, const sp<Looper>& handlerLooper,
+            const sp<Throttler>& throttler);
     virtual ~ReportHandler();
 
     virtual void handleMessage(const Message& message);
 
     /**
-     * Adds a ReportRequest to the queue.
+     * Schedule a report for the "main" report, where it will be delivered to
+     * the uploaders and/or dropbox.
      */
-    void scheduleRunReport(const sp<ReportRequest>& request);
+    void schedulePersistedReport(const IncidentReportArgs& args);
+
+    /**
+     * Adds a ReportRequest to the queue for one that has a listener an and fd
+     */
+    void scheduleStreamingReport(const IncidentReportArgs& args,
+                                    const sp<IIncidentReportStatusListener>& listener,
+                                    int streamFd);
 
     /**
      * Resets mBacklogDelay to the default and schedules sending
      * the messages to dropbox.
      */
-    void scheduleSendBacklogToDropbox();
+    void scheduleSendBacklog();
 
 private:
     mutex mLock;
-    nsecs_t mBacklogDelay;
+
+    sp<WorkDirectory> mWorkDirectory;
+    sp<Broadcaster> mBroadcaster;
+
     sp<Looper> mHandlerLooper;
-    sp<ReportRequestQueue> mQueue;
+    nsecs_t mBacklogDelay;
     sp<Throttler> mThrottler;
 
+    sp<ReportBatch> mBatch;
+
     /**
      * Runs all of the reports that have been queued.
      */
-    void run_report();
+    void take_report();
 
     /**
-     * Schedules a dropbox task mBacklogDelay nanoseconds from now.
+     * Schedules permission controller approve the reports.
      */
-    void schedule_send_backlog_to_dropbox_locked();
+    void schedule_send_approvals_locked();
 
     /**
-     * Sends the backlog to the dropbox service.
+     * Sends the approvals to the PermissionController
      */
-    void send_backlog_to_dropbox();
+    void send_approvals();
+
+    /**
+     * Schedules the broadcasts that reports are complete mBacklogDelay nanoseconds from now.
+     * The delay is because typically when an incident report is taken, the system is not
+     * really in a happy state.  So we wait a bit before sending the report to let things
+     * quiet down if they can.  The urgency is in taking the report, not sharing the report.
+     * However, we don
+     */
+    void schedule_send_broadcasts_locked();
+
+    /**
+     * Sends the broadcasts to the dropbox service.
+     */
+    void send_broadcasts();
 };
 
 // ================================================================================
@@ -108,6 +125,17 @@
 
     virtual Status systemRunning();
 
+    virtual Status getIncidentReportList(const String16& pkg, const String16& cls,
+            vector<String16>* result);
+
+    virtual Status getIncidentReport(const String16& pkg, const String16& cls,
+            const String16& id, IncidentManager::IncidentReport* result);
+
+    virtual Status deleteIncidentReports(const String16& pkg, const String16& cls,
+            const String16& id);
+
+    virtual Status deleteAllIncidentReports(const String16& pkg);
+
     // Implement commands for debugging purpose.
     virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                 uint32_t flags) override;
@@ -115,7 +143,8 @@
     virtual status_t dump(int fd, const Vector<String16>& args);
 
 private:
-    sp<ReportRequestQueue> mQueue;
+    sp<WorkDirectory> mWorkDirectory;
+    sp<Broadcaster> mBroadcaster;
     sp<ReportHandler> mHandler;
     sp<Throttler> mThrottler;
 
diff --git a/cmds/incidentd/src/Privacy.cpp b/cmds/incidentd/src/Privacy.cpp
index 6e55f90..386303b 100644
--- a/cmds/incidentd/src/Privacy.cpp
+++ b/cmds/incidentd/src/Privacy.cpp
@@ -23,6 +23,8 @@
 namespace os {
 namespace incidentd {
 
+using namespace android::os;
+
 uint64_t encode_field_id(const Privacy* p) { return (uint64_t)p->type << 32 | p->field_id; }
 
 const Privacy* lookup(const Privacy* p, uint32_t fieldId) {
@@ -35,39 +37,48 @@
     return NULL;
 }
 
-static bool allowDest(const uint8_t dest, const uint8_t policy) {
-    switch (policy) {
-        case android::os::DEST_LOCAL:
-            return dest == android::os::DEST_LOCAL;
-        case android::os::DEST_EXPLICIT:
-        case DEST_UNSET:
-            return dest == android::os::DEST_LOCAL || dest == android::os::DEST_EXPLICIT ||
-                   dest == DEST_UNSET;
-        case android::os::DEST_AUTOMATIC:
+static bool isAllowed(const uint8_t policy, const uint8_t check) {
+    switch (check) {
+        case PRIVACY_POLICY_LOCAL:
+            return policy == PRIVACY_POLICY_LOCAL;
+        case PRIVACY_POLICY_EXPLICIT:
+        case PRIVACY_POLICY_UNSET:
+            return policy == PRIVACY_POLICY_LOCAL
+                    || policy == PRIVACY_POLICY_EXPLICIT
+                    || policy == PRIVACY_POLICY_UNSET;
+        case PRIVACY_POLICY_AUTOMATIC:
             return true;
         default:
             return false;
     }
 }
 
-bool PrivacySpec::operator<(const PrivacySpec& other) const { return dest < other.dest; }
-
-bool PrivacySpec::CheckPremission(const Privacy* privacy, const uint8_t defaultDest) const {
-    uint8_t policy = privacy != NULL ? privacy->dest : defaultDest;
-    return allowDest(dest, policy);
+PrivacySpec::PrivacySpec(uint8_t argPolicy) {
+    // TODO: Why on earth do we have two definitions of policy.  Maybe
+    // it's not too late to clean this up.
+    switch (argPolicy) {
+        case android::os::PRIVACY_POLICY_AUTOMATIC:
+        case android::os::PRIVACY_POLICY_EXPLICIT:
+        case android::os::PRIVACY_POLICY_LOCAL:
+            mPolicy = argPolicy;
+            break;
+        default:
+            mPolicy = android::os::PRIVACY_POLICY_AUTOMATIC;
+            break;
+    }
 }
 
-bool PrivacySpec::RequireAll() const { return dest == android::os::DEST_LOCAL; }
+bool PrivacySpec::operator<(const PrivacySpec& that) const {
+    return mPolicy < that.mPolicy;
+}
 
-PrivacySpec PrivacySpec::new_spec(int dest) {
-    switch (dest) {
-        case android::os::DEST_AUTOMATIC:
-        case android::os::DEST_EXPLICIT:
-        case android::os::DEST_LOCAL:
-            return PrivacySpec(dest);
-        default:
-            return PrivacySpec(android::os::DEST_AUTOMATIC);
-    }
+bool PrivacySpec::CheckPremission(const Privacy* privacy, const uint8_t defaultDest) const {
+    uint8_t check = privacy != NULL ? privacy->policy : defaultDest;
+    return isAllowed(mPolicy, check);
+}
+
+bool PrivacySpec::RequireAll() const {
+    return mPolicy == android::os::PRIVACY_POLICY_LOCAL;
 }
 
 }  // namespace incidentd
diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h
index a0159d9..fc8caae 100644
--- a/cmds/incidentd/src/Privacy.h
+++ b/cmds/incidentd/src/Privacy.h
@@ -18,15 +18,15 @@
 #ifndef PRIVACY_H
 #define PRIVACY_H
 
+#include <android/os/IncidentReportArgs.h>
+
 #include <stdint.h>
 
 namespace android {
 namespace os {
 namespace incidentd {
 
-// This is the default value of DEST enum, sync with privacy.proto
-const uint8_t DEST_UNSET = 255;  // DEST_UNSET is not exposed to libincident
-const uint8_t DEST_DEFAULT_VALUE = DEST_UNSET;
+using namespace android::os;
 
 /*
  * In order to NOT auto-generate large chuck of code by proto compiler in incidentd,
@@ -48,8 +48,8 @@
     // This array is NULL-terminated.
     Privacy** children;
 
-    // DESTINATION Enum in frameworks/base/libs/incident/proto/android/privacy.proto.
-    uint8_t dest;
+    // DESTINATION Enum in frameworks/base/core/proto/android/privacy.proto.
+    uint8_t policy;
     // A list of regexp rules for stripping string fields in proto.
     const char** patterns;
 };
@@ -63,27 +63,28 @@
 /**
  * PrivacySpec defines the request has what level of privacy authorization.
  * For example, a device without user consent should only be able to upload AUTOMATIC fields.
- * DEST_UNSET are treated as DEST_EXPLICIT.
+ * PRIVACY_POLICY_UNSET are treated as PRIVACY_POLICY_EXPLICIT.
  */
 class PrivacySpec {
 public:
-    const uint8_t dest;
+    explicit PrivacySpec(uint8_t argPolicy);
 
-    PrivacySpec() : dest(DEST_DEFAULT_VALUE) {}
     bool operator<(const PrivacySpec& other) const;
 
     // check permission of a policy, if returns true, don't strip the data.
     bool CheckPremission(const Privacy* privacy,
-                         const uint8_t defaultDest = DEST_DEFAULT_VALUE) const;
+                         const uint8_t defaultPrivacyPolicy = PRIVACY_POLICY_UNSET) const;
 
     // if returns true, no data need to be stripped.
     bool RequireAll() const;
 
-    // Constructs spec using static methods below.
-    static PrivacySpec new_spec(int dest);
+    uint8_t getPolicy() const;
 
 private:
-    explicit PrivacySpec(uint8_t dest) : dest(dest) {}
+    // unimplemented constructors
+    explicit PrivacySpec();
+
+    uint8_t mPolicy;
 };
 
 }  // namespace incidentd
diff --git a/cmds/incidentd/src/PrivacyBuffer.cpp b/cmds/incidentd/src/PrivacyBuffer.cpp
deleted file mode 100644
index 08f535d..0000000
--- a/cmds/incidentd/src/PrivacyBuffer.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false
-#include "Log.h"
-
-#include "PrivacyBuffer.h"
-#include "incidentd_util.h"
-
-#include <android-base/file.h>
-#include <android/util/protobuf.h>
-#include <log/log.h>
-
-namespace android {
-namespace os {
-namespace incidentd {
-
-/**
- * Write the field to buf based on the wire type, iterator will point to next field.
- * If skip is set to true, no data will be written to buf. Return number of bytes written.
- */
-void PrivacyBuffer::writeFieldOrSkip(uint32_t fieldTag, bool skip) {
-    uint8_t wireType = read_wire_type(fieldTag);
-    size_t bytesToWrite = 0;
-    uint64_t varint = 0;
-
-    switch (wireType) {
-        case WIRE_TYPE_VARINT:
-            varint = mData.readRawVarint();
-            if (!skip) {
-                mProto.writeRawVarint(fieldTag);
-                mProto.writeRawVarint(varint);
-            }
-            return;
-        case WIRE_TYPE_FIXED64:
-            if (!skip) mProto.writeRawVarint(fieldTag);
-            bytesToWrite = 8;
-            break;
-        case WIRE_TYPE_LENGTH_DELIMITED:
-            bytesToWrite = mData.readRawVarint();
-            if (!skip) mProto.writeLengthDelimitedHeader(read_field_id(fieldTag), bytesToWrite);
-            break;
-        case WIRE_TYPE_FIXED32:
-            if (!skip) mProto.writeRawVarint(fieldTag);
-            bytesToWrite = 4;
-            break;
-    }
-    if (skip) {
-        mData.rp()->move(bytesToWrite);
-    } else {
-        for (size_t i = 0; i < bytesToWrite; i++) {
-            mProto.writeRawByte(mData.next());
-        }
-    }
-}
-
-/**
- * Strip next field based on its private policy and request spec, then stores data in buf.
- * Return NO_ERROR if succeeds, otherwise BAD_VALUE is returned to indicate bad data in FdBuffer.
- *
- * The iterator must point to the head of a protobuf formatted field for successful operation.
- * After exit with NO_ERROR, iterator points to the next protobuf field's head.
- */
-status_t PrivacyBuffer::stripField(const Privacy* parentPolicy, const PrivacySpec& spec,
-                                   int depth /* use as a counter for this recusive method. */) {
-    if (!mData.hasNext() || parentPolicy == NULL) return BAD_VALUE;
-    uint32_t fieldTag = mData.readRawVarint();
-    uint32_t fieldId = read_field_id(fieldTag);
-    const Privacy* policy = lookup(parentPolicy, fieldId);
-
-    VLOG("[Depth %2d]Try to strip id %d, wiretype %d", depth, fieldId, read_wire_type(fieldTag));
-    if (policy == NULL || policy->children == NULL) {
-        bool skip = !spec.CheckPremission(policy, parentPolicy->dest);
-        // iterator will point to head of next field
-        size_t currentAt = mData.rp()->pos();
-        writeFieldOrSkip(fieldTag, skip);
-        VLOG("[Depth %2d]Field %d %ss %zu bytes", depth, fieldId, skip ? "skip" : "write",
-             get_varint_size(fieldTag) + mData.rp()->pos() - currentAt);
-        return NO_ERROR;
-    }
-    // current field is message type and its sub-fields have extra privacy policies
-    uint32_t msgSize = mData.readRawVarint();
-    size_t start = mData.rp()->pos();
-    uint64_t token = mProto.start(encode_field_id(policy));
-    while (mData.rp()->pos() - start != msgSize) {
-        status_t err = stripField(policy, spec, depth + 1);
-        if (err != NO_ERROR) {
-            VLOG("Bad value when stripping id %d, wiretype %d, tag %#x, depth %d, size %d, "
-                "relative pos %zu, ", fieldId, read_wire_type(fieldTag), fieldTag, depth,
-                msgSize, mData.rp()->pos() - start);
-            return err;
-        }
-    }
-    mProto.end(token);
-    return NO_ERROR;
-}
-
-// ================================================================================
-PrivacyBuffer::PrivacyBuffer(const Privacy* policy, EncodedBuffer::iterator data)
-    : mPolicy(policy), mData(data), mProto(), mSize(0) {}
-
-PrivacyBuffer::~PrivacyBuffer() {}
-
-status_t PrivacyBuffer::strip(const PrivacySpec& spec) {
-    VLOG("Strip with spec %d", spec.dest);
-    // optimization when no strip happens
-    if (mPolicy == NULL || mPolicy->children == NULL || spec.RequireAll()) {
-        if (spec.CheckPremission(mPolicy)) mSize = mData.size();
-        return NO_ERROR;
-    }
-    while (mData.hasNext()) {
-        status_t err = stripField(mPolicy, spec, 0);
-        if (err != NO_ERROR) return err; // Error logged in stripField.
-    }
-    if (mData.bytesRead() != mData.size()) {
-        VLOG("Buffer corrupted: expect %zu bytes, read %zu bytes",
-            mData.size(), mData.bytesRead());
-        return BAD_VALUE;
-    }
-    mSize = mProto.size();
-    mData.rp()->rewind();  // rewind the read pointer back to beginning after the strip.
-    return NO_ERROR;
-}
-
-void PrivacyBuffer::clear() {
-    mSize = 0;
-    mProto.clear();
-}
-
-size_t PrivacyBuffer::size() const { return mSize; }
-
-status_t PrivacyBuffer::flush(int fd) {
-    status_t err = NO_ERROR;
-    EncodedBuffer::iterator iter = size() == mData.size() ? mData : mProto.data();
-    while (iter.readBuffer() != NULL) {
-        err = WriteFully(fd, iter.readBuffer(), iter.currentToRead()) ? NO_ERROR : -errno;
-        iter.rp()->move(iter.currentToRead());
-        if (err != NO_ERROR) return err;
-    }
-    return NO_ERROR;
-}
-
-}  // namespace incidentd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/incidentd/src/PrivacyBuffer.h b/cmds/incidentd/src/PrivacyBuffer.h
deleted file mode 100644
index eac3862..0000000
--- a/cmds/incidentd/src/PrivacyBuffer.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#ifndef PRIVACY_BUFFER_H
-#define PRIVACY_BUFFER_H
-
-#include "Privacy.h"
-
-#include <android/util/EncodedBuffer.h>
-#include <android/util/ProtoOutputStream.h>
-#include <stdint.h>
-#include <utils/Errors.h>
-
-namespace android {
-namespace os {
-namespace incidentd {
-
-using namespace android::util;
-
-/**
- * PrivacyBuffer holds the original protobuf data and strips PII-sensitive fields
- * based on the request and holds stripped data in its own buffer for output.
- */
-class PrivacyBuffer {
-public:
-    PrivacyBuffer(const Privacy* policy, EncodedBuffer::iterator data);
-    ~PrivacyBuffer();
-
-    /**
-     * Strip based on the request and hold data in its own buffer. Return NO_ERROR if strip
-     * succeeds.
-     */
-    status_t strip(const PrivacySpec& spec);
-
-    /**
-     * Clear encoded buffer so it can be reused by another request.
-     */
-    void clear();
-
-    /**
-     * Return the size of the stripped data.
-     */
-    size_t size() const;
-
-    /**
-     * Flush buffer to the given fd. NO_ERROR is returned if the flush succeeds.
-     */
-    status_t flush(int fd);
-
-private:
-    const Privacy* mPolicy;
-    EncodedBuffer::iterator mData;
-
-    ProtoOutputStream mProto;
-    size_t mSize;
-
-    status_t stripField(const Privacy* parentPolicy, const PrivacySpec& spec, int depth);
-    void writeFieldOrSkip(uint32_t fieldTag, bool skip);
-};
-
-}  // namespace incidentd
-}  // namespace os
-}  // namespace android
-
-#endif  // PRIVACY_BUFFER_H
\ No newline at end of file
diff --git a/cmds/incidentd/src/PrivacyFilter.cpp b/cmds/incidentd/src/PrivacyFilter.cpp
new file mode 100644
index 0000000..7126322
--- /dev/null
+++ b/cmds/incidentd/src/PrivacyFilter.cpp
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define DEBUG false
+#include "Log.h"
+
+#include "incidentd_util.h"
+#include "PrivacyFilter.h"
+#include "proto_util.h"
+
+#include <android-base/file.h>
+#include <android/util/protobuf.h>
+#include <android/util/ProtoFileReader.h>
+#include <log/log.h>
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+// ================================================================================
+/**
+ * Write the field to buf based on the wire type, iterator will point to next field.
+ * If skip is set to true, no data will be written to buf. Return number of bytes written.
+ */
+void write_field_or_skip(ProtoOutputStream* out, const sp<ProtoReader>& in,
+        uint32_t fieldTag, bool skip) {
+    uint8_t wireType = read_wire_type(fieldTag);
+    size_t bytesToWrite = 0;
+    uint64_t varint = 0;
+
+    switch (wireType) {
+        case WIRE_TYPE_VARINT:
+            varint = in->readRawVarint();
+            if (!skip) {
+                out->writeRawVarint(fieldTag);
+                out->writeRawVarint(varint);
+            }
+            return;
+        case WIRE_TYPE_FIXED64:
+            if (!skip) {
+                out->writeRawVarint(fieldTag);
+            }
+            bytesToWrite = 8;
+            break;
+        case WIRE_TYPE_LENGTH_DELIMITED:
+            bytesToWrite = in->readRawVarint();
+            if (!skip) {
+                out->writeLengthDelimitedHeader(read_field_id(fieldTag), bytesToWrite);
+            }
+            break;
+        case WIRE_TYPE_FIXED32:
+            if (!skip) {
+                out->writeRawVarint(fieldTag);
+            }
+            bytesToWrite = 4;
+            break;
+    }
+    if (skip) {
+        in->move(bytesToWrite);
+    } else {
+        for (size_t i = 0; i < bytesToWrite; i++) {
+            out->writeRawByte(in->next());
+        }
+    }
+}
+
+/**
+ * Strip next field based on its private policy and request spec, then stores data in buf.
+ * Return NO_ERROR if succeeds, otherwise BAD_VALUE is returned to indicate bad data in
+ * FdBuffer.
+ *
+ * The iterator must point to the head of a protobuf formatted field for successful operation.
+ * After exit with NO_ERROR, iterator points to the next protobuf field's head.
+ *
+ * depth is the depth of recursion, for debugging.
+ */
+status_t strip_field(ProtoOutputStream* out, const sp<ProtoReader>& in,
+        const Privacy* parentPolicy, const PrivacySpec& spec, int depth) {
+    if (!in->hasNext() || parentPolicy == NULL) {
+        return BAD_VALUE;
+    }
+    uint32_t fieldTag = in->readRawVarint();
+    uint32_t fieldId = read_field_id(fieldTag);
+    const Privacy* policy = lookup(parentPolicy, fieldId);
+
+    if (policy == NULL || policy->children == NULL) {
+        bool skip = !spec.CheckPremission(policy, parentPolicy->policy);
+        // iterator will point to head of next field
+        size_t currentAt = in->bytesRead();
+        write_field_or_skip(out, in, fieldTag, skip);
+        return NO_ERROR;
+    }
+    // current field is message type and its sub-fields have extra privacy policies
+    uint32_t msgSize = in->readRawVarint();
+    size_t start = in->bytesRead();
+    uint64_t token = out->start(encode_field_id(policy));
+    while (in->bytesRead() - start != msgSize) {
+        status_t err = strip_field(out, in, policy, spec, depth + 1);
+        if (err != NO_ERROR) {
+            ALOGW("Bad value when stripping id %d, wiretype %d, tag %#x, depth %d, size %d, "
+                    "relative pos %zu, ", fieldId, read_wire_type(fieldTag), fieldTag, depth,
+                    msgSize, in->bytesRead() - start);
+            return err;
+        }
+    }
+    out->end(token);
+    return NO_ERROR;
+}
+
+// ================================================================================
+class FieldStripper {
+public:
+    FieldStripper(const Privacy* restrictions, const sp<ProtoReader>& data,
+            uint8_t bufferLevel);
+
+    /**
+     * Take the data that we have, and filter it down so that no fields
+     * are more sensitive than the given privacy policy.
+     */
+    status_t strip(uint8_t privacyPolicy);
+
+    /**
+     * At the current filter level, how many bytes of data there is.
+     */
+    ssize_t dataSize() const { return mSize; }
+
+    /**
+     * Write the data from the current filter level to the file descriptor.
+     */
+    status_t writeData(int fd);
+
+private:
+    /**
+     * The global set of field --> required privacy level mapping.
+     */
+    const Privacy* mRestrictions;
+
+    /**
+     * The current buffer.
+     */
+    sp<ProtoReader> mData;
+
+    /**
+     * The current size of the buffer inside mData.
+     */
+    ssize_t mSize;
+
+    /**
+     * The current privacy policy that the data is filtered to, as an optimization
+     * so we don't always re-filter data that has already been filtered.
+     */
+    uint8_t mCurrentLevel;
+
+};
+
+FieldStripper::FieldStripper(const Privacy* restrictions, const sp<ProtoReader>& data,
+            uint8_t bufferLevel)
+        :mRestrictions(restrictions),
+         mData(data),
+         mSize(data->size()),
+         mCurrentLevel(bufferLevel) {
+    if (mSize < 0) {
+        ALOGW("FieldStripper constructed with a ProtoReader that doesn't support size."
+                " Data will be missing.");
+    }
+}
+
+status_t FieldStripper::strip(const uint8_t privacyPolicy) {
+    // If the current strip level is less (fewer fields retained) than what's already in the
+    // buffer, then we can skip it.
+    if (mCurrentLevel < privacyPolicy) {
+        PrivacySpec spec(privacyPolicy);
+        ProtoOutputStream proto;
+
+        // Optimization when no strip happens.
+        if (mRestrictions == NULL || mRestrictions->children == NULL || spec.RequireAll()) {
+            if (spec.CheckPremission(mRestrictions)) {
+                mSize = mData->size();
+            }
+            return NO_ERROR;
+        }
+
+        while (mData->hasNext()) {
+            status_t err = strip_field(&proto, mData, mRestrictions, spec, 0);
+            if (err != NO_ERROR) {
+                return err; // Error logged in strip_field.
+            }
+        }
+
+        if (mData->bytesRead() != mData->size()) {
+            ALOGW("Buffer corrupted: expect %zu bytes, read %zu bytes", mData->size(),
+                    mData->bytesRead());
+            return BAD_VALUE;
+        }
+
+        mData = proto.data();
+        mSize = proto.size();
+        mCurrentLevel = privacyPolicy;
+    }
+    return NO_ERROR;
+}
+
+status_t FieldStripper::writeData(int fd) {
+    status_t err = NO_ERROR;
+    sp<ProtoReader> reader = mData;
+    while (reader->readBuffer() != NULL) {
+        err = WriteFully(fd, reader->readBuffer(), reader->currentToRead()) ? NO_ERROR : -errno;
+        reader->move(reader->currentToRead());
+        if (err != NO_ERROR) return err;
+    }
+    return NO_ERROR;
+}
+
+
+// ================================================================================
+FilterFd::FilterFd(uint8_t privacyPolicy, int fd)
+        :mPrivacyPolicy(privacyPolicy),
+         mFd(fd) {
+}
+
+FilterFd::~FilterFd() {
+}
+
+// ================================================================================
+PrivacyFilter::PrivacyFilter(int sectionId, const Privacy* restrictions)
+        :mSectionId(sectionId),
+         mRestrictions(restrictions),
+         mOutputs() {
+}
+
+PrivacyFilter::~PrivacyFilter() {
+}
+
+void PrivacyFilter::addFd(const sp<FilterFd>& output) {
+    mOutputs.push_back(output);
+}
+
+status_t PrivacyFilter::writeData(const FdBuffer& buffer, uint8_t bufferLevel,
+        size_t* maxSize) {
+    status_t err;
+
+    if (maxSize != NULL) {
+        *maxSize = 0;
+    }
+
+    // Order the writes by privacy filter, with increasing levels of filtration,k
+    // so we can do the filter once, and then write many times.
+    sort(mOutputs.begin(), mOutputs.end(),
+        [](const sp<FilterFd>& a, const sp<FilterFd>& b) -> bool { 
+            return a->getPrivacyPolicy() < b->getPrivacyPolicy();
+        });
+
+    uint8_t privacyPolicy = PRIVACY_POLICY_LOCAL; // a.k.a. no filtering
+    FieldStripper fieldStripper(mRestrictions, buffer.data()->read(), bufferLevel);
+    for (const sp<FilterFd>& output: mOutputs) {
+        // Do another level of filtering if necessary
+        if (privacyPolicy != output->getPrivacyPolicy()) {
+            privacyPolicy = output->getPrivacyPolicy();
+            err = fieldStripper.strip(privacyPolicy);
+            if (err != NO_ERROR) {
+                // We can't successfully strip this data.  We will skip
+                // the rest of this section.
+                return err;
+            }
+        }
+
+        // Write the resultant buffer to the fd, along with the header.
+        ssize_t dataSize = fieldStripper.dataSize();
+        if (dataSize > 0) {
+            err = write_section_header(output->getFd(), mSectionId, dataSize);
+            if (err != NO_ERROR) {
+                output->onWriteError(err);
+                continue;
+            }
+
+            err = fieldStripper.writeData(output->getFd());
+            if (err != NO_ERROR) {
+                output->onWriteError(err);
+                continue;
+            }
+        }
+
+        if (maxSize != NULL) {
+            if (dataSize > *maxSize) {
+                *maxSize = dataSize;
+            }
+        }
+    }
+
+    return NO_ERROR;
+}
+
+// ================================================================================
+class ReadbackFilterFd : public FilterFd {
+public:
+    ReadbackFilterFd(uint8_t privacyPolicy, int fd);
+
+    virtual void onWriteError(status_t err);
+    status_t getError() { return mError; }
+
+private:
+    status_t mError;
+};
+
+ReadbackFilterFd::ReadbackFilterFd(uint8_t privacyPolicy, int fd)
+        :FilterFd(privacyPolicy, fd),
+         mError(NO_ERROR) {
+}
+
+void ReadbackFilterFd::onWriteError(status_t err) {
+    mError = err;
+}
+
+// ================================================================================
+status_t filter_and_write_report(int to, int from, uint8_t bufferLevel,
+        const IncidentReportArgs& args) {
+    status_t err;
+    sp<ProtoFileReader> reader = new ProtoFileReader(from);
+
+    while (reader->hasNext()) {
+        uint64_t fieldTag = reader->readRawVarint();
+        uint32_t fieldId = read_field_id(fieldTag);
+        uint8_t wireType = read_wire_type(fieldTag);
+        if (wireType == WIRE_TYPE_LENGTH_DELIMITED && args.containsSection(fieldId)) {
+            // We need this field, but we need to strip it to the level provided in args.
+            PrivacyFilter filter(fieldId, get_privacy_of_section(fieldId));
+            filter.addFd(new ReadbackFilterFd(args.getPrivacyPolicy(), to));
+
+            // Read this section from the reader into an FdBuffer
+            size_t sectionSize = reader->readRawVarint();
+            FdBuffer sectionData;
+            err = sectionData.write(reader, sectionSize);
+            if (err != NO_ERROR) {
+                ALOGW("filter_and_write_report FdBuffer.write failed (this shouldn't happen): %s",
+                        strerror(-err));
+                return err;
+            }
+
+            // Do the filter and write.
+            err = filter.writeData(sectionData, bufferLevel, nullptr);
+            if (err != NO_ERROR) {
+                ALOGW("filter_and_write_report filter.writeData had an error: %s", strerror(-err));
+                return err;
+            }
+        } else {
+            // We don't need this field.  Incident does not have any direct children
+            // other than sections.  So just skip them.
+            write_field_or_skip(NULL, reader, fieldTag, true);
+        }
+    }
+
+    err = reader->getError();
+    if (err != NO_ERROR) {
+        ALOGW("filter_and_write_report reader had an error: %s", strerror(-err));
+        return err;
+    }
+
+    return NO_ERROR;
+}
+
+}  // namespace incidentd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/incidentd/src/PrivacyFilter.h b/cmds/incidentd/src/PrivacyFilter.h
new file mode 100644
index 0000000..76b2849
--- /dev/null
+++ b/cmds/incidentd/src/PrivacyFilter.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#ifndef PRIVACY_BUFFER_H
+#define PRIVACY_BUFFER_H
+
+#include "Privacy.h"
+
+#include "FdBuffer.h"
+
+#include <android/os/IncidentReportArgs.h>
+#include <android/util/ProtoOutputStream.h>
+#include <stdint.h>
+#include <utils/Errors.h>
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using namespace android::util;
+
+/**
+ * Class to wrap a file descriptor, so callers of PrivacyFilter
+ * can associate additional data with each fd for their own
+ * purposes.
+ */
+class FilterFd : public RefBase {
+public:
+    FilterFd(uint8_t privacyPolicy, int fd);
+    virtual ~FilterFd();
+
+    uint8_t getPrivacyPolicy() const { return mPrivacyPolicy; }
+    int getFd() { return mFd;}
+
+    virtual void onWriteError(status_t err) = 0;
+
+private:
+    uint8_t mPrivacyPolicy;
+    int mFd;
+};
+
+/**
+ * PrivacyFilter holds the original protobuf data and strips PII-sensitive fields
+ * for several requests, streaming them to a set of corresponding file descriptors.
+ */
+class PrivacyFilter {
+public:
+    /**
+     * Constructor, with the field --> privacy restrictions mapping.
+     */
+    PrivacyFilter(int sectionId, const Privacy* restrictions);
+
+    ~PrivacyFilter();
+
+    /**
+     * Add a target file descriptor, and the privacy policy to which
+     * it should be filtered.
+     */
+    void addFd(const sp<FilterFd>& output);
+
+    /**
+     * Write the data, filtered according to the privacy specs, to each of the
+     * file descriptors.  Any non-NO_ERROR return codes are fatal to the whole
+     * report.  Individual write errors to streams are reported via the callbacks
+     * on the FilterFds.
+     *
+     * If maxSize is not NULL, it will be set to the maximum size buffer that
+     * was written (i.e. after filtering).
+     *
+     * The buffer is assumed to have already been filtered to bufferLevel.
+     */
+    status_t writeData(const FdBuffer& buffer, uint8_t bufferLevel, size_t* maxSize);
+
+private:
+    int mSectionId;
+    const Privacy* mRestrictions;
+    vector<sp<FilterFd>> mOutputs;
+};
+
+status_t filter_and_write_report(int to, int from, uint8_t bufferLevel,
+        const IncidentReportArgs& args);
+
+}  // namespace incidentd
+}  // namespace os
+}  // namespace android
+
+#endif  // PRIVACY_BUFFER_H
diff --git a/cmds/incidentd/src/Reporter.cpp b/cmds/incidentd/src/Reporter.cpp
index 8f62da2..218c1b2 100644
--- a/cmds/incidentd/src/Reporter.cpp
+++ b/cmds/incidentd/src/Reporter.cpp
@@ -18,12 +18,17 @@
 
 #include "Reporter.h"
 
+#include "incidentd_util.h"
 #include "Privacy.h"
+#include "PrivacyFilter.h"
+#include "proto_util.h"
 #include "report_directory.h"
 #include "section_list.h"
 
-#include <android-base/properties.h>
+#include <android-base/file.h>
 #include <android/os/DropBoxManager.h>
+#include <android/util/protobuf.h>
+#include <android/util/ProtoOutputStream.h>
 #include <private/android_filesystem_config.h>
 #include <utils/SystemClock.h>
 
@@ -33,308 +38,664 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <string>
-
-/**
- * The directory where the incident reports are stored.
- */
-static const char* INCIDENT_DIRECTORY = "/data/misc/incidents/";
+#include <time.h>
 
 namespace android {
 namespace os {
 namespace incidentd {
 
+using namespace android::util;
+
+/**
+ * The field id of the metadata section from
+ *      frameworks/base/core/proto/android/os/incident.proto
+ */
+const int FIELD_ID_METADATA = 2;
+
+IncidentMetadata_Destination privacy_policy_to_dest(uint8_t privacyPolicy) {
+    switch (privacyPolicy) {
+        case PRIVACY_POLICY_AUTOMATIC:
+            return IncidentMetadata_Destination_AUTOMATIC;
+        case PRIVACY_POLICY_EXPLICIT:
+            return IncidentMetadata_Destination_EXPLICIT;
+        case PRIVACY_POLICY_LOCAL:
+            return IncidentMetadata_Destination_LOCAL;
+        default:
+            // Anything else reverts to automatic
+            return IncidentMetadata_Destination_AUTOMATIC;
+    }
+}
+
+void poo_make_metadata(IncidentMetadata* result, const IncidentMetadata& full,
+        int64_t reportId, int32_t privacyPolicy, const IncidentReportArgs& args) {
+    result->set_report_id(reportId);
+    result->set_dest(privacy_policy_to_dest(privacyPolicy));
+
+    size_t sectionCount = full.sections_size();
+    for (int sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
+        const IncidentMetadata::SectionStats& sectionStats = full.sections(sectionIndex);
+        if (args.containsSection(sectionStats.id())) {
+            *result->add_sections() = sectionStats;
+        }
+    }
+}
+
+// ARGS must have a containsSection(int) method
+template <typename ARGS> void make_metadata(IncidentMetadata* result, const IncidentMetadata& full,
+        int64_t reportId, int32_t privacyPolicy, ARGS args) {
+    result->set_report_id(reportId);
+    result->set_dest(privacy_policy_to_dest(privacyPolicy));
+
+    size_t sectionCount = full.sections_size();
+    for (int sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
+        const IncidentMetadata::SectionStats& sectionStats = full.sections(sectionIndex);
+        if (args->containsSection(sectionStats.id())) {
+            *result->add_sections() = sectionStats;
+        }
+    }
+}
+
+// ================================================================================
+class StreamingFilterFd : public FilterFd {
+public:
+    StreamingFilterFd(uint8_t privacyPolicy, int fd, const sp<ReportRequest>& request);
+
+    virtual void onWriteError(status_t err);
+
+private:
+    sp<ReportRequest> mRequest;
+};
+
+StreamingFilterFd::StreamingFilterFd(uint8_t privacyPolicy, int fd,
+            const sp<ReportRequest>& request)
+        :FilterFd(privacyPolicy, fd),
+         mRequest(request) {
+}
+
+void StreamingFilterFd::onWriteError(status_t err) {
+    mRequest->setStatus(err);
+}
+
+
+// ================================================================================
+class PersistedFilterFd : public FilterFd {
+public:
+    PersistedFilterFd(uint8_t privacyPolicy, int fd, const sp<ReportFile>& reportFile);
+
+    virtual void onWriteError(status_t err);
+
+private:
+    sp<ReportFile> mReportFile;
+};
+
+PersistedFilterFd::PersistedFilterFd(uint8_t privacyPolicy, int fd,
+            const sp<ReportFile>& reportFile)
+        :FilterFd(privacyPolicy, fd),
+         mReportFile(reportFile) {
+}
+
+void PersistedFilterFd::onWriteError(status_t err) {
+    mReportFile->setWriteError(err);
+}
+
+
 // ================================================================================
 ReportRequest::ReportRequest(const IncidentReportArgs& a,
-                             const sp<IIncidentReportStatusListener>& l, int f)
-    : args(a), listener(l), fd(f), err(NO_ERROR) {}
+                             const sp<IIncidentReportStatusListener>& listener, int fd)
+        :args(a),
+         mListener(listener),
+         mFd(fd),
+         mIsStreaming(fd >= 0),
+         mStatus(NO_ERROR) {
+}
 
 ReportRequest::~ReportRequest() {
-    if (fd >= 0) {
+    if (mIsStreaming && mFd >= 0) {
         // clean up the opened file descriptor
-        close(fd);
+        close(mFd);
     }
 }
 
-bool ReportRequest::ok() { return fd >= 0 && err == NO_ERROR; }
-
-// ================================================================================
-ReportRequestSet::ReportRequestSet()
-    : mRequests(), mSections(), mMainFd(-1), mMainDest(-1), mMetadata(), mSectionStats() {}
-
-ReportRequestSet::~ReportRequestSet() {}
-
-// TODO: dedup on exact same args and fd, report the status back to listener!
-void ReportRequestSet::add(const sp<ReportRequest>& request) {
-    mRequests.push_back(request);
-    mSections.merge(request->args);
-    mMetadata.set_request_size(mMetadata.request_size() + 1);
+bool ReportRequest::ok() {
+    return mFd >= 0 && mStatus == NO_ERROR;
 }
 
-void ReportRequestSet::setMainFd(int fd) {
-    mMainFd = fd;
-    mMetadata.set_use_dropbox(fd > 0);
-}
-
-void ReportRequestSet::setMainDest(int dest) {
-    mMainDest = dest;
-    PrivacySpec spec = PrivacySpec::new_spec(dest);
-    switch (spec.dest) {
-        case android::os::DEST_AUTOMATIC:
-            mMetadata.set_dest(IncidentMetadata_Destination_AUTOMATIC);
-            break;
-        case android::os::DEST_EXPLICIT:
-            mMetadata.set_dest(IncidentMetadata_Destination_EXPLICIT);
-            break;
-        case android::os::DEST_LOCAL:
-            mMetadata.set_dest(IncidentMetadata_Destination_LOCAL);
-            break;
+void ReportRequest::closeFd() {
+    if (mIsStreaming && mFd >= 0) {
+        close(mFd);
+        mFd = -1;
     }
 }
 
-bool ReportRequestSet::containsSection(int id) { return mSections.containsSection(id); }
-
-IncidentMetadata::SectionStats* ReportRequestSet::sectionStats(int id) {
-    if (mSectionStats.find(id) == mSectionStats.end()) {
-        IncidentMetadata::SectionStats stats;
-        stats.set_id(id);
-        mSectionStats[id] = stats;
-    }
-    return &mSectionStats[id];
-}
-
 // ================================================================================
-Reporter::Reporter() : Reporter(INCIDENT_DIRECTORY) { isTest = false; };
+ReportBatch::ReportBatch() {}
 
-Reporter::Reporter(const char* directory) : batch() {
-    char buf[100];
+ReportBatch::~ReportBatch() {}
 
-    mMaxSize = 30 * 1024 * 1024;  // incident reports can take up to 30MB on disk
-    mMaxCount = 100;
-
-    // string ends up with '/' is a directory
-    String8 dir = String8(directory);
-    if (directory[dir.size() - 1] != '/') dir += "/";
-    mIncidentDirectory = dir.string();
-
-    // There can't be two at the same time because it's on one thread.
-    mStartTime = time(NULL);
-    strftime(buf, sizeof(buf), "incident-%Y%m%d-%H%M%S", localtime(&mStartTime));
-    mFilename = mIncidentDirectory + buf;
+void ReportBatch::addPersistedReport(const IncidentReportArgs& args) {
+    ComponentName component(args.receiverPkg(), args.receiverCls());
+    map<ComponentName, sp<ReportRequest>>::iterator found = mPersistedRequests.find(component);
+    if (found == mPersistedRequests.end()) {
+        // not found
+        mPersistedRequests[component] = new ReportRequest(args, nullptr, -1);
+    } else {
+        // found
+        sp<ReportRequest> request = found->second;
+        request->args.merge(args);
+    }
 }
 
-Reporter::~Reporter() {}
+void ReportBatch::addStreamingReport(const IncidentReportArgs& args,
+        const sp<IIncidentReportStatusListener>& listener, int streamFd) {
+    mStreamingRequests.push_back(new ReportRequest(args, listener, streamFd));
+}
 
-Reporter::run_report_status_t Reporter::runReport(size_t* reportByteSize) {
+bool ReportBatch::empty() const {
+    return mPersistedRequests.size() == 0 && mStreamingRequests.size() == 0;
+}
+
+sp<ReportRequest> ReportBatch::getPersistedRequest(const ComponentName& component) {
+    map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.find(component);
+    if (it != mPersistedRequests.find(component)) {
+        return it->second;
+    } else {
+        return nullptr;
+    }
+}
+
+void ReportBatch::forEachPersistedRequest(const function<void (const sp<ReportRequest>&)>& func) {
+    for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
+            it != mPersistedRequests.end(); it++) {
+        func(it->second);
+    }
+}
+
+void ReportBatch::forEachStreamingRequest(const function<void (const sp<ReportRequest>&)>& func) {
+    for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
+            request != mStreamingRequests.end(); request++) {
+        func(*request);
+    }
+}
+
+void ReportBatch::forEachListener(
+        const function<void (const sp<IIncidentReportStatusListener>&)>& func) {
+    for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
+            it != mPersistedRequests.end(); it++) {
+        sp<IIncidentReportStatusListener> listener = it->second->getListener();
+        if (listener != nullptr) {
+            func(listener);
+        }
+    }
+    for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
+            request != mStreamingRequests.end(); request++) {
+        sp<IIncidentReportStatusListener> listener = (*request)->getListener();
+        if (listener != nullptr) {
+            func(listener);
+        }
+    }
+}
+
+void ReportBatch::forEachListener(int sectionId,
+        const function<void (const sp<IIncidentReportStatusListener>&)>& func) {
+    for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
+            it != mPersistedRequests.end(); it++) {
+        if (it->second->containsSection(sectionId)) {
+            sp<IIncidentReportStatusListener> listener = it->second->getListener();
+            if (listener != nullptr) {
+                func(listener);
+            }
+        }
+    }
+    for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
+            request != mStreamingRequests.end(); request++) {
+        if ((*request)->containsSection(sectionId)) {
+            sp<IIncidentReportStatusListener> listener = (*request)->getListener();
+            if (listener != nullptr) {
+                func(listener);
+            }
+        }
+    }
+}
+
+void ReportBatch::getCombinedPersistedArgs(IncidentReportArgs* result) {
+    for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
+            it != mPersistedRequests.end(); it++) {
+        result->merge(it->second->args);
+    }
+}
+
+bool ReportBatch::containsSection(int sectionId) {
+    // We don't cache this, because in case of error, we remove requests
+    // from the batch, and this is easier than recomputing the set.
+    for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
+            it != mPersistedRequests.end(); it++) {
+        if (it->second->containsSection(sectionId)) {
+            return true;
+        }
+    }
+    for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
+            request != mStreamingRequests.end(); request++) {
+        if ((*request)->containsSection(sectionId)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void ReportBatch::clearPersistedRequests() {
+    mPersistedRequests.clear();
+}
+
+void ReportBatch::getFailedRequests(vector<sp<ReportRequest>>* requests) {
+    for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
+            it != mPersistedRequests.end(); it++) {
+        if (it->second->getStatus() != NO_ERROR) {
+            requests->push_back(it->second);
+        }
+    }
+    for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
+            request != mStreamingRequests.end(); request++) {
+        if ((*request)->getStatus() != NO_ERROR) {
+            requests->push_back(*request);
+        }
+    }
+}
+
+void ReportBatch::removeRequest(const sp<ReportRequest>& request) {
+    for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
+            it != mPersistedRequests.end(); it++) {
+        if (it->second == request) {
+            mPersistedRequests.erase(it);
+            return;
+        }
+    }
+    for (vector<sp<ReportRequest>>::iterator it = mStreamingRequests.begin();
+            it != mStreamingRequests.end(); it++) {
+        if (*it == request) {
+            mStreamingRequests.erase(it);
+            return;
+        }
+    }
+}
+
+// ================================================================================
+ReportWriter::ReportWriter(const sp<ReportBatch>& batch)
+        :mBatch(batch),
+         mPersistedFile(),
+         mMaxPersistedPrivacyPolicy(PRIVACY_POLICY_UNSET) {
+}
+
+ReportWriter::~ReportWriter() {
+}
+
+void ReportWriter::setPersistedFile(sp<ReportFile> file) {
+    mPersistedFile = file;
+}
+
+void ReportWriter::setMaxPersistedPrivacyPolicy(uint8_t privacyPolicy) {
+    mMaxPersistedPrivacyPolicy = privacyPolicy;
+}
+
+void ReportWriter::startSection(int sectionId) {
+    mCurrentSectionId = sectionId;
+    mSectionStartTimeMs = uptimeMillis();
+
+    mSectionStatsCalledForSectionId = -1;
+    mDumpSizeBytes = 0;
+    mDumpDurationMs = 0;
+    mSectionTimedOut = false;
+    mSectionTruncated = false;
+    mSectionBufferSuccess = false;
+    mHadError = false;
+    mSectionErrors.clear();
+    
+}
+
+void ReportWriter::setSectionStats(const FdBuffer& buffer) {
+    mSectionStatsCalledForSectionId = mCurrentSectionId;
+    mDumpSizeBytes = buffer.size();
+    mDumpDurationMs = buffer.durationMs();
+    mSectionTimedOut = buffer.timedOut();
+    mSectionTruncated = buffer.truncated();
+    mSectionBufferSuccess = !buffer.timedOut() && !buffer.truncated();
+}
+
+void ReportWriter::endSection(IncidentMetadata::SectionStats* sectionMetadata) {
+    long endTime = uptimeMillis();
+
+    if (mSectionStatsCalledForSectionId != mCurrentSectionId) {
+        ALOGW("setSectionStats not called for section %d", mCurrentSectionId);
+    }
+
+    sectionMetadata->set_id(mCurrentSectionId);
+    sectionMetadata->set_success((!mHadError) && mSectionBufferSuccess);
+    sectionMetadata->set_report_size_bytes(mMaxSectionDataFilteredSize);
+    sectionMetadata->set_exec_duration_ms(endTime - mSectionStartTimeMs);
+    sectionMetadata->set_dump_size_bytes(mDumpSizeBytes);
+    sectionMetadata->set_dump_duration_ms(mDumpDurationMs);
+    sectionMetadata->set_timed_out(mSectionTimedOut);
+    sectionMetadata->set_is_truncated(mSectionTruncated);
+    sectionMetadata->set_error_msg(mSectionErrors);
+}
+
+void ReportWriter::warning(const Section* section, status_t err, const char* format, ...) {
+    va_list args;
+    va_start(args, format);
+    vflog(section, err, ANDROID_LOG_ERROR, "error", format, args);
+    va_end(args);
+}
+
+void ReportWriter::error(const Section* section, status_t err, const char* format, ...) {
+    va_list args;
+    va_start(args, format);
+    vflog(section, err, ANDROID_LOG_WARN, "warning", format, args);
+    va_end(args);
+}
+
+void ReportWriter::vflog(const Section* section, status_t err, int level, const char* levelText,
+        const char* format, va_list args) {
+    const char* prefixFormat = "%s in section %d (%d) '%s': ";
+    int prefixLen = snprintf(NULL, 0, prefixFormat, levelText, section->id,
+            err, strerror(-err));
+
+    va_list measureArgs;
+    va_copy(measureArgs, args);
+    int messageLen = vsnprintf(NULL, 0, format, args);
+    va_end(measureArgs);
+
+    char* line = (char*)malloc(prefixLen + messageLen + 1);
+    if (line == NULL) {
+        // All hope is lost, just give up.
+        return;
+    }
+
+    sprintf(line, prefixFormat, levelText, section->id, err, strerror(-err));
+
+    vsprintf(line + prefixLen, format, args);
+
+    __android_log_write(level, LOG_TAG, line);
+
+    if (mSectionErrors.length() == 0) {
+        mSectionErrors = line;
+    } else {
+        mSectionErrors += '\n';
+        mSectionErrors += line;
+    }
+
+    free(line);
+
+    if (level >= ANDROID_LOG_ERROR) {
+        mHadError = true;
+    }
+}
+
+// Reads data from FdBuffer and writes it to the requests file descriptor.
+status_t ReportWriter::writeSection(const FdBuffer& buffer) {
+    PrivacyFilter filter(mCurrentSectionId, get_privacy_of_section(mCurrentSectionId));
+
+    // Add the fd for the persisted requests
+    if (mPersistedFile != nullptr) {
+        filter.addFd(new PersistedFilterFd(mMaxPersistedPrivacyPolicy,
+                    mPersistedFile->getDataFileFd(), mPersistedFile));
+    }
+
+    // Add the fds for the streamed requests
+    mBatch->forEachStreamingRequest([&filter, this](const sp<ReportRequest>& request) {
+        if (request->ok() && request->args.containsSection(mCurrentSectionId)) {
+            filter.addFd(new StreamingFilterFd(request->args.getPrivacyPolicy(),
+                        request->getFd(), request));
+        }
+    });
+
+    return filter.writeData(buffer, PRIVACY_POLICY_LOCAL, &mMaxSectionDataFilteredSize);
+}
+
+
+// ================================================================================
+Reporter::Reporter(const sp<WorkDirectory>& workDirectory, const sp<ReportBatch>& batch)
+        :mWorkDirectory(workDirectory),
+         mWriter(batch),
+         mBatch(batch) {
+}
+
+Reporter::~Reporter() {
+}
+
+void Reporter::runReport(size_t* reportByteSize) {
     status_t err = NO_ERROR;
-    bool needMainFd = false;
-    int mainFd = -1;
-    int mainDest = -1;
-    int sectionCount = 0;
-    HeaderSection headers;
-    MetadataSection metadataSection;
-    std::string buildType = android::base::GetProperty("ro.build.type", "");
-    const bool isUserdebugOrEng = buildType == "userdebug" || buildType == "eng";
 
-    // See if we need the main file
-    for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
-        if ((*it)->fd < 0 && mainFd < 0) {
-            needMainFd = true;
-            mainDest = (*it)->args.dest();
-            break;
-        }
-    }
-    if (needMainFd) {
-        // Create the directory
-        if (!isTest) err = create_directory(mIncidentDirectory);
-        if (err != NO_ERROR) {
-            goto DONE;
-        }
+    IncidentMetadata metadata;
+    int persistedPrivacyPolicy = PRIVACY_POLICY_UNSET;
 
-        // If there are too many files in the directory (for whatever reason),
-        // delete the oldest ones until it's under the limit. Doing this first
-        // does mean that we can go over, so the max size is not a hard limit.
-        if (!isTest) clean_directory(mIncidentDirectory, mMaxSize, mMaxCount);
-
-        // Open the file.
-        err = create_file(&mainFd);
-        if (err != NO_ERROR) {
-            goto DONE;
-        }
-
-        // Add to the set
-        batch.setMainFd(mainFd);
-        batch.setMainDest(mainDest);
-    }
+    (*reportByteSize) = 0;
 
     // Tell everyone that we're starting.
-    for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
-        if ((*it)->listener != NULL) {
-            (*it)->listener->onReportStarted();
+    ALOGI("Starting incident report");
+    mBatch->forEachListener([](const auto& listener) { listener->onReportStarted(); });
+
+    if (mBatch->hasPersistedReports()) {
+        // Open a work file to contain the contents of all of the persisted reports.
+        // For this block, if we can't initialize the report file for some reason,
+        // then we will remove the persisted ReportRequests from the report, but
+        // continue with the streaming ones.
+        mPersistedFile = mWorkDirectory->createReportFile();
+        ALOGI("Report will be persisted: envelope: %s  data: %s",
+                mPersistedFile->getEnvelopeFileName().c_str(),
+                mPersistedFile->getDataFileName().c_str());
+
+        // Record all of the metadata to the persisted file's metadata file.
+        // It will be read from there and reconstructed as the actual reports
+        // are sent out.
+        if (mPersistedFile != nullptr) {
+            mBatch->forEachPersistedRequest([this, &persistedPrivacyPolicy](
+                        const sp<ReportRequest>& request) {
+                mPersistedFile->addReport(request->args);
+                if (request->args.getPrivacyPolicy() < persistedPrivacyPolicy) {
+                    persistedPrivacyPolicy = request->args.getPrivacyPolicy();
+                }
+            });
+            mPersistedFile->setMaxPersistedPrivacyPolicy(persistedPrivacyPolicy);
+            err = mPersistedFile->saveEnvelope();
+            if (err != NO_ERROR) {
+                mWorkDirectory->remove(mPersistedFile);
+                mPersistedFile = nullptr;
+            }
+            mWriter.setMaxPersistedPrivacyPolicy(persistedPrivacyPolicy);
+        }
+
+        if (mPersistedFile != nullptr) {
+            err = mPersistedFile->startWritingDataFile();
+            if (err != NO_ERROR) {
+                mWorkDirectory->remove(mPersistedFile);
+                mPersistedFile = nullptr;
+            }
+        }
+
+        if (mPersistedFile != nullptr) {
+            mWriter.setPersistedFile(mPersistedFile);
+        } else {
+            ALOGW("Error creating the persisted file, so clearing persisted reports.");
+            // If we couldn't open the file (permissions err, etc), then
+            // we still want to proceed with any streaming reports, but
+            // cancel all of the persisted ones.
+            mBatch->forEachPersistedRequest([](const sp<ReportRequest>& request) {
+                sp<IIncidentReportStatusListener> listener = request->getListener();
+                if (listener != nullptr) {
+                    listener->onReportFailed();
+                }
+            });
+            mBatch->clearPersistedRequests();
         }
     }
 
-    // Write the incident headers
-    headers.Execute(&batch);
+    // If we have a persisted ID, then we allow all the readers to see that.  There's
+    // enough in the data to allow for a join, and nothing in here that intrisincally
+    // could ever prevent that, so just give them the ID.  If we don't have that then we
+    // make and ID that's extremely likely to be unique, but clock resetting could allow
+    // it to be duplicate.
+    int64_t reportId;
+    if (mPersistedFile != nullptr) {
+        reportId = mPersistedFile->getTimestampNs();
+    } else {
+        struct timespec spec;
+        clock_gettime(CLOCK_REALTIME, &spec);
+        reportId = (spec.tv_sec) * 1000 + spec.tv_nsec;
+    }
+
+    // Write the incident report headers - each request gets its own headers.  It's different
+    // from the other top-level fields in IncidentReport that are the sections where the rest
+    // is all shared data (although with their own individual privacy filtering).
+    mBatch->forEachStreamingRequest([](const sp<ReportRequest>& request) {
+        const vector<vector<uint8_t>>& headers = request->args.headers();
+        for (vector<vector<uint8_t>>::const_iterator buf = headers.begin(); buf != headers.end();
+             buf++) {
+            // If there was an error now, there will be an error later and we will remove
+            // it from the list then.
+            write_header_section(request->getFd(), buf->data(), buf->size());
+        }
+    });
+
+    // If writing to any of the headers failed, we don't want to keep processing
+    // sections for it.
+    cancel_and_remove_failed_requests();
 
     // For each of the report fields, see if we need it, and if so, execute the command
     // and report to those that care that we're doing it.
     for (const Section** section = SECTION_LIST; *section; section++) {
-        const int id = (*section)->id;
-        if ((*section)->userdebugAndEngOnly && !isUserdebugOrEng) {
-            VLOG("Skipping incident report section %d '%s' because it's limited to userdebug/eng",
-                  id, (*section)->name.string());
+        const int sectionId = (*section)->id;
+
+        // If nobody wants this section, skip it.
+        if (!mBatch->containsSection(sectionId)) {
             continue;
         }
-        if (this->batch.containsSection(id)) {
-            VLOG("Taking incident report section %d '%s'", id, (*section)->name.string());
-            for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
-                if ((*it)->listener != NULL && (*it)->args.containsSection(id)) {
-                    (*it)->listener->onReportSectionStatus(
-                            id, IIncidentReportStatusListener::STATUS_STARTING);
-                }
-            }
 
-            // Execute - go get the data and write it into the file descriptors.
-            IncidentMetadata::SectionStats* stats = batch.sectionStats(id);
-            int64_t startTime = uptimeMillis();
-            err = (*section)->Execute(&batch);
-            int64_t endTime = uptimeMillis();
-            stats->set_exec_duration_ms(endTime - startTime);
-            if (err != NO_ERROR) {
-                ALOGW("Incident section %s (%d) failed: %s. Stopping report.",
-                      (*section)->name.string(), id, strerror(-err));
-                // Execute() has already recorded this status. Only update if there's new failure.
-                stats->set_success(false);
-                goto DONE;
-            }
-            (*reportByteSize) += stats->report_size_bytes();
+        ALOGD("Start incident report section %d '%s'", sectionId, (*section)->name.string());
+        IncidentMetadata::SectionStats* sectionMetadata = metadata.add_sections();
 
-            // Notify listener of starting
-            for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
-                if ((*it)->listener != NULL && (*it)->args.containsSection(id)) {
-                    (*it)->listener->onReportSectionStatus(
-                            id, IIncidentReportStatusListener::STATUS_FINISHED);
-                }
-            }
-            VLOG("Finish incident report section %d '%s'", id, (*section)->name.string());
-            sectionCount++;
+        // Notify listener of starting
+        mBatch->forEachListener(sectionId, [sectionId](const auto& listener) {
+            listener->onReportSectionStatus(
+                    sectionId, IIncidentReportStatusListener::STATUS_STARTING);
+        });
+
+        // Go get the data and write it into the file descriptors.
+        mWriter.startSection(sectionId);
+        err = (*section)->Execute(&mWriter);
+        mWriter.endSection(sectionMetadata);
+
+        // Sections returning errors are fatal. Most errors should not be fatal.
+        if (err != NO_ERROR) {
+            mWriter.error((*section), err, "Section failed. Stopping report.");
+            goto DONE;
         }
+
+        // The returned max data size is used for throttling too many incident reports.
+        (*reportByteSize) += sectionMetadata->report_size_bytes();
+
+        // For any requests that failed during this section, remove them now.  We do this
+        // before calling back about section finished, so listeners do not erroniously get the
+        // impression that the section succeeded.  But we do it here instead of inside
+        // writeSection so that the callback is done from a known context and not from the
+        // bowels of a section, where changing the batch could cause odd errors.
+        cancel_and_remove_failed_requests();
+
+        // Notify listener of finishing
+        mBatch->forEachListener(sectionId, [sectionId](const auto& listener) {
+                listener->onReportSectionStatus(
+                        sectionId, IIncidentReportStatusListener::STATUS_FINISHED);
+        });
+
+        ALOGD("Finish incident report section %d '%s'", sectionId, (*section)->name.string());
     }
 
 DONE:
-    ALOGD("Incident reporting took %d sections.", sectionCount);
-    // Reports the metdadata when taking the incident report.
-    if (!isTest) metadataSection.Execute(&batch);
+    // Finish up the persisted file.
+    if (mPersistedFile != nullptr) {
+        mPersistedFile->closeDataFile();
 
-    // Close the file.
-    if (mainFd >= 0) {
-        close(mainFd);
-    }
+        // Set the stored metadata
+        IncidentReportArgs combinedArgs;
+        mBatch->getCombinedPersistedArgs(&combinedArgs);
+        IncidentMetadata persistedMetadata;
+        make_metadata(&persistedMetadata, metadata, mPersistedFile->getTimestampNs(),
+                persistedPrivacyPolicy, &combinedArgs);
+        mPersistedFile->setMetadata(persistedMetadata);
 
-    // Tell everyone that we're done.
-    for (ReportRequestSet::iterator it = batch.begin(); it != batch.end(); it++) {
-        if ((*it)->listener != NULL) {
-            if (err == NO_ERROR) {
-                (*it)->listener->onReportFinished();
-            } else {
-                (*it)->listener->onReportFailed();
-            }
+        mPersistedFile->markCompleted();
+        err = mPersistedFile->saveEnvelope();
+        if (err != NO_ERROR) {
+            ALOGW("mPersistedFile->saveEnvelope returned %s. Won't send broadcast",
+                    strerror(-err));
+            // Abandon ship.
+            mWorkDirectory->remove(mPersistedFile);
         }
     }
 
-    // Put the report into dropbox.
-    if (needMainFd && err == NO_ERROR) {
-        sp<DropBoxManager> dropbox = new DropBoxManager();
-        Status status = dropbox->addFile(String16("incident"), mFilename, 0);
-        ALOGD("Incident report done. dropbox status=%s\n", status.toString8().string());
-        if (!status.isOk()) {
-            return REPORT_NEEDS_DROPBOX;
+    // Write the metadata to the streaming ones
+    mBatch->forEachStreamingRequest([reportId, &metadata](const sp<ReportRequest>& request) {
+        IncidentMetadata streamingMetadata;
+        make_metadata(&streamingMetadata, metadata, reportId,
+                request->args.getPrivacyPolicy(), request);
+        status_t nonFatalErr = write_section(request->getFd(), FIELD_ID_METADATA,
+                streamingMetadata);
+        if (nonFatalErr != NO_ERROR) {
+            ALOGW("Error writing the metadata to streaming incident report.  This is the last"
+                    " thing so we won't return an error: %s", strerror(nonFatalErr));
         }
+    });
 
-        // If the status was ok, delete the file. If not, leave it around until the next
-        // boot or the next checkin. If the directory gets too big older files will
-        // be rotated out.
-        if (!isTest) unlink(mFilename.c_str());
+    // Finish up the streaming ones.
+    mBatch->forEachStreamingRequest([](const sp<ReportRequest>& request) {
+        request->closeFd();
+    });
+
+    // Tell the listeners that we're done.
+    if (err == NO_ERROR) {
+        mBatch->forEachListener([](const auto& listener) {
+            listener->onReportFinished();
+        });
+    } else {
+        mBatch->forEachListener([](const auto& listener) {
+            listener->onReportFailed();
+        });
     }
 
-    return REPORT_FINISHED;
+    ALOGI("Done taking incident report err=%s", strerror(-err));
 }
 
-/**
- * Create our output file and set the access permissions to -rw-rw----
- */
-status_t Reporter::create_file(int* fd) {
-    const char* filename = mFilename.c_str();
-
-    *fd = open(filename, O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC, 0660);
-    if (*fd < 0) {
-        ALOGE("Couldn't open incident file: %s (%s)", filename, strerror(errno));
-        return -errno;
-    }
-
-    // Override umask. Not super critical. If it fails go on with life.
-    chmod(filename, 0660);
-
-    if (chown(filename, AID_INCIDENTD, AID_INCIDENTD)) {
-        ALOGE("Unable to change ownership of incident file %s: %s\n", filename, strerror(errno));
-        status_t err = -errno;
-        unlink(mFilename.c_str());
-        return err;
-    }
-
-    return NO_ERROR;
-}
-
-Reporter::run_report_status_t Reporter::upload_backlog() {
-    DIR* dir;
-    struct dirent* entry;
-    struct stat st;
-    status_t err;
-
-    ALOGD("Start uploading backlogs in %s", INCIDENT_DIRECTORY);
-    if ((err = create_directory(INCIDENT_DIRECTORY)) != NO_ERROR) {
-        ALOGE("directory doesn't exist: %s", strerror(-err));
-        return REPORT_FINISHED;
-    }
-
-    if ((dir = opendir(INCIDENT_DIRECTORY)) == NULL) {
-        ALOGE("Couldn't open incident directory: %s", INCIDENT_DIRECTORY);
-        return REPORT_NEEDS_DROPBOX;
-    }
-
-    sp<DropBoxManager> dropbox = new DropBoxManager();
-
-    // Enumerate, count and add up size
-    int count = 0;
-    while ((entry = readdir(dir)) != NULL) {
-        if (entry->d_name[0] == '.') {
-            continue;
+void Reporter::cancel_and_remove_failed_requests() {
+    // Handle a failure in the persisted file
+    if (mPersistedFile != nullptr) {
+        if (mPersistedFile->getWriteError() != NO_ERROR) {
+            ALOGW("Error writing to the persisted file (%s). Closing it and canceling.",
+                    strerror(-mPersistedFile->getWriteError()));
+            mBatch->forEachPersistedRequest([this](const sp<ReportRequest>& request) {
+                sp<IIncidentReportStatusListener> listener = request->getListener();
+                if (listener != nullptr) {
+                    listener->onReportFailed();
+                }
+                mBatch->removeRequest(request);
+            });
+            mWriter.setPersistedFile(nullptr);
+            mPersistedFile->closeDataFile();
+            mWorkDirectory->remove(mPersistedFile);
+            mPersistedFile = nullptr;
         }
-        String8 filename = String8(INCIDENT_DIRECTORY) + entry->d_name;
-        if (stat(filename.string(), &st) != 0) {
-            ALOGE("Unable to stat file %s", filename.string());
-            continue;
-        }
-        if (!S_ISREG(st.st_mode)) {
-            continue;
-        }
-
-        Status status = dropbox->addFile(String16("incident"), filename.string(), 0);
-        ALOGD("Incident report done. dropbox status=%s\n", status.toString8().string());
-        if (!status.isOk()) {
-            return REPORT_NEEDS_DROPBOX;
-        }
-
-        // If the status was ok, delete the file. If not, leave it around until the next
-        // boot or the next checkin. If the directory gets too big older files will
-        // be rotated out.
-        unlink(filename.string());
-        count++;
     }
-    ALOGD("Successfully uploaded %d files to Dropbox.", count);
-    closedir(dir);
 
-    return REPORT_FINISHED;
+    // Handle failures in the streaming files
+    vector<sp<ReportRequest>> failed;
+    mBatch->getFailedRequests(&failed);
+    for (sp<ReportRequest>& request: failed) {
+        ALOGW("Error writing to a request stream (%s). Closing it and canceling.",
+                strerror(-request->getStatus()));
+        sp<IIncidentReportStatusListener> listener = request->getListener();
+        if (listener != nullptr) {
+            listener->onReportFailed();
+        }
+        request->closeFd();  // Will only close the streaming ones.
+        mBatch->removeRequest(request);
+    }
 }
 
 }  // namespace incidentd
diff --git a/cmds/incidentd/src/Reporter.h b/cmds/incidentd/src/Reporter.h
index 2a3abd7..e7a474f 100644
--- a/cmds/incidentd/src/Reporter.h
+++ b/cmds/incidentd/src/Reporter.h
@@ -15,103 +15,247 @@
  */
 #pragma once
 
-#ifndef REPORTER_H
-#define REPORTER_H
+#include "FdBuffer.h"
+#include "Throttler.h"
+#include "WorkDirectory.h"
 
+#include "frameworks/base/core/proto/android/os/metadata.pb.h"
+#include <android/content/ComponentName.h>
 #include <android/os/IIncidentReportStatusListener.h>
 #include <android/os/IncidentReportArgs.h>
+#include <android/util/protobuf.h>
 
 #include <map>
 #include <string>
 #include <vector>
 
 #include <time.h>
-
-#include "Throttler.h"
-#include "frameworks/base/libs/incident/proto/android/os/metadata.pb.h"
+#include <stdarg.h>
 
 namespace android {
 namespace os {
 namespace incidentd {
 
+using namespace std;
+using namespace android::content;
+using namespace android::os;
+
+class Section;
+
 // ================================================================================
-struct ReportRequest : public virtual RefBase {
+class ReportRequest : public virtual RefBase {
+public:
     IncidentReportArgs args;
-    sp<IIncidentReportStatusListener> listener;
-    int fd;
-    status_t err;
 
     ReportRequest(const IncidentReportArgs& args, const sp<IIncidentReportStatusListener>& listener,
                   int fd);
     virtual ~ReportRequest();
 
+    bool isStreaming() { return mIsStreaming; }
+
+    void setStatus(status_t err) { mStatus = err; }
+    status_t getStatus() const { return mStatus; }
+
     bool ok();  // returns true if the request is ok for write.
+
+    bool containsSection(int sectionId) const { return args.containsSection(sectionId); }
+
+    sp<IIncidentReportStatusListener> getListener() { return mListener; }
+
+    int getFd() { return mFd; }
+
+    int setPersistedFd(int fd);
+
+    void closeFd();
+
+private:
+    sp<IIncidentReportStatusListener> mListener;
+    int mFd;
+    bool mIsStreaming;
+    status_t mStatus;
 };
 
 // ================================================================================
-class ReportRequestSet {
+class ReportBatch : public virtual RefBase {
 public:
-    ReportRequestSet();
-    ~ReportRequestSet();
+    ReportBatch();
+    virtual ~ReportBatch();
 
-    void add(const sp<ReportRequest>& request);
-    void setMainFd(int fd);
-    void setMainDest(int dest);
+    // TODO: Should there be some kind of listener associated with the
+    // component? Could be good for getting status updates e.g. in the ui,
+    // as it progresses.  But that's out of scope for now.
 
-    typedef vector<sp<ReportRequest>>::iterator iterator;
+    /**
+     * Schedule a report for the "main" report, where it will be delivered to
+     * the uploaders and/or dropbox.
+     */
+    void addPersistedReport(const IncidentReportArgs& args);
 
-    iterator begin() { return mRequests.begin(); }
-    iterator end() { return mRequests.end(); }
+    /**
+     * Adds a ReportRequest to the queue for one that has a listener an and fd
+     */
+    void addStreamingReport(const IncidentReportArgs& args,
+           const sp<IIncidentReportStatusListener>& listener, int streamFd);
 
-    int mainFd() { return mMainFd; }
-    int mainDest() { return mMainDest; }
-    IncidentMetadata& metadata() { return mMetadata; }
-    map<int, IncidentMetadata::SectionStats>& allSectionStats() { return mSectionStats; }
+    /**
+     * Returns whether both queues are empty.
+     */
+    bool empty() const;
 
+    /**
+     * Returns whether there are any persisted records.
+     */
+    bool hasPersistedReports() const { return mPersistedRequests.size() > 0; }
+
+    /**
+     * Return the persisted request for the given component, or nullptr.
+     */
+    sp<ReportRequest> getPersistedRequest(const ComponentName& component);
+
+    /**
+     * Call func(request) for each Request.
+     */
+    void forEachPersistedRequest(const function<void (const sp<ReportRequest>&)>& func);
+
+    /**
+     * Call func(request) for each Request.
+     */
+    void forEachStreamingRequest(const function<void (const sp<ReportRequest>&)>& func);
+
+    /**
+     * Call func(request) for each file descriptor that has 
+     */
+    void forEachFd(int sectionId, const function<void (const sp<ReportRequest>&)>& func);
+
+    /**
+     * Call func(listener) for every listener in this batch.
+     */
+    void forEachListener(const function<void (const sp<IIncidentReportStatusListener>&)>& func);
+
+    /**
+     * Call func(listener) for every listener in this batch that requests
+     * sectionId.
+     */
+    void forEachListener(int sectionId,
+            const function<void (const sp<IIncidentReportStatusListener>&)>& func);
+    /**
+     * Get an IncidentReportArgs that represents the combined args for the
+     * persisted requests.
+     */
+    void getCombinedPersistedArgs(IncidentReportArgs* results);
+
+    /**
+     * Return whether any of the requests contain the section.
+     */
     bool containsSection(int id);
-    IncidentMetadata::SectionStats* sectionStats(int id);
+
+    /**
+     * Remove all of the broadcast (persisted) requests.
+     */
+    void clearPersistedRequests();
+
+    /**
+     * Get the requests that have encountered errors.
+     */
+    void getFailedRequests(vector<sp<ReportRequest>>* requests);
+
+    /**
+     * Remove the request from whichever list it's in.
+     */
+    void removeRequest(const sp<ReportRequest>& request);
+
 
 private:
-    vector<sp<ReportRequest>> mRequests;
-    IncidentReportArgs mSections;
-    int mMainFd;
-    int mMainDest;
+    map<ComponentName, sp<ReportRequest>> mPersistedRequests;
+    vector<sp<ReportRequest>> mStreamingRequests;
+};
 
-    IncidentMetadata mMetadata;
-    map<int, IncidentMetadata::SectionStats> mSectionStats;
+// ================================================================================
+class ReportWriter {
+public:
+    ReportWriter(const sp<ReportBatch>& batch);
+    ~ReportWriter();
+
+    void setPersistedFile(sp<ReportFile> file);
+    void setMaxPersistedPrivacyPolicy(uint8_t privacyPolicy);
+
+    void startSection(int sectionId);
+    void endSection(IncidentMetadata::SectionStats* sectionStats);
+
+    void setSectionStats(const FdBuffer& buffer);
+
+    void warning(const Section* section, status_t err, const char* format, ...);
+    void error(const Section* section, status_t err, const char* format, ...);
+
+    status_t writeSection(const FdBuffer& buffer);
+
+private:
+    // Data about all requests
+    sp<ReportBatch> mBatch;
+
+    /**
+     * The file on disk where we will store the persisted file.
+     */
+    sp<ReportFile> mPersistedFile;
+
+    /**
+     * The least restricted privacy policy of all of the perstited
+     * requests. We pre-filter to that to save disk space.
+     */
+    uint8_t mMaxPersistedPrivacyPolicy;
+
+    /**
+     * The current section that is being written.
+     */
+    int mCurrentSectionId;
+
+    /**
+     * The time that that the current section was started.
+     */
+    int64_t mSectionStartTimeMs;
+
+    /**
+     * The last section that setSectionStats was called for, so if someone misses
+     * it we can log that.
+     */
+    int mSectionStatsCalledForSectionId;
+
+    /*
+     * Fields for IncidentMetadata.SectionStats.  Set by setSectionStats.  Accessed by
+     * getSectionStats.
+     */
+    int32_t mDumpSizeBytes;
+    int64_t mDumpDurationMs;
+    bool mSectionTimedOut;
+    bool mSectionTruncated;
+    bool mSectionBufferSuccess;
+    bool mHadError;
+    string mSectionErrors;
+    size_t mMaxSectionDataFilteredSize;
+
+    void vflog(const Section* section, status_t err, int level, const char* levelText,
+        const char* format, va_list args);
 };
 
 // ================================================================================
 class Reporter : public virtual RefBase {
 public:
-    enum run_report_status_t { REPORT_FINISHED = 0, REPORT_NEEDS_DROPBOX = 1 };
+    Reporter(const sp<WorkDirectory>& workDirectory, const sp<ReportBatch>& batch);
 
-    ReportRequestSet batch;
-
-    Reporter();                       // PROD must use this constructor.
-    explicit Reporter(const char* directory);  // For testing purpose only.
     virtual ~Reporter();
 
     // Run the report as described in the batch and args parameters.
-    run_report_status_t runReport(size_t* reportByteSize);
-
-    static run_report_status_t upload_backlog();
+    void runReport(size_t* reportByteSize);
 
 private:
-    String8 mIncidentDirectory;
+    sp<WorkDirectory> mWorkDirectory;
+    ReportWriter mWriter;
+    sp<ReportBatch> mBatch;
+    sp<ReportFile> mPersistedFile;
 
-    string mFilename;
-    off_t mMaxSize;
-    size_t mMaxCount;
-    time_t mStartTime;
-
-    status_t create_file(int* fd);
-
-    bool isTest = true;  // default to true for testing
+    void cancel_and_remove_failed_requests();
 };
 
 }  // namespace incidentd
 }  // namespace os
 }  // namespace android
-
-#endif  // REPORTER_H
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 32ec1ba..935a7c4 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -25,8 +25,10 @@
 #include <set>
 
 #include <android-base/file.h>
+#include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android/util/protobuf.h>
+#include <android/util/ProtoOutputStream.h>
 #include <binder/IServiceManager.h>
 #include <debuggerd/client.h>
 #include <dumputils/dump_utils.h>
@@ -37,7 +39,6 @@
 
 #include "FdBuffer.h"
 #include "Privacy.h"
-#include "PrivacyBuffer.h"
 #include "frameworks/base/core/proto/android/os/backtrace.proto.h"
 #include "frameworks/base/core/proto/android/os/data.proto.h"
 #include "frameworks/base/core/proto/android/util/log.proto.h"
@@ -51,7 +52,6 @@
 using namespace android::util;
 
 // special section ids
-const int FIELD_ID_INCIDENT_HEADER = 1;
 const int FIELD_ID_INCIDENT_METADATA = 2;
 
 // incident section parameters
@@ -64,206 +64,18 @@
 }
 
 // ================================================================================
-static status_t write_section_header(int fd, int sectionId, size_t size) {
-    uint8_t buf[20];
-    uint8_t* p = write_length_delimited_tag_header(buf, sectionId, size);
-    return WriteFully(fd, buf, p - buf) ? NO_ERROR : -errno;
-}
-
-static void write_section_stats(IncidentMetadata::SectionStats* stats, const FdBuffer& buffer) {
-    stats->set_dump_size_bytes(buffer.data().size());
-    stats->set_dump_duration_ms(buffer.durationMs());
-    stats->set_timed_out(buffer.timedOut());
-    stats->set_is_truncated(buffer.truncated());
-    stats->set_success(!buffer.timedOut() && !buffer.truncated());
-}
-
-// Reads data from FdBuffer and writes it to the requests file descriptor.
-static status_t write_report_requests(const int id, const FdBuffer& buffer,
-                                      ReportRequestSet* requests) {
-    status_t err = -EBADF;
-    EncodedBuffer::iterator data = buffer.data();
-    PrivacyBuffer privacyBuffer(get_privacy_of_section(id), data);
-    IncidentMetadata::SectionStats* stats = requests->sectionStats(id);
-    int nPassed = 0;
-
-    // The streaming ones, group requests by spec in order to save unnecessary strip operations
-    map<PrivacySpec, vector<sp<ReportRequest>>> requestsBySpec;
-    for (auto it = requests->begin(); it != requests->end(); it++) {
-        sp<ReportRequest> request = *it;
-        if (!request->ok() || !request->args.containsSection(id)) {
-            continue;  // skip invalid request
-        }
-        PrivacySpec spec = PrivacySpec::new_spec(request->args.dest());
-        requestsBySpec[spec].push_back(request);
-    }
-
-    for (auto mit = requestsBySpec.begin(); mit != requestsBySpec.end(); mit++) {
-        PrivacySpec spec = mit->first;
-        err = privacyBuffer.strip(spec);
-        if (err != NO_ERROR) {
-            // Privacy Buffer is corrupted, probably due to an ill-formatted proto. This is a
-            // non-fatal error. The whole report is still valid. So just log the failure.
-            ALOGW("Failed to strip section %d with spec %d: %s",
-                id, spec.dest, strerror(-err));
-            stats->set_success(false);
-            stats->set_error_msg("Failed to strip section: privacy buffer corrupted, probably "
-                "due to an ill-formatted proto");
-            nPassed++;
-            continue;
-        }
-
-        if (privacyBuffer.size() == 0) continue;
-
-        for (auto it = mit->second.begin(); it != mit->second.end(); it++) {
-            sp<ReportRequest> request = *it;
-            err = write_section_header(request->fd, id, privacyBuffer.size());
-            if (err != NO_ERROR) {
-                request->err = err;
-                continue;
-            }
-            err = privacyBuffer.flush(request->fd);
-            if (err != NO_ERROR) {
-                request->err = err;
-                continue;
-            }
-            nPassed++;
-            VLOG("Section %d flushed %zu bytes to fd %d with spec %d", id, privacyBuffer.size(),
-                 request->fd, spec.dest);
-        }
-        privacyBuffer.clear();
-    }
-
-    // The dropbox file
-    if (requests->mainFd() >= 0) {
-        PrivacySpec spec = PrivacySpec::new_spec(requests->mainDest());
-        err = privacyBuffer.strip(spec);
-        if (err != NO_ERROR) {
-            ALOGW("Failed to strip section %d with spec %d for dropbox: %s",
-                id, spec.dest, strerror(-err));
-            stats->set_success(false);
-            stats->set_error_msg("Failed to strip section: privacy buffer corrupted, probably "
-                "due to an ill-formatted proto");
-            nPassed++;
-            goto DONE;
-        }
-        if (privacyBuffer.size() == 0) goto DONE;
-
-        err = write_section_header(requests->mainFd(), id, privacyBuffer.size());
-        if (err != NO_ERROR) {
-            requests->setMainFd(-1);
-            goto DONE;
-        }
-        err = privacyBuffer.flush(requests->mainFd());
-        if (err != NO_ERROR) {
-            requests->setMainFd(-1);
-            goto DONE;
-        }
-        nPassed++;
-        VLOG("Section %d flushed %zu bytes to dropbox %d with spec %d", id, privacyBuffer.size(),
-             requests->mainFd(), spec.dest);
-        // Reports bytes of the section uploaded via dropbox after filtering.
-        requests->sectionStats(id)->set_report_size_bytes(privacyBuffer.size());
-    }
-
-DONE:
-    // only returns error if there is no fd to write to.
-    return nPassed > 0 ? NO_ERROR : err;
-}
-
-// ================================================================================
-Section::Section(int i, int64_t timeoutMs, bool userdebugAndEngOnly)
+Section::Section(int i, int64_t timeoutMs)
     : id(i),
-      timeoutMs(timeoutMs),
-      userdebugAndEngOnly(userdebugAndEngOnly) {}
+      timeoutMs(timeoutMs) {
+}
 
 Section::~Section() {}
 
 // ================================================================================
-HeaderSection::HeaderSection() : Section(FIELD_ID_INCIDENT_HEADER, 0) {}
-
-HeaderSection::~HeaderSection() {}
-
-status_t HeaderSection::Execute(ReportRequestSet* requests) const {
-    for (ReportRequestSet::iterator it = requests->begin(); it != requests->end(); it++) {
-        const sp<ReportRequest> request = *it;
-        const vector<vector<uint8_t>>& headers = request->args.headers();
-
-        for (vector<vector<uint8_t>>::const_iterator buf = headers.begin(); buf != headers.end();
-             buf++) {
-            if (buf->empty()) continue;
-
-            // So the idea is only requests with negative fd are written to dropbox file.
-            int fd = request->fd >= 0 ? request->fd : requests->mainFd();
-            write_section_header(fd, id, buf->size());
-            WriteFully(fd, (uint8_t const*)buf->data(), buf->size());
-            // If there was an error now, there will be an error later and we will remove
-            // it from the list then.
-        }
-    }
-    return NO_ERROR;
-}
-// ================================================================================
-MetadataSection::MetadataSection() : Section(FIELD_ID_INCIDENT_METADATA, 0) {}
-
-MetadataSection::~MetadataSection() {}
-
-status_t MetadataSection::Execute(ReportRequestSet* requests) const {
-    ProtoOutputStream proto;
-    IncidentMetadata metadata = requests->metadata();
-    proto.write(FIELD_TYPE_ENUM | IncidentMetadata::kDestFieldNumber, metadata.dest());
-    proto.write(FIELD_TYPE_INT32 | IncidentMetadata::kRequestSizeFieldNumber,
-                metadata.request_size());
-    proto.write(FIELD_TYPE_BOOL | IncidentMetadata::kUseDropboxFieldNumber, metadata.use_dropbox());
-    for (auto iter = requests->allSectionStats().begin(); iter != requests->allSectionStats().end();
-         iter++) {
-        IncidentMetadata::SectionStats stats = iter->second;
-        uint64_t token = proto.start(FIELD_TYPE_MESSAGE | IncidentMetadata::kSectionsFieldNumber);
-        proto.write(FIELD_TYPE_INT32 | IncidentMetadata::SectionStats::kIdFieldNumber, stats.id());
-        proto.write(FIELD_TYPE_BOOL | IncidentMetadata::SectionStats::kSuccessFieldNumber,
-                    stats.success());
-        proto.write(FIELD_TYPE_INT32 | IncidentMetadata::SectionStats::kReportSizeBytesFieldNumber,
-                    stats.report_size_bytes());
-        proto.write(FIELD_TYPE_INT64 | IncidentMetadata::SectionStats::kExecDurationMsFieldNumber,
-                    stats.exec_duration_ms());
-        proto.write(FIELD_TYPE_INT32 | IncidentMetadata::SectionStats::kDumpSizeBytesFieldNumber,
-                    stats.dump_size_bytes());
-        proto.write(FIELD_TYPE_INT64 | IncidentMetadata::SectionStats::kDumpDurationMsFieldNumber,
-                    stats.dump_duration_ms());
-        proto.write(FIELD_TYPE_BOOL | IncidentMetadata::SectionStats::kTimedOutFieldNumber,
-                    stats.timed_out());
-        proto.write(FIELD_TYPE_BOOL | IncidentMetadata::SectionStats::kIsTruncatedFieldNumber,
-                    stats.is_truncated());
-        proto.write(FIELD_TYPE_STRING | IncidentMetadata::SectionStats::kErrorMsgFieldNumber,
-                    stats.error_msg());
-        proto.end(token);
-    }
-
-    for (ReportRequestSet::iterator it = requests->begin(); it != requests->end(); it++) {
-        const sp<ReportRequest> request = *it;
-        if (request->fd < 0 || request->err != NO_ERROR) {
-            continue;
-        }
-        write_section_header(request->fd, id, proto.size());
-        if (!proto.flush(request->fd)) {
-            ALOGW("Failed to write metadata to fd %d", request->fd);
-            // we don't fail if we can't write to a single request's fd.
-        }
-    }
-    if (requests->mainFd() >= 0) {
-        write_section_header(requests->mainFd(), id, proto.size());
-        if (!proto.flush(requests->mainFd())) {
-            ALOGW("Failed to write metadata to dropbox fd %d", requests->mainFd());
-            return -1;
-        }
-    }
-    return NO_ERROR;
-}
-// ================================================================================
 static inline bool isSysfs(const char* filename) { return strncmp(filename, "/sys/", 5) == 0; }
 
 FileSection::FileSection(int id, const char* filename, const int64_t timeoutMs)
-    : Section(id, timeoutMs, false), mFilename(filename) {
+    : Section(id, timeoutMs), mFilename(filename) {
     name = "file ";
     name += filename;
     mIsSysfs = isSysfs(filename);
@@ -271,7 +83,7 @@
 
 FileSection::~FileSection() {}
 
-status_t FileSection::Execute(ReportRequestSet* requests) const {
+status_t FileSection::Execute(ReportWriter* writer) const {
     // read from mFilename first, make sure the file is available
     // add O_CLOEXEC to make sure it is closed when exec incident helper
     unique_fd fd(open(mFilename, O_RDONLY | O_CLOEXEC));
@@ -301,7 +113,7 @@
     status_t readStatus = buffer.readProcessedDataInStream(fd.get(), std::move(p2cPipe.writeFd()),
                                                            std::move(c2pPipe.readFd()),
                                                            this->timeoutMs, mIsSysfs);
-    write_section_stats(requests->sectionStats(this->id), buffer);
+    writer->setSectionStats(buffer);
     if (readStatus != NO_ERROR || buffer.timedOut()) {
         ALOGW("[%s] failed to read data from incident helper: %s, timedout: %s",
               this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
@@ -315,7 +127,7 @@
         return ihStatus;
     }
 
-    return write_report_requests(this->id, buffer, requests);
+    return writer->writeSection(buffer);
 }
 // ================================================================================
 GZipSection::GZipSection(int id, const char* filename, ...) : Section(id) {
@@ -332,7 +144,7 @@
 
 GZipSection::~GZipSection() { free(mFilenames); }
 
-status_t GZipSection::Execute(ReportRequestSet* requests) const {
+status_t GZipSection::Execute(ReportWriter* writer) const {
     // Reads the files in order, use the first available one.
     int index = 0;
     unique_fd fd;
@@ -366,7 +178,7 @@
 
     // construct Fdbuffer to output GZippedfileProto, the reason to do this instead of using
     // ProtoOutputStream is to avoid allocation of another buffer inside ProtoOutputStream.
-    EncodedBuffer* internalBuffer = buffer.getInternalBuffer();
+    sp<EncodedBuffer> internalBuffer = buffer.data();
     internalBuffer->writeHeader((uint32_t)GZippedFileProto::FILENAME, WIRE_TYPE_LENGTH_DELIMITED);
     size_t fileLen = strlen(mFilenames[index]);
     internalBuffer->writeRawVarint32(fileLen);
@@ -383,7 +195,7 @@
     status_t readStatus = buffer.readProcessedDataInStream(
             fd.get(), std::move(p2cPipe.writeFd()), std::move(c2pPipe.readFd()), this->timeoutMs,
             isSysfs(mFilenames[index]));
-    write_section_stats(requests->sectionStats(this->id), buffer);
+    writer->setSectionStats(buffer);
     if (readStatus != NO_ERROR || buffer.timedOut()) {
         ALOGW("[%s] failed to read data from gzip: %s, timedout: %s", this->name.string(),
               strerror(-readStatus), buffer.timedOut() ? "true" : "false");
@@ -402,7 +214,7 @@
     internalBuffer->writeRawVarint32(dataSize);
     internalBuffer->copy(dataBeginAt, dataSize);
 
-    return write_report_requests(this->id, buffer, requests);
+    return writer->writeSection(buffer);
 }
 
 // ================================================================================
@@ -425,8 +237,8 @@
 WorkerThreadData::~WorkerThreadData() {}
 
 // ================================================================================
-WorkerThreadSection::WorkerThreadSection(int id, const int64_t timeoutMs, bool userdebugAndEngOnly)
-    : Section(id, timeoutMs, userdebugAndEngOnly) {}
+WorkerThreadSection::WorkerThreadSection(int id, const int64_t timeoutMs)
+    : Section(id, timeoutMs) {}
 
 WorkerThreadSection::~WorkerThreadSection() {}
 
@@ -458,13 +270,12 @@
     return NULL;
 }
 
-status_t WorkerThreadSection::Execute(ReportRequestSet* requests) const {
+status_t WorkerThreadSection::Execute(ReportWriter* writer) const {
     status_t err = NO_ERROR;
     pthread_t thread;
     pthread_attr_t attr;
     bool workerDone = false;
     FdBuffer buffer;
-    IncidentMetadata::SectionStats* stats = requests->sectionStats(this->id);
 
     // Data shared between this thread and the worker thread.
     sp<WorkerThreadData> data = new WorkerThreadData(this);
@@ -474,10 +285,6 @@
         return -errno;
     }
 
-    // The worker thread needs a reference and we can't let the count go to zero
-    // if that thread is slow to start.
-    data->incStrong(this);
-
     // Create the thread
     err = pthread_attr_init(&attr);
     if (err != 0) {
@@ -489,12 +296,17 @@
         pthread_attr_destroy(&attr);
         return -err;
     }
+
+    // The worker thread needs a reference and we can't let the count go to zero
+    // if that thread is slow to start.
+    data->incStrong(this);
+
     err = pthread_create(&thread, &attr, worker_thread_func, (void*)data.get());
+    pthread_attr_destroy(&attr);
     if (err != 0) {
-        pthread_attr_destroy(&attr);
+        data->decStrong(this);
         return -err;
     }
-    pthread_attr_destroy(&attr);
 
     // Loop reading until either the timeout or the worker side is done (i.e. eof).
     err = buffer.read(data->pipe.readFd().get(), this->timeoutMs);
@@ -517,18 +329,17 @@
         workerDone = data->workerDone;
     }
 
-    write_section_stats(stats, buffer);
+    writer->setSectionStats(buffer);
     if (err != NO_ERROR) {
         char errMsg[128];
         snprintf(errMsg, 128, "[%s] failed with error '%s'",
             this->name.string(), strerror(-err));
-        stats->set_success(false);
-        stats->set_error_msg(errMsg);
+        writer->error(this, err, "WorkerThreadSection failed.");
         return NO_ERROR;
     }
     if (buffer.truncated()) {
         ALOGW("[%s] too large, truncating", this->name.string());
-        // Do not write a truncated section. It won't pass through the PrivacyBuffer.
+        // Do not write a truncated section. It won't pass through the PrivacyFilter.
         return NO_ERROR;
     }
     if (!workerDone || buffer.timedOut()) {
@@ -537,7 +348,7 @@
     }
 
     // Write the data that was collected
-    return write_report_requests(this->id, buffer, requests);
+    return writer->writeSection(buffer);
 }
 
 // ================================================================================
@@ -568,7 +379,7 @@
 
 CommandSection::~CommandSection() { free(mCommand); }
 
-status_t CommandSection::Execute(ReportRequestSet* requests) const {
+status_t CommandSection::Execute(ReportWriter* writer) const {
     FdBuffer buffer;
     Fpipe cmdPipe;
     Fpipe ihPipe;
@@ -591,7 +402,7 @@
 
     cmdPipe.writeFd().reset();
     status_t readStatus = buffer.read(ihPipe.readFd().get(), this->timeoutMs);
-    write_section_stats(requests->sectionStats(this->id), buffer);
+    writer->setSectionStats(buffer);
     if (readStatus != NO_ERROR || buffer.timedOut()) {
         ALOGW("[%s] failed to read data from incident helper: %s, timedout: %s",
               this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false");
@@ -605,18 +416,18 @@
     status_t cmdStatus = wait_child(cmdPid);
     status_t ihStatus = wait_child(ihPid);
     if (cmdStatus != NO_ERROR || ihStatus != NO_ERROR) {
-        ALOGW("[%s] abnormal child processes, return status: command: %s, incident "
-              "helper: %s",
+        ALOGW("[%s] abnormal child processes, return status: command: %s, incident helper: %s",
               this->name.string(), strerror(-cmdStatus), strerror(-ihStatus));
-        return cmdStatus != NO_ERROR ? cmdStatus : ihStatus;
+        // Not a fatal error.
+        return NO_ERROR;
     }
 
-    return write_report_requests(this->id, buffer, requests);
+    return writer->writeSection(buffer);
 }
 
 // ================================================================================
-DumpsysSection::DumpsysSection(int id, bool userdebugAndEngOnly, const char* service, ...)
-    : WorkerThreadSection(id, REMOTE_CALL_TIMEOUT_MS, userdebugAndEngOnly), mService(service) {
+DumpsysSection::DumpsysSection(int id, const char* service, ...)
+    : WorkerThreadSection(id, REMOTE_CALL_TIMEOUT_MS), mService(service) {
     name = "dumpsys ";
     name += service;
 
@@ -842,7 +653,8 @@
         const std::string link_name = android::base::StringPrintf("/proc/%d/exe", pid);
         std::string exe;
         if (!android::base::Readlink(link_name, &exe)) {
-            ALOGE("Can't read '%s': %s\n", link_name.c_str(), strerror(errno));
+            ALOGE("Section %s: Can't read '%s': %s\n", name.string(),
+                    link_name.c_str(), strerror(errno));
             continue;
         }
 
@@ -913,10 +725,10 @@
         }
 
         auto dump = std::make_unique<char[]>(buffer.size());
-        auto iterator = buffer.data();
+        sp<ProtoReader> reader = buffer.data()->read();
         int i = 0;
-        while (iterator.hasNext()) {
-            dump[i] = iterator.next();
+        while (reader->hasNext()) {
+            dump[i] = reader->next();
             i++;
         }
         uint64_t token = proto.start(android::os::BackTraceProto::TRACES);
diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h
index 86d956f..cfe7e16 100644
--- a/cmds/incidentd/src/Section.h
+++ b/cmds/incidentd/src/Section.h
@@ -40,35 +40,12 @@
 public:
     const int id;
     const int64_t timeoutMs;  // each section must have a timeout
-    const bool userdebugAndEngOnly;
     String8 name;
 
-    Section(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS, bool userdebugAndEngOnly = false);
+    Section(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS);
     virtual ~Section();
 
-    virtual status_t Execute(ReportRequestSet* requests) const = 0;
-};
-
-/**
- * Section that generates incident headers.
- */
-class HeaderSection : public Section {
-public:
-    HeaderSection();
-    virtual ~HeaderSection();
-
-    virtual status_t Execute(ReportRequestSet* requests) const;
-};
-
-/**
- * Section that generates incident metadata.
- */
-class MetadataSection : public Section {
-public:
-    MetadataSection();
-    virtual ~MetadataSection();
-
-    virtual status_t Execute(ReportRequestSet* requests) const;
+    virtual status_t Execute(ReportWriter* writer) const = 0;
 };
 
 /**
@@ -80,7 +57,7 @@
                 int64_t timeoutMs = 5000 /* 5 seconds */);
     virtual ~FileSection();
 
-    virtual status_t Execute(ReportRequestSet* requests) const;
+    virtual status_t Execute(ReportWriter* writer) const;
 
 private:
     const char* mFilename;
@@ -95,7 +72,7 @@
     GZipSection(int id, const char* filename, ...);
     virtual ~GZipSection();
 
-    virtual status_t Execute(ReportRequestSet* requests) const;
+    virtual status_t Execute(ReportWriter* writer) const;
 
 private:
     // It looks up the content from multiple files and stops when the first one is available.
@@ -107,11 +84,10 @@
  */
 class WorkerThreadSection : public Section {
 public:
-    WorkerThreadSection(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS,
-                        bool userdebugAndEngOnly = false);
+    WorkerThreadSection(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS);
     virtual ~WorkerThreadSection();
 
-    virtual status_t Execute(ReportRequestSet* requests) const;
+    virtual status_t Execute(ReportWriter* writer) const;
 
     virtual status_t BlockingCall(int pipeWriteFd) const = 0;
 };
@@ -127,7 +103,7 @@
 
     virtual ~CommandSection();
 
-    virtual status_t Execute(ReportRequestSet* requests) const;
+    virtual status_t Execute(ReportWriter* writer) const;
 
 private:
     const char** mCommand;
@@ -138,7 +114,7 @@
  */
 class DumpsysSection : public WorkerThreadSection {
 public:
-    DumpsysSection(int id, bool userdebugAndEngOnly, const char* service, ...);
+    DumpsysSection(int id, const char* service, ...);
     virtual ~DumpsysSection();
 
     virtual status_t BlockingCall(int pipeWriteFd) const;
@@ -149,6 +125,21 @@
 };
 
 /**
+ * Section that calls dumpsys on a system service.
+ */
+class SystemPropertyDumpsysSection : public WorkerThreadSection {
+public:
+    SystemPropertyDumpsysSection(int id, const char* service, ...);
+    virtual ~SystemPropertyDumpsysSection();
+
+    virtual status_t BlockingCall(int pipeWriteFd) const;
+
+private:
+    String16 mService;
+    Vector<String16> mArgs;
+};
+
+/**
  * Section that reads from logd.
  */
 class LogSection : public WorkerThreadSection {
diff --git a/cmds/incidentd/src/WorkDirectory.cpp b/cmds/incidentd/src/WorkDirectory.cpp
new file mode 100644
index 0000000..ae640c6
--- /dev/null
+++ b/cmds/incidentd/src/WorkDirectory.cpp
@@ -0,0 +1,836 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Log.h"
+
+#include "WorkDirectory.h"
+
+#include "proto_util.h"
+#include "PrivacyFilter.h"
+
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <private/android_filesystem_config.h>
+
+#include <iomanip>
+#include <map>
+#include <sstream>
+#include <thread>
+#include <vector>
+
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using std::thread;
+using google::protobuf::MessageLite;
+using google::protobuf::RepeatedPtrField;
+using google::protobuf::io::FileInputStream;
+using google::protobuf::io::FileOutputStream;
+
+/**
+ * Turn off to skip removing files for debugging.
+ */
+static const bool DO_UNLINK = true;
+
+/**
+ * File extension for envelope files.
+ */
+static const string EXTENSION_ENVELOPE(".envelope");
+
+/**
+ * File extension for data files.
+ */
+static const string EXTENSION_DATA(".data");
+
+/**
+ * Send these reports to dropbox.
+ */
+const ComponentName DROPBOX_SENTINEL("android", "DROPBOX");
+
+/** metadata field id in IncidentProto */
+const int FIELD_ID_INCIDENT_METADATA = 2;
+
+/**
+ * Read a protobuf from disk into the message.
+ */
+static status_t read_proto(MessageLite* msg, const string& filename) {
+    int fd = open(filename.c_str(), O_RDONLY | O_CLOEXEC);
+    if (fd < 0) {
+        return -errno;
+    }
+
+    FileInputStream stream(fd);
+    stream.SetCloseOnDelete(fd);
+
+    if (!msg->ParseFromZeroCopyStream(&stream)) {
+        return BAD_VALUE;
+    }
+
+    return stream.GetErrno();
+}
+
+/**
+ * Write a protobuf to disk.
+ */
+static status_t write_proto(const MessageLite& msg, const string& filename) {
+    int fd = open(filename.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC, 0660);
+    if (fd < 0) {
+        return -errno;
+    }
+
+    FileOutputStream stream(fd);
+    stream.SetCloseOnDelete(fd);
+
+    if (!msg.SerializeToZeroCopyStream(&stream)) {
+        ALOGW("write_proto: error writing to %s", filename.c_str());
+        return BAD_VALUE;
+    }
+
+    return stream.GetErrno();
+}
+
+static string strip_extension(const string& filename) {
+    return filename.substr(0, filename.find('.'));
+}
+
+static bool ends_with(const string& str, const string& ending) {
+    if (str.length() >= ending.length()) {
+        return str.compare(str.length()-ending.length(), ending.length(), ending) == 0;
+    } else {
+        return false;
+    }
+}
+
+// Returns true if it was a valid timestamp.
+static bool parse_timestamp_ns(const string& id, int64_t* result) {
+    char* endptr;
+    *result = strtoll(id.c_str(), &endptr, 10);
+    return id.length() != 0 && *endptr == '\0';
+}
+
+static bool has_section(const ReportFileProto_Report& report, int section) {
+    const size_t sectionCount = report.section_size();
+    for (int i = 0; i < sectionCount; i++) {
+        if (report.section(i) == section) {
+            return true;
+        }
+    }
+    return false;
+}
+
+status_t create_directory(const char* directory) {
+    struct stat st;
+    status_t err = NO_ERROR;
+    char* dir = strdup(directory);
+
+    // Skip first slash
+    char* d = dir + 1;
+
+    // Create directories, assigning them to the system user
+    bool last = false;
+    while (!last) {
+        d = strchr(d, '/');
+        if (d != NULL) {
+            *d = '\0';
+        } else {
+            last = true;
+        }
+        if (stat(dir, &st) == 0) {
+            if (!S_ISDIR(st.st_mode)) {
+                err = ALREADY_EXISTS;
+                goto done;
+            }
+        } else {
+            ALOGE("No such directory %s, something wrong.", dir);
+            err = -1;
+            goto done;
+        }
+        if (!last) {
+            *d++ = '/';
+        }
+    }
+
+    // Ensure that the final directory is owned by the system with 0770. If it isn't
+    // we won't write into it.
+    if (stat(directory, &st) != 0) {
+        ALOGE("No incident reports today. Can't stat: %s", directory);
+        err = -errno;
+        goto done;
+    }
+    if ((st.st_mode & 0777) != 0770) {
+        ALOGE("No incident reports today. Mode is %0o on report directory %s", st.st_mode,
+              directory);
+        err = BAD_VALUE;
+        goto done;
+    }
+    if (st.st_uid != AID_INCIDENTD || st.st_gid != AID_INCIDENTD) {
+        ALOGE("No incident reports today. Owner is %d and group is %d on report directory %s",
+              st.st_uid, st.st_gid, directory);
+        err = BAD_VALUE;
+        goto done;
+    }
+
+done:
+    free(dir);
+    return err;
+}
+
+void log_envelope(const ReportFileProto& envelope) {
+    ALOGD("Envelope: {");
+    for (int i=0; i<envelope.report_size(); i++) {
+        ALOGD("  report {");
+        ALOGD("    pkg=%s", envelope.report(i).pkg().c_str());
+        ALOGD("    cls=%s", envelope.report(i).cls().c_str());
+        ALOGD("    share_approved=%d", envelope.report(i).share_approved());
+        ALOGD("    privacy_policy=%d", envelope.report(i).privacy_policy());
+        ALOGD("    all_sections=%d", envelope.report(i).all_sections());
+        for (int j=0; j<envelope.report(i).section_size(); j++) {
+            ALOGD("    section[%d]=%d", j, envelope.report(i).section(j));
+        }
+        ALOGD("  }");
+    }
+    ALOGD("  data_file=%s", envelope.data_file().c_str());
+    ALOGD("  privacy_policy=%d", envelope.privacy_policy());
+    ALOGD("  data_file_size=%lld", envelope.data_file_size());
+    ALOGD("  completed=%d", envelope.completed());
+    ALOGD("}");
+}
+
+// ================================================================================
+struct WorkDirectoryEntry {
+    WorkDirectoryEntry();
+    explicit WorkDirectoryEntry(const WorkDirectoryEntry& that);
+    ~WorkDirectoryEntry();
+
+    string envelope;
+    string data;
+    int64_t timestampNs;
+    off_t size;
+};
+
+WorkDirectoryEntry::WorkDirectoryEntry()
+        :envelope(),
+         data(),
+         size(0) {
+}
+
+WorkDirectoryEntry::WorkDirectoryEntry(const WorkDirectoryEntry& that)
+        :envelope(that.envelope),
+         data(that.data),
+         size(that.size) {
+}
+
+WorkDirectoryEntry::~WorkDirectoryEntry() {
+}
+
+// ================================================================================
+ReportFile::ReportFile(const sp<WorkDirectory>& workDirectory, int64_t timestampNs,
+            const string& envelopeFileName, const string& dataFileName)
+        :mWorkDirectory(workDirectory),
+         mTimestampNs(timestampNs),
+         mEnvelopeFileName(envelopeFileName),
+         mDataFileName(dataFileName),
+         mEnvelope(),
+         mDataFd(-1),
+         mError(NO_ERROR) {
+    // might get overwritten when we read but that's ok
+    mEnvelope.set_data_file(mDataFileName);
+}
+
+ReportFile::~ReportFile() {
+    if (mDataFd >= 0) {
+        close(mDataFd);
+    }
+}
+
+int64_t ReportFile::getTimestampNs() const {
+    return mTimestampNs;
+}
+
+void ReportFile::addReport(const IncidentReportArgs& args) {
+    // There is only one report per component.  Merge into an existing one if necessary.
+    ReportFileProto_Report* report;
+    const int reportCount = mEnvelope.report_size();
+    int i = 0;
+    for (; i < reportCount; i++) {
+        report = mEnvelope.mutable_report(i);
+        if (report->pkg() == args.receiverPkg() && report->cls() == args.receiverCls()) {
+            if (args.getPrivacyPolicy() < report->privacy_policy()) {
+                // Lower privacy policy (less restrictive) wins.
+                report->set_privacy_policy(args.getPrivacyPolicy());
+            }
+            report->set_all_sections(report->all_sections() | args.all());
+            for (int section: args.sections()) {
+                if (!has_section(*report, section)) {
+                    report->add_section(section);
+                }
+            }
+            break;
+        }
+    }
+    if (i >= reportCount) {
+        report = mEnvelope.add_report();
+        report->set_pkg(args.receiverPkg());
+        report->set_cls(args.receiverCls());
+        report->set_privacy_policy(args.getPrivacyPolicy());
+        report->set_all_sections(args.all());
+        for (int section: args.sections()) {
+            report->add_section(section);
+        }
+    }
+
+    for (const vector<uint8_t>& header: args.headers()) {
+        report->add_header(header.data(), header.size());
+    }
+}
+
+void ReportFile::removeReport(const string& pkg, const string& cls) {
+    RepeatedPtrField<ReportFileProto_Report>* reports = mEnvelope.mutable_report();
+    const int reportCount = reports->size();
+    for (int i = 0; i < reportCount; i++) {
+        const ReportFileProto_Report& r = reports->Get(i);
+        if (r.pkg() == pkg && r.cls() == cls) {
+            reports->DeleteSubrange(i, 1);
+            return;
+        }
+    }
+}
+
+void ReportFile::removeReports(const string& pkg) {
+    RepeatedPtrField<ReportFileProto_Report>* reports = mEnvelope.mutable_report();
+    const int reportCount = reports->size();
+    for (int i = reportCount-1; i >= 0; i--) {
+        const ReportFileProto_Report& r = reports->Get(i);
+        if (r.pkg() == pkg) {
+            reports->DeleteSubrange(i, 1);
+        }
+    }
+}
+
+void ReportFile::setMetadata(const IncidentMetadata& metadata) {
+    *mEnvelope.mutable_metadata() = metadata;
+}
+
+void ReportFile::markCompleted() {
+    mEnvelope.set_completed(true);
+}
+
+status_t ReportFile::markApproved(const string& pkg, const string& cls) {
+    size_t const reportCount = mEnvelope.report_size();
+    for (int reportIndex = 0; reportIndex < reportCount; reportIndex++) {
+        ReportFileProto_Report* report = mEnvelope.mutable_report(reportIndex);
+        if (report->pkg() == pkg && report->cls() == cls) {
+            report->set_share_approved(true);
+            return NO_ERROR;
+        }
+    }
+    return NAME_NOT_FOUND;
+}
+
+void ReportFile::setMaxPersistedPrivacyPolicy(int persistedPrivacyPolicy) {
+    mEnvelope.set_privacy_policy(persistedPrivacyPolicy);
+}
+
+status_t ReportFile::saveEnvelope() {
+    return save_envelope_impl(true);
+}
+
+status_t ReportFile::trySaveEnvelope() {
+    return save_envelope_impl(false);
+}
+
+status_t ReportFile::loadEnvelope() {
+    return load_envelope_impl(true);
+}
+
+status_t ReportFile::tryLoadEnvelope() {
+    return load_envelope_impl(false);
+}
+
+const ReportFileProto& ReportFile::getEnvelope() {
+    return mEnvelope;
+}
+
+status_t ReportFile::startWritingDataFile() {
+    if (mDataFd >= 0) {
+        ALOGW("ReportFile::startWritingDataFile called with the file already open: %s",
+                mDataFileName.c_str());
+        return ALREADY_EXISTS;
+    }
+    mDataFd = open(mDataFileName.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC, 0660);
+    if (mDataFd < 0) {
+        return -errno;
+    }
+    return NO_ERROR;
+}
+
+void ReportFile::closeDataFile() {
+    if (mDataFd >= 0) {
+        mEnvelope.set_data_file_size(lseek(mDataFd, 0, SEEK_END));
+        close(mDataFd);
+        mDataFd = -1;
+    }
+}
+
+status_t ReportFile::startFilteringData(int writeFd, const IncidentReportArgs& args) {
+    // Open data file.
+    int dataFd = open(mDataFileName.c_str(), O_RDONLY | O_CLOEXEC);
+    if (dataFd < 0) {
+        ALOGW("Error opening incident report '%s' %s", getDataFileName().c_str(), strerror(-errno));
+        close(writeFd);
+        return -errno;
+    }
+
+    // Check that the size on disk is what we thought we wrote.
+    struct stat st;
+    if (fstat(dataFd, &st) != 0) {
+        ALOGW("Error running fstat incident report '%s' %s", getDataFileName().c_str(),
+              strerror(-errno));
+        close(writeFd);
+        return -errno;
+    }
+    if (st.st_size != mEnvelope.data_file_size()) {
+        ALOGW("File size mismatch. Envelope says %" PRIi64 " bytes but data file is %" PRIi64
+              " bytes: %s",
+              (int64_t)mEnvelope.data_file_size(), st.st_size, mDataFileName.c_str());
+        ALOGW("Removing incident report");
+        mWorkDirectory->remove(this);
+        close(writeFd);
+        return BAD_VALUE;
+    }
+
+    status_t err;
+
+    for (const auto& report : mEnvelope.report()) {
+        for (const auto& header : report.header()) {
+           write_header_section(writeFd,
+               reinterpret_cast<const uint8_t*>(header.c_str()), header.size());
+        }
+    }
+
+    if (mEnvelope.has_metadata()) {
+        write_section(writeFd, FIELD_ID_INCIDENT_METADATA, mEnvelope.metadata());
+    }
+
+    err = filter_and_write_report(writeFd, dataFd, mEnvelope.privacy_policy(), args);
+    if (err != NO_ERROR) {
+        ALOGW("Error writing incident report '%s' to dropbox: %s", getDataFileName().c_str(),
+                strerror(-err));
+    }
+
+    close(writeFd);
+    return NO_ERROR;
+}
+
+string ReportFile::getDataFileName() const {
+    return mDataFileName;
+}
+
+string ReportFile::getEnvelopeFileName() const {
+    return mEnvelopeFileName;
+}
+
+int ReportFile::getDataFileFd() {
+    return mDataFd;
+}
+
+void ReportFile::setWriteError(status_t err) {
+    mError = err;
+}
+
+status_t ReportFile::getWriteError() {
+    return mError;
+}
+
+string ReportFile::getId() {
+    return to_string(mTimestampNs);
+}
+
+status_t ReportFile::save_envelope_impl(bool cleanup) {
+    status_t err;
+    err = write_proto(mEnvelope, mEnvelopeFileName);
+    if (err != NO_ERROR) {
+        // If there was an error writing the envelope, then delete the whole thing.
+        if (cleanup) {
+            mWorkDirectory->remove(this);
+        }
+        return err;
+    }
+    return NO_ERROR;
+}
+
+status_t ReportFile::load_envelope_impl(bool cleanup) {
+    status_t err;
+    err = read_proto(&mEnvelope, mEnvelopeFileName);
+    if (err != NO_ERROR) {
+        // If there was an error reading the envelope, then delete the whole thing.
+        if (cleanup) {
+            mWorkDirectory->remove(this);
+        }
+        return err;
+    }
+    return NO_ERROR;
+}
+
+
+
+// ================================================================================
+//
+
+WorkDirectory::WorkDirectory()
+        :mDirectory("/data/misc/incidents"),
+         mMaxFileCount(100),
+         mMaxDiskUsageBytes(30 * 1024 * 1024) {  // Incident reports can take up to 30MB on disk.
+                                                 // TODO: Should be a flag.
+    create_directory(mDirectory.c_str());
+}
+
+WorkDirectory::WorkDirectory(const string& dir, int maxFileCount, long maxDiskUsageBytes)
+        :mDirectory(dir),
+         mMaxFileCount(maxFileCount),
+         mMaxDiskUsageBytes(maxDiskUsageBytes) {
+    create_directory(mDirectory.c_str());
+}
+
+sp<ReportFile> WorkDirectory::createReportFile() {
+    unique_lock<mutex> lock(mLock);
+    status_t err;
+
+    clean_directory_locked();
+
+    int64_t timestampNs = make_timestamp_ns_locked();
+    string envelopeFileName = make_filename(timestampNs, EXTENSION_ENVELOPE);
+    string dataFileName = make_filename(timestampNs, EXTENSION_DATA);
+
+    sp<ReportFile> result = new ReportFile(this, timestampNs, envelopeFileName, dataFileName);
+
+    err = result->trySaveEnvelope();
+    if (err != NO_ERROR) {
+        ALOGW("Can't save envelope file %s: %s", strerror(-errno), envelopeFileName.c_str());
+        return nullptr;
+    }
+
+    return result;
+}
+
+status_t WorkDirectory::getReports(vector<sp<ReportFile>>* result, int64_t after) {
+    unique_lock<mutex> lock(mLock);
+
+    const bool DBG = true;
+
+    if (DBG) {
+        ALOGD("WorkDirectory::getReports");
+    }
+
+    map<string,WorkDirectoryEntry> files;
+    get_directory_contents_locked(&files, after);
+    for (map<string,WorkDirectoryEntry>::iterator it = files.begin();
+            it != files.end(); it++) {
+        sp<ReportFile> reportFile = new ReportFile(this, it->second.timestampNs,
+                it->second.envelope, it->second.data);
+        if (DBG) {
+            ALOGD("  %s", reportFile->getId().c_str());
+        }
+        result->push_back(reportFile);
+    }
+    return NO_ERROR;
+}
+
+sp<ReportFile> WorkDirectory::getReport(const string& pkg, const string& cls, const string& id,
+            IncidentReportArgs* args) {
+    unique_lock<mutex> lock(mLock);
+
+    status_t err;
+    int64_t timestampNs;
+    if (!parse_timestamp_ns(id, &timestampNs)) {
+        return nullptr;
+    }
+
+    // Make the ReportFile object, and then see if it's valid and for pkg and cls.
+    sp<ReportFile> result = new ReportFile(this, timestampNs,
+            make_filename(timestampNs, EXTENSION_ENVELOPE),
+            make_filename(timestampNs, EXTENSION_DATA));
+
+    err = result->tryLoadEnvelope();
+    if (err != NO_ERROR) {
+        ALOGW("Can't open envelope file for report %s/%s %s", pkg.c_str(), cls.c_str(), id.c_str());
+        return nullptr;
+    }
+
+    const ReportFileProto& envelope = result->getEnvelope();
+    const size_t reportCount = envelope.report_size();
+    for (int i = 0; i < reportCount; i++) {
+        const ReportFileProto_Report& report = envelope.report(i);
+        if (report.pkg() == pkg && report.cls() == cls) {
+            if (args != nullptr) {
+                get_args_from_report(args, report);
+            }
+            return result;
+        }
+
+    }
+
+    return nullptr;
+}
+
+bool WorkDirectory::hasMore(int64_t after) {
+    unique_lock<mutex> lock(mLock);
+
+    map<string,WorkDirectoryEntry> files;
+    get_directory_contents_locked(&files, after);
+    return files.size() > 0;
+}
+
+void WorkDirectory::commit(const sp<ReportFile>& report, const string& pkg, const string& cls) {
+    status_t err;
+    ALOGI("Committing report %s for %s/%s", report->getId().c_str(), pkg.c_str(), cls.c_str());
+
+    unique_lock<mutex> lock(mLock);
+
+    // Load the envelope here inside the lock.
+    err = report->loadEnvelope();
+
+    report->removeReport(pkg, cls);
+
+    delete_files_for_report_if_necessary(report);
+}
+
+void WorkDirectory::commitAll(const string& pkg) {
+    status_t err;
+    ALOGI("All reports for %s", pkg.c_str());
+
+    unique_lock<mutex> lock(mLock);
+
+    map<string,WorkDirectoryEntry> files;
+    get_directory_contents_locked(&files, 0);
+    
+    for (map<string,WorkDirectoryEntry>::iterator it = files.begin();
+            it != files.end(); it++) {
+        sp<ReportFile> reportFile = new ReportFile(this, it->second.timestampNs,
+                it->second.envelope, it->second.data);
+
+        err = reportFile->loadEnvelope();
+        if (err != NO_ERROR) {
+            continue;
+        }
+
+        reportFile->removeReports(pkg);
+
+        delete_files_for_report_if_necessary(reportFile);
+    }
+}
+
+void WorkDirectory::remove(const sp<ReportFile>& report) {
+    unique_lock<mutex> lock(mLock);
+    // Set this to false to leave files around for debugging.
+    if (DO_UNLINK) {
+        unlink(report->getDataFileName().c_str());
+        unlink(report->getEnvelopeFileName().c_str());
+    }
+}
+
+int64_t WorkDirectory::make_timestamp_ns_locked() {
+    // Guarantee that we don't have duplicate timestamps.
+    // This is a little bit lame, but since reports are created on the
+    // same thread and are kinda slow we'll seldomly actually hit the
+    // condition.  The bigger risk is the clock getting reset and causing
+    // a collision.  In that case, we'll just make incident reporting a
+    // little bit slower.  Nobody will notice if we just loop until we
+    // have a unique file name.
+    int64_t timestampNs = 0;
+    do {
+        struct timespec spec;
+        if (timestampNs > 0) {
+            spec.tv_sec = 0;
+            spec.tv_nsec = 1;
+            nanosleep(&spec, nullptr);
+        }
+        clock_gettime(CLOCK_REALTIME, &spec);
+        timestampNs = (spec.tv_sec) * 1000 + spec.tv_nsec;
+    } while (file_exists_locked(timestampNs));
+    return timestampNs;
+}
+
+/**
+ * It is required to hold the lock here so in case someone else adds it
+ * our result is still correct for the caller.
+ */
+bool WorkDirectory::file_exists_locked(int64_t timestampNs) {
+    const string filename = make_filename(timestampNs, EXTENSION_ENVELOPE);
+    struct stat st;
+    return stat(filename.c_str(), &st) == 0;
+}
+
+string WorkDirectory::make_filename(int64_t timestampNs, const string& extension) {
+    // Zero pad the timestamp so it can also be alpha sorted.
+    stringstream result;
+    result << mDirectory << '/' << setfill('0') << setw(20) << timestampNs << extension;
+    return result.str();
+}
+
+off_t WorkDirectory::get_directory_contents_locked(map<string,WorkDirectoryEntry>* files,
+        int64_t after) {
+    DIR* dir;
+    struct dirent* entry;
+
+    if ((dir = opendir(mDirectory.c_str())) == NULL) {
+        ALOGE("Couldn't open incident directory: %s", mDirectory.c_str());
+        return -1;
+    }
+
+    string dirbase(mDirectory);
+    if (mDirectory[dirbase.size() - 1] != '/') dirbase += "/";
+
+    off_t totalSize = 0;
+
+    // Enumerate, count and add up size
+    while ((entry = readdir(dir)) != NULL) {
+        if (entry->d_name[0] == '.') {
+            continue;
+        }
+        string entryname = entry->d_name;  // local to this dir
+        string filename = dirbase + entryname;  // fully qualified
+
+        bool isEnvelope = ends_with(entryname, EXTENSION_ENVELOPE);
+        bool isData = ends_with(entryname, EXTENSION_DATA);
+
+        // If the file isn't one of our files, just ignore it.  Otherwise,
+        // sum up the sizes.
+        if (isEnvelope || isData) {
+            string timestamp = strip_extension(entryname);
+
+            int64_t timestampNs;
+            if (!parse_timestamp_ns(timestamp, &timestampNs)) {
+                continue;
+            }
+
+            if (after == 0 || timestampNs > after) {
+                struct stat st;
+                if (stat(filename.c_str(), &st) != 0) {
+                    ALOGE("Unable to stat file %s", filename.c_str());
+                    continue;
+                }
+                if (!S_ISREG(st.st_mode)) {
+                    continue;
+                }
+
+                WorkDirectoryEntry& entry = (*files)[timestamp];
+                if (isEnvelope) {
+                    entry.envelope = filename;
+                } else if (isData) {
+                    entry.data = filename;
+                }
+                entry.timestampNs = timestampNs;
+                entry.size += st.st_size;
+                totalSize += st.st_size;
+            }
+        }
+    }
+
+    closedir(dir);
+
+    // Now check if there are any data files that don't have envelope files.
+    // If there are, then just go ahead and delete them now.  Don't wait for
+    // a cleaning.
+
+    if (DO_UNLINK) {
+        map<string,WorkDirectoryEntry>::iterator it = files->begin();
+        while (it != files->end()) {
+            if (it->second.envelope.length() == 0) {
+                unlink(it->second.data.c_str());
+                it = files->erase(it);
+            } else {
+                it++;
+            }
+        }
+    }
+
+    return totalSize;
+}
+
+void WorkDirectory::clean_directory_locked() {
+    DIR* dir;
+    struct dirent* entry;
+    struct stat st;
+
+    // Map of filename without extension to the entries about it.  Conveniently,
+    // this also keeps the list sorted by filename, which is a timestamp.
+    map<string,WorkDirectoryEntry> files;
+    off_t totalSize = get_directory_contents_locked(&files, 0);
+    if (totalSize < 0) {
+        return;
+    }
+    int totalCount = files.size();
+
+    // Count or size is less than max, then we're done.
+    if (totalSize < mMaxDiskUsageBytes && totalCount < mMaxFileCount) {
+        return;
+    }
+
+    // Remove files until we're under our limits.
+    if (DO_UNLINK) {
+        for (map<string, WorkDirectoryEntry>::const_iterator it = files.begin();
+                it != files.end() && (totalSize >= mMaxDiskUsageBytes
+                    || totalCount >= mMaxFileCount);
+                it++) {
+            unlink(it->second.envelope.c_str());
+            unlink(it->second.data.c_str());
+            totalSize -= it->second.size;
+            totalCount--;
+        }
+    }
+}
+
+void WorkDirectory::delete_files_for_report_if_necessary(const sp<ReportFile>& report) {
+    if (report->getEnvelope().report_size() == 0) {
+        ALOGI("Report %s is finished. Deleting from storage.", report->getId().c_str());
+        if (DO_UNLINK) {
+            unlink(report->getDataFileName().c_str());
+            unlink(report->getEnvelopeFileName().c_str());
+        }
+    }
+}
+
+// ================================================================================
+void get_args_from_report(IncidentReportArgs* out, const ReportFileProto_Report& report) {
+    out->setPrivacyPolicy(report.privacy_policy());
+    out->setAll(report.all_sections());
+    out->setReceiverPkg(report.pkg());
+    out->setReceiverCls(report.cls());
+
+    const int sectionCount = report.section_size();
+    for (int i = 0; i < sectionCount; i++) {
+        out->addSection(report.section(i));
+    }
+
+    const int headerCount = report.header_size();
+    for (int i = 0; i < headerCount; i++) {
+        const string& header  = report.header(i);
+        vector<uint8_t> vec(header.begin(), header.end());
+        out->addHeader(vec);
+    }
+}
+
+
+}  // namespace incidentd
+}  // namespace os
+}  // namespace android
+
diff --git a/cmds/incidentd/src/WorkDirectory.h b/cmds/incidentd/src/WorkDirectory.h
new file mode 100644
index 0000000..3c6a2f2
--- /dev/null
+++ b/cmds/incidentd/src/WorkDirectory.h
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/content/ComponentName.h>
+#include <android/os/IncidentReportArgs.h>
+#include <frameworks/base/core/proto/android/os/metadata.pb.h>
+#include <frameworks/base/cmds/incidentd/src/report_file.pb.h>
+
+#include <utils/RefBase.h>
+
+#include <mutex>
+#include <string>
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using android::content::ComponentName;
+using android::os::IncidentReportArgs;
+using namespace std;
+
+extern const ComponentName DROPBOX_SENTINEL;
+
+class WorkDirectory;
+struct WorkDirectoryEntry;
+
+void get_args_from_report(IncidentReportArgs* out, const ReportFileProto_Report& report);
+
+/**
+ * A ReportFile object is backed by two files.
+ *   - A metadata file, which contains a 
+ */
+class ReportFile : public virtual RefBase {
+public:
+    ReportFile(const sp<WorkDirectory>& workDirectory, int64_t timestampNs,
+            const string& envelopeFileName, const string& dataFileName);
+
+    virtual ~ReportFile();
+
+    /**
+     * Get the timestamp from when this file was added.
+     */
+    int64_t getTimestampNs() const;
+
+    /**
+     * Add an additional report to this ReportFile.
+     */
+    void addReport(const IncidentReportArgs& args);
+
+    /**
+     * Remove the reports for pkg/cls from this file.
+     */
+    void removeReport(const string& pkg, const string& cls);
+
+    /**
+     * Remove all reports for pkg from this file.
+     */
+    void removeReports(const string& pkg);
+
+    /**
+     * Set the metadata for this incident report.
+     */
+    void setMetadata(const IncidentMetadata& metadata);
+
+    /*
+     * Mark this incident report as finished and ready for broadcast.
+     */
+    void markCompleted();
+
+    /*
+     * Mark this incident report as finished and ready for broadcast.
+     */
+    status_t markApproved(const string& pkg, const string& cls);
+    
+    /**
+     * Set the privacy policy that is being used to pre-filter the data
+     * going to disk.
+     */
+    void setMaxPersistedPrivacyPolicy(int persistedPrivacyPolicy);
+
+    /**
+     * Save the metadata (envelope) information about the incident
+     * report.  Must be called after addReport, setMetadata markCompleted
+     * markApproved to save those changes to disk.
+     */
+    status_t saveEnvelope();
+
+    /**
+     * Like saveEnvelope() but will not clean up if there is an error.
+     */
+    status_t trySaveEnvelope();
+
+    /**
+     * Read the envelope information from disk.  If there was an error, the envelope and
+     * data file will be removed.  If the proto can't be loaded, the whole file is deleted.
+     */
+    status_t loadEnvelope();
+
+    /**
+     * Like loadEnvelope() but will not clean up if there is an error.
+     */
+    status_t tryLoadEnvelope();
+
+    /**
+     * Get the envelope information.
+     */
+    const ReportFileProto& getEnvelope();
+
+    /**
+     * Open the file that will contain the contents of the incident report.  Call
+     * close() or closeDataFile() on the result of getDataFileFd() when you're done.
+     * This is not done automatically in the desctructor.   If there is an error, returns
+     * it and you will not get an fd.
+     */
+    status_t startWritingDataFile();
+
+    /**
+     * Close the data file.
+     */
+    void closeDataFile();
+
+    /**
+     * Use the privacy and section configuration from the args parameter to filter data, write
+     * to [writeFd] and take the ownership of [writeFd].
+     *
+     * Note: this call is blocking. When the writeFd is a pipe fd for IPC, caller should make sure
+     * it's called on a separate thread so that reader can start to read without waiting for writer
+     * to finish writing (which may not happen due to pipe buffer overflow).
+     */
+    status_t startFilteringData(int writeFd, const IncidentReportArgs& args);
+
+    /**
+     * Get the name of the data file on disk.
+     */
+    string getDataFileName() const;
+
+    /**
+     * Get the name of the envelope file on disk.
+     */
+    string getEnvelopeFileName() const;
+
+    /**
+     * Return the file descriptor for the data file, or -1 if it is not
+     * currently open.
+     */
+    int getDataFileFd();
+
+    /**
+     * Record that there was an error writing to the data file.
+     */
+    void setWriteError(status_t err);
+
+    /**
+     * Get whether there was previously an error writing to the data file.
+     */
+    status_t getWriteError();
+
+    /**
+     * Get the unique identifier for this file.
+     */
+    string getId();
+
+private:
+    sp<WorkDirectory> mWorkDirectory;
+    int64_t mTimestampNs;
+    string mEnvelopeFileName;
+    string mDataFileName;
+    ReportFileProto mEnvelope;
+    int mDataFd;
+    status_t mError;
+
+    status_t save_envelope_impl(bool cleanup);
+    status_t load_envelope_impl(bool cleanup);
+};
+
+/**
+ * For directory cleanup to work, WorkDirectory must be kept
+ * alive for the duration of all of the ReportFiles.  In the real
+ * incidentd, WorkDirectory is a singleton.  In tests, it may
+ * have a shorter duration.
+ */
+class WorkDirectory : public virtual RefBase {
+public:
+    /**
+     * Save files to the default location.
+     */
+    WorkDirectory();
+
+    /**
+     * Save files to a specific location (primarily for testing).
+     */
+    WorkDirectory(const string& dir, int maxFileCount, long maxDiskUsageBytes);
+
+    /**
+     * Return a new report file.  Creating this object won't fail, but
+     * subsequent actions on the file could, if the disk is full, permissions
+     * aren't set correctly, etc.
+     */
+    sp<ReportFile> createReportFile();
+
+    /**
+     * Get the reports that are saved on-disk, with the time after (>) than the
+     * given timestamp.  Pass 0 to start at the beginning.  These files
+     * will be sorted by timestamp.  The envelope will not have been loaded.
+     */
+    status_t getReports(vector<sp<ReportFile>>* files, int64_t after);
+
+    /**
+     * Get the report with the given package, class and id. Returns nullptr if
+     * that can't be found.  The envelope will have been loaded.  Returns the
+     * original IncidentReportArgs in *args if args != nullptr.
+     */
+    sp<ReportFile> getReport(const string& pkg, const string& cls, const string& id,
+            IncidentReportArgs* args);
+
+    /**
+     * Returns whether there are more reports after the given timestamp.
+     */
+    bool hasMore(int64_t after);
+
+    /**
+     * Confirm that a particular broadcast receiver has received the data.  When all
+     * broadcast receivers for a particular report file have finished, the envelope
+     * and data files will be deleted.
+     */
+    void commit(const sp<ReportFile>& report, const string& pkg, const string& cls);
+
+    /**
+     * Commit all reports the given package.
+     */
+    void commitAll(const string& pkg);
+
+    /**
+     * Remove the envelope and data file from disk, regardless of whether there are
+     * more pending readers or broadcasts, for example in response to an error.
+     */
+    void remove(const sp<ReportFile>& report);
+    
+private:
+    string mDirectory;
+    int mMaxFileCount;
+    long mMaxDiskUsageBytes;
+
+    // Held while creating or removing envelope files, which are the file that keeps
+    // the directory consistent.
+    mutex mLock;
+
+    int64_t make_timestamp_ns_locked();
+    bool file_exists_locked(int64_t timestampNs);    
+    off_t get_directory_contents_locked(map<string,WorkDirectoryEntry>* files, int64_t after);
+    void clean_directory_locked();
+    void delete_files_for_report_if_necessary(const sp<ReportFile>& report);
+
+    string make_filename(int64_t timestampNs, const string& extension);
+};
+
+
+}  // namespace incidentd
+}  // namespace os
+}  // namespace android
+
diff --git a/cmds/incidentd/src/incidentd_util.cpp b/cmds/incidentd/src/incidentd_util.cpp
index af685d8..dfaf893 100644
--- a/cmds/incidentd/src/incidentd_util.cpp
+++ b/cmds/incidentd/src/incidentd_util.cpp
@@ -68,7 +68,6 @@
     // fork used in multithreaded environment, avoid adding unnecessary code in child process
     pid_t pid = fork();
     if (pid == 0) {
-        VLOG("[In child]cmd %s", argv[0]);
         if (input != NULL && (TEMP_FAILURE_RETRY(dup2(input->readFd().get(), STDIN_FILENO)) < 0 ||
                               !input->close())) {
             ALOGW("Failed to dup2 stdin.");
@@ -158,4 +157,4 @@
 
 }  // namespace incidentd
 }  // namespace os
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/cmds/incidentd/src/incidentd_util.h b/cmds/incidentd/src/incidentd_util.h
index 3dac2c4..cc30768 100644
--- a/cmds/incidentd/src/incidentd_util.h
+++ b/cmds/incidentd/src/incidentd_util.h
@@ -78,6 +78,8 @@
 status_t kill_child(pid_t pid);
 status_t wait_child(pid_t pid);
 
+status_t start_detached_thread(const function<void ()>& func);
+
 }  // namespace incidentd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/incidentd/src/proto_util.cpp b/cmds/incidentd/src/proto_util.cpp
new file mode 100644
index 0000000..4e8ff71
--- /dev/null
+++ b/cmds/incidentd/src/proto_util.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "proto_util.h"
+
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <android/util/protobuf.h>
+#include <android/util/ProtoOutputStream.h>
+#include <android-base/file.h>
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using namespace android::base;
+using namespace android::util;
+using google::protobuf::io::FileOutputStream;
+
+// special section ids
+const int FIELD_ID_INCIDENT_HEADER = 1;
+
+status_t write_header_section(int fd, const uint8_t* buf, size_t bufSize) {
+    status_t err;
+
+    if (bufSize == 0) {
+        return NO_ERROR;
+    }
+
+    err = write_section_header(fd, FIELD_ID_INCIDENT_HEADER, bufSize);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    err = WriteFully(fd, buf, bufSize);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    return NO_ERROR;
+}
+
+status_t write_section_header(int fd, int sectionId, size_t size) {
+    uint8_t buf[20];
+    uint8_t* p = write_length_delimited_tag_header(buf, sectionId, size);
+    return WriteFully(fd, buf, p - buf) ? NO_ERROR : -errno;
+}
+
+status_t write_section(int fd, int sectionId, const MessageLite& message) {
+    status_t err;
+
+    err = write_section_header(fd, sectionId, message.ByteSize());
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    FileOutputStream stream(fd);
+    if (!message.SerializeToZeroCopyStream(&stream)) {
+        return stream.GetErrno();
+    } else {
+        return NO_ERROR;
+    }
+}
+
+
+
+}  // namespace incidentd
+}  // namespace os
+}  // namespace android
+
diff --git a/cmds/incidentd/src/proto_util.h b/cmds/incidentd/src/proto_util.h
new file mode 100644
index 0000000..2c0ab48
--- /dev/null
+++ b/cmds/incidentd/src/proto_util.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/Errors.h>
+
+#include <google/protobuf/message_lite.h>
+
+#include <vector>
+
+namespace android {
+namespace os {
+namespace incidentd {
+
+using std::vector;
+using google::protobuf::MessageLite;
+
+/**
+ * Write the IncidentHeaderProto section
+ */
+status_t write_header_section(int fd, const uint8_t* buf, size_t bufSize);
+
+/**
+ * Write the prologue for a section in the incident report
+ * (This is the proto length-prefixed field format).
+ */
+status_t write_section_header(int fd, int sectionId, size_t size);
+
+/**
+ * Write the given protobuf object as a section.
+ */
+status_t write_section(int fd, int sectionId, const MessageLite& message);
+
+}  // namespace incidentd
+}  // namespace os
+}  // namespace android
+
+
diff --git a/cmds/incidentd/src/report_directory.cpp b/cmds/incidentd/src/report_directory.cpp
index e2883ba..7d20a74 100644
--- a/cmds/incidentd/src/report_directory.cpp
+++ b/cmds/incidentd/src/report_directory.cpp
@@ -33,63 +33,6 @@
 namespace os {
 namespace incidentd {
 
-status_t create_directory(const char* directory) {
-    struct stat st;
-    status_t err = NO_ERROR;
-    char* dir = strdup(directory);
-
-    // Skip first slash
-    char* d = dir + 1;
-
-    // Create directories, assigning them to the system user
-    bool last = false;
-    while (!last) {
-        d = strchr(d, '/');
-        if (d != NULL) {
-            *d = '\0';
-        } else {
-            last = true;
-        }
-        if (stat(dir, &st) == 0) {
-            if (!S_ISDIR(st.st_mode)) {
-                err = ALREADY_EXISTS;
-                goto done;
-            }
-        } else {
-            ALOGE("No such directory %s, something wrong.", dir);
-            err = -1;
-            goto done;
-        }
-        if (!last) {
-            *d++ = '/';
-        }
-    }
-
-    // Ensure that the final directory is owned by the system with 0770. If it isn't
-    // we won't write into it.
-    if (stat(directory, &st) != 0) {
-        ALOGE("No incident reports today. Can't stat: %s", directory);
-        err = -errno;
-        goto done;
-    }
-    if ((st.st_mode & 0777) != 0770) {
-        ALOGE("No incident reports today. Mode is %0o on report directory %s", st.st_mode,
-              directory);
-        err = BAD_VALUE;
-        goto done;
-    }
-    if (st.st_uid != AID_INCIDENTD || st.st_gid != AID_INCIDENTD) {
-        ALOGE("No incident reports today. Owner is %d and group is %d on report directory %s",
-              st.st_uid, st.st_gid, directory);
-        err = BAD_VALUE;
-        goto done;
-    }
-
-done:
-    free(dir);
-    return err;
-}
-
 static bool stat_mtime_cmp(const std::pair<String8, struct stat>& a,
                            const std::pair<String8, struct stat>& b) {
     return a.second.st_mtime < b.second.st_mtime;
@@ -153,4 +96,4 @@
 
 }  // namespace incidentd
 }  // namespace os
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/cmds/incidentd/src/report_file.proto b/cmds/incidentd/src/report_file.proto
new file mode 100644
index 0000000..7563da2
--- /dev/null
+++ b/cmds/incidentd/src/report_file.proto
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package android.os.incidentd;
+
+import "frameworks/base/core/proto/android/os/metadata.proto";
+
+message ReportFileProto {
+    /**
+     * Metadata about each of the calls to reportIncident that
+     * initiated the incident report.
+     */
+    message Report {
+        /**
+         * Package name for broadcast receiver to be told when
+         * the report is complete.
+         */
+        optional string pkg = 1;
+
+        /**
+         * Class name for broadcast receiver to be told when
+         * the report is complete.
+         */
+        optional string cls = 2;
+
+        /**
+         * Privacy policy at which this report should be shared.
+         */
+        optional uint32 privacy_policy = 4;
+
+        /**
+         * Whether all available sections should be returned.
+         */
+        optional bool all_sections = 5;
+
+        /**
+         * If all_sections is not true, then this is the
+         * list of sections that were requested.
+         */
+        repeated int32 section = 6;
+
+        /**
+         * Flattened IncidentHeaderProto that was passed with this
+         * request.
+         */
+        repeated bytes header = 7;
+
+        /**
+         * Whether the user has approved this report to be shared with
+         * the given client.
+         */
+        optional bool share_approved = 8;
+    }
+
+    /**
+     * Metadata section recorded while the incident report
+     * was taken.
+     */
+    optional android.os.IncidentMetadata metadata = 1;
+
+    /**
+     * Report data structures for the incident reports.
+     */
+    repeated Report report = 2;
+
+    /**
+     * The file name, relative to the work directory where
+     * the data file is stored. The content of the data file
+     * is an android.os.IncidentProto, without the metadata
+     * or header sections.
+     */
+    optional string data_file = 3;
+
+    /**
+     * The privacy policy to which the file is already filtered.
+     */
+    optional uint32 privacy_policy = 4;
+
+    /**
+     * How big the data file is expected to be.  If the size
+     * recorded here and the size on disk mismatch, then we
+     * know there was an error.
+     */
+    optional int64 data_file_size = 5;
+
+    /**
+     * Whether this report has been finished, and is now
+     * ready for broadcast / dropbox / etc.
+     */
+    optional bool completed = 6;
+}
+
diff --git a/cmds/incidentd/tests/FdBuffer_test.cpp b/cmds/incidentd/tests/FdBuffer_test.cpp
index 3f92c2a..7edfadf 100644
--- a/cmds/incidentd/tests/FdBuffer_test.cpp
+++ b/cmds/incidentd/tests/FdBuffer_test.cpp
@@ -50,9 +50,9 @@
 
     void AssertBufferContent(const char* expected) {
         int i = 0;
-        EncodedBuffer::iterator it = buffer.data();
-        while (it.hasNext()) {
-            ASSERT_EQ(it.next(), expected[i++]);
+        sp<ProtoReader> reader = buffer.data()->read();
+        while (reader->hasNext()) {
+            ASSERT_EQ(reader->next(), expected[i++]);
         }
         EXPECT_EQ(expected[i], '\0');
     }
@@ -92,8 +92,8 @@
 }
 
 TEST_F(FdBufferTest, IterateEmpty) {
-    EncodedBuffer::iterator it = buffer.data();
-    EXPECT_FALSE(it.hasNext());
+    sp<ProtoReader> reader = buffer.data()->read();
+    EXPECT_FALSE(reader->hasNext());
 }
 
 TEST_F(FdBufferTest, ReadAndIterate) {
@@ -102,15 +102,23 @@
     ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, READ_TIMEOUT));
 
     int i = 0;
-    EncodedBuffer::iterator it = buffer.data();
-    while (it.hasNext()) {
-        EXPECT_EQ(it.next(), (uint8_t)testdata[i++]);
-    }
+    sp<ProtoReader> reader = buffer.data()->read();
 
-    it.rp()->rewind();
-    it.rp()->move(buffer.size());
-    EXPECT_EQ(it.bytesRead(), testdata.size());
-    EXPECT_FALSE(it.hasNext());
+    while (reader->hasNext()) {
+        EXPECT_EQ(reader->next(), (uint8_t)testdata[i++]);
+    }
+}
+
+TEST_F(FdBufferTest, Move) {
+    std::string testdata = "FdBuffer test string";
+    ASSERT_TRUE(WriteStringToFile(testdata, tf.path));
+    ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, READ_TIMEOUT));
+
+    sp<ProtoReader> reader = buffer.data()->read();
+    reader->move(buffer.size());
+
+    EXPECT_EQ(reader->bytesRead(), testdata.size());
+    EXPECT_FALSE(reader->hasNext());
 }
 
 TEST_F(FdBufferTest, ReadTimeout) {
@@ -224,7 +232,7 @@
     }
 }
 
-TEST_F(FdBufferTest, ReadInStreamMoreThan4MB) {
+TEST_F(FdBufferTest, ReadInStreamMoreThan4MBWithMove) {
     const std::string testFile = kTestDataPath + "morethan4MB.txt";
     size_t fourMB = (size_t)4 * 1024 * 1024;
     unique_fd fd(open(testFile.c_str(), O_RDONLY | O_CLOEXEC));
@@ -250,15 +258,45 @@
         EXPECT_FALSE(buffer.timedOut());
         EXPECT_TRUE(buffer.truncated());
         wait(&pid);
-        EncodedBuffer::iterator it = buffer.data();
-        it.rp()->move(fourMB);
-        EXPECT_EQ(it.bytesRead(), fourMB);
-        EXPECT_FALSE(it.hasNext());
+        sp<ProtoReader> reader = buffer.data()->read();
+        reader->move(fourMB);
 
-        it.rp()->rewind();
-        while (it.hasNext()) {
-            char c = 'A' + (it.bytesRead() % 64 / 8);
-            ASSERT_TRUE(it.next() == c);
+        EXPECT_EQ(reader->bytesRead(), fourMB);
+        EXPECT_FALSE(reader->hasNext());
+    }
+}
+
+TEST_F(FdBufferTest, ReadInStreamMoreThan4MBWithNext) {
+    const std::string testFile = kTestDataPath + "morethan4MB.txt";
+    size_t fourMB = (size_t)4 * 1024 * 1024;
+    unique_fd fd(open(testFile.c_str(), O_RDONLY | O_CLOEXEC));
+    ASSERT_NE(fd.get(), -1);
+    int pid = fork();
+    ASSERT_TRUE(pid != -1);
+
+    if (pid == 0) {
+        p2cPipe.writeFd().reset();
+        c2pPipe.readFd().reset();
+        ASSERT_TRUE(DoDataStream(p2cPipe.readFd(), c2pPipe.writeFd()));
+        p2cPipe.readFd().reset();
+        c2pPipe.writeFd().reset();
+        _exit(EXIT_SUCCESS);
+    } else {
+        p2cPipe.readFd().reset();
+        c2pPipe.writeFd().reset();
+
+        ASSERT_EQ(NO_ERROR,
+                  buffer.readProcessedDataInStream(fd, std::move(p2cPipe.writeFd()),
+                                                   std::move(c2pPipe.readFd()), READ_TIMEOUT));
+        EXPECT_EQ(buffer.size(), fourMB);
+        EXPECT_FALSE(buffer.timedOut());
+        EXPECT_TRUE(buffer.truncated());
+        wait(&pid);
+        sp<ProtoReader> reader = buffer.data()->read();
+
+        while (reader->hasNext()) {
+            char c = 'A' + (reader->bytesRead() % 64 / 8);
+            ASSERT_TRUE(reader->next() == c);
         }
     }
 }
diff --git a/cmds/incidentd/tests/PrivacyBuffer_test.cpp b/cmds/incidentd/tests/PrivacyBuffer_test.cpp
deleted file mode 100644
index 871226b..0000000
--- a/cmds/incidentd/tests/PrivacyBuffer_test.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#define DEBUG false
-#include "Log.h"
-
-#include "FdBuffer.h"
-#include "PrivacyBuffer.h"
-
-#include <android-base/file.h>
-#include <android-base/test_utils.h>
-#include <android/os/IncidentReportArgs.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <string.h>
-
-using namespace android;
-using namespace android::base;
-using namespace android::os;
-using namespace android::os::incidentd;
-using ::testing::StrEq;
-using ::testing::Test;
-using ::testing::internal::CaptureStdout;
-using ::testing::internal::GetCapturedStdout;
-
-const uint8_t OTHER_TYPE = 1;
-const uint8_t STRING_TYPE = 9;
-const uint8_t MESSAGE_TYPE = 11;
-const std::string STRING_FIELD_0 = "\x02\viamtestdata";
-const std::string VARINT_FIELD_1 = "\x08\x96\x01";  // 150
-const std::string STRING_FIELD_2 = "\x12\vandroidwins";
-const std::string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff";  // -1
-const std::string FIX32_FIELD_4 = "\x25\xff\xff\xff\xff";                  // -1
-const std::string MESSAGE_FIELD_5 = "\x2a\x10" + VARINT_FIELD_1 + STRING_FIELD_2;
-const std::string NEGATIVE_VARINT_FIELD_6 = "\x30\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01";  // -1
-
-class PrivacyBufferTest : public Test {
-public:
-    virtual ~PrivacyBufferTest() {
-        // Delete in reverse order of construction, to be consistent with
-        // regular allocation/deallocation.
-        while (!privacies.empty()) {
-            delete privacies.back();
-            privacies.pop_back();
-        }
-    }
-
-    virtual void SetUp() override { ASSERT_NE(tf.fd, -1); }
-
-    void writeToFdBuffer(std::string str) {
-        ASSERT_TRUE(WriteStringToFile(str, tf.path));
-        ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, 10000));
-        ASSERT_EQ(str.size(), buffer.size());
-    }
-
-    void assertBuffer(PrivacyBuffer& buf, std::string expected) {
-        ASSERT_EQ(buf.size(), expected.size());
-        CaptureStdout();
-        ASSERT_EQ(buf.flush(STDOUT_FILENO), NO_ERROR);
-        ASSERT_THAT(GetCapturedStdout(), StrEq(expected));
-    }
-
-    void assertStrip(uint8_t dest, std::string expected, Privacy* policy) {
-        PrivacySpec spec = PrivacySpec::new_spec(dest);
-        EncodedBuffer::iterator bufData = buffer.data();
-        PrivacyBuffer privacyBuf(policy, bufData);
-        ASSERT_EQ(privacyBuf.strip(spec), NO_ERROR);
-        assertBuffer(privacyBuf, expected);
-    }
-
-    void assertStripByFields(uint8_t dest, std::string expected, int size, Privacy* privacy, ...) {
-        Privacy* list[size + 1];
-        list[0] = privacy;
-        va_list args;
-        va_start(args, privacy);
-        for (int i = 1; i < size; i++) {
-            Privacy* p = va_arg(args, Privacy*);
-            list[i] = p;
-        }
-        va_end(args);
-        list[size] = NULL;
-        assertStrip(dest, expected, create_message_privacy(300, list));
-    }
-
-    Privacy* create_privacy(uint32_t field_id, uint8_t type, uint8_t dest) {
-        Privacy* p = new_uninit_privacy();
-        p->field_id = field_id;
-        p->type = type;
-        p->children = NULL;
-        p->dest = dest;
-        p->patterns = NULL;
-        return p;
-    }
-
-    Privacy* create_message_privacy(uint32_t field_id, Privacy** children) {
-        Privacy* p = new_uninit_privacy();
-        p->field_id = field_id;
-        p->type = MESSAGE_TYPE;
-        p->children = children;
-        p->dest = DEST_DEFAULT_VALUE;
-        p->patterns = NULL;
-        return p;
-    }
-
-    FdBuffer buffer;
-
-private:
-    TemporaryFile tf;
-    // Littering this code with unique_ptr (or similar) is ugly, so we just
-    // mass-free everything after the test completes.
-    std::vector<Privacy*> privacies;
-
-    Privacy* new_uninit_privacy() {
-        Privacy* p = new Privacy;
-        privacies.push_back(p);
-        return p;
-    }
-};
-
-TEST_F(PrivacyBufferTest, NullPolicy) {
-    writeToFdBuffer(STRING_FIELD_0);
-    assertStrip(DEST_EXPLICIT, STRING_FIELD_0, NULL);
-}
-
-TEST_F(PrivacyBufferTest, StripUnsetField) {
-    writeToFdBuffer(STRING_FIELD_0);
-    assertStripByFields(DEST_AUTOMATIC, "", 1, create_privacy(0, STRING_TYPE, DEST_UNSET));
-}
-
-TEST_F(PrivacyBufferTest, StripVarintField) {
-    writeToFdBuffer(VARINT_FIELD_1);
-    assertStripByFields(DEST_EXPLICIT, "", 1, create_privacy(1, OTHER_TYPE, DEST_LOCAL));
-}
-
-TEST_F(PrivacyBufferTest, StripLengthDelimitedField_String) {
-    writeToFdBuffer(STRING_FIELD_2);
-    assertStripByFields(DEST_EXPLICIT, "", 1, create_privacy(2, STRING_TYPE, DEST_LOCAL));
-}
-
-TEST_F(PrivacyBufferTest, StripFixed64Field) {
-    writeToFdBuffer(FIX64_FIELD_3);
-    assertStripByFields(DEST_EXPLICIT, "", 1, create_privacy(3, OTHER_TYPE, DEST_LOCAL));
-}
-
-TEST_F(PrivacyBufferTest, StripFixed32Field) {
-    writeToFdBuffer(FIX32_FIELD_4);
-    assertStripByFields(DEST_EXPLICIT, "", 1, create_privacy(4, OTHER_TYPE, DEST_LOCAL));
-}
-
-TEST_F(PrivacyBufferTest, StripLengthDelimitedField_Message) {
-    writeToFdBuffer(MESSAGE_FIELD_5);
-    assertStripByFields(DEST_EXPLICIT, "", 1, create_privacy(5, MESSAGE_TYPE, DEST_LOCAL));
-}
-
-TEST_F(PrivacyBufferTest, StripNegativeVarint) {
-    writeToFdBuffer(NEGATIVE_VARINT_FIELD_6);
-    assertStripByFields(DEST_EXPLICIT, "", 1, create_privacy(6, OTHER_TYPE, DEST_LOCAL));
-}
-
-TEST_F(PrivacyBufferTest, NoStripVarintField) {
-    writeToFdBuffer(VARINT_FIELD_1);
-    assertStripByFields(DEST_EXPLICIT, VARINT_FIELD_1, 1,
-                        create_privacy(1, OTHER_TYPE, DEST_AUTOMATIC));
-}
-
-TEST_F(PrivacyBufferTest, NoStripLengthDelimitedField_String) {
-    writeToFdBuffer(STRING_FIELD_2);
-    assertStripByFields(DEST_EXPLICIT, STRING_FIELD_2, 1,
-                        create_privacy(2, STRING_TYPE, DEST_AUTOMATIC));
-}
-
-TEST_F(PrivacyBufferTest, NoStripFixed64Field) {
-    writeToFdBuffer(FIX64_FIELD_3);
-    assertStripByFields(DEST_EXPLICIT, FIX64_FIELD_3, 1,
-                        create_privacy(3, OTHER_TYPE, DEST_AUTOMATIC));
-}
-
-TEST_F(PrivacyBufferTest, NoStripFixed32Field) {
-    writeToFdBuffer(FIX32_FIELD_4);
-    assertStripByFields(DEST_EXPLICIT, FIX32_FIELD_4, 1,
-                        create_privacy(4, OTHER_TYPE, DEST_AUTOMATIC));
-}
-
-TEST_F(PrivacyBufferTest, NoStripLengthDelimitedField_Message) {
-    writeToFdBuffer(MESSAGE_FIELD_5);
-    assertStripByFields(DEST_EXPLICIT, MESSAGE_FIELD_5, 1,
-                        create_privacy(5, MESSAGE_TYPE, DEST_AUTOMATIC));
-}
-
-TEST_F(PrivacyBufferTest, NoStripNegativeVarintField) {
-    writeToFdBuffer(NEGATIVE_VARINT_FIELD_6);
-    assertStripByFields(DEST_EXPLICIT, NEGATIVE_VARINT_FIELD_6, 1,
-                        create_privacy(6, OTHER_TYPE, DEST_AUTOMATIC));
-}
-
-TEST_F(PrivacyBufferTest, StripVarintAndString) {
-    writeToFdBuffer(STRING_FIELD_0 + VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3 +
-                    FIX32_FIELD_4);
-    std::string expected = STRING_FIELD_0 + FIX64_FIELD_3 + FIX32_FIELD_4;
-    assertStripByFields(DEST_EXPLICIT, expected, 2, create_privacy(1, OTHER_TYPE, DEST_LOCAL),
-                        create_privacy(2, STRING_TYPE, DEST_LOCAL));
-}
-
-TEST_F(PrivacyBufferTest, StripVarintAndFixed64) {
-    writeToFdBuffer(STRING_FIELD_0 + VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3 +
-                    FIX32_FIELD_4);
-    std::string expected = STRING_FIELD_0 + STRING_FIELD_2 + FIX32_FIELD_4;
-    assertStripByFields(DEST_EXPLICIT, expected, 2, create_privacy(1, OTHER_TYPE, DEST_LOCAL),
-                        create_privacy(3, OTHER_TYPE, DEST_LOCAL));
-}
-
-TEST_F(PrivacyBufferTest, StripVarintInNestedMessage) {
-    writeToFdBuffer(STRING_FIELD_0 + MESSAGE_FIELD_5);
-    Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
-    std::string expected = STRING_FIELD_0 + "\x2a\xd" + STRING_FIELD_2;
-    assertStripByFields(DEST_EXPLICIT, expected, 1, create_message_privacy(5, list));
-}
-
-TEST_F(PrivacyBufferTest, StripFix64AndVarintInNestedMessage) {
-    writeToFdBuffer(STRING_FIELD_0 + FIX64_FIELD_3 + MESSAGE_FIELD_5);
-    Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
-    std::string expected = STRING_FIELD_0 + "\x2a\xd" + STRING_FIELD_2;
-    assertStripByFields(DEST_EXPLICIT, expected, 2, create_privacy(3, OTHER_TYPE, DEST_LOCAL),
-                        create_message_privacy(5, list));
-}
-
-TEST_F(PrivacyBufferTest, ClearAndStrip) {
-    string data = STRING_FIELD_0 + VARINT_FIELD_1;
-    writeToFdBuffer(data);
-    Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
-    EncodedBuffer::iterator bufData = buffer.data();
-    PrivacyBuffer privacyBuf(create_message_privacy(300, list), bufData);
-    PrivacySpec spec1 = PrivacySpec::new_spec(DEST_EXPLICIT);
-    PrivacySpec spec2 = PrivacySpec::new_spec(DEST_LOCAL);
-
-    ASSERT_EQ(privacyBuf.strip(spec1), NO_ERROR);
-    assertBuffer(privacyBuf, STRING_FIELD_0);
-    ASSERT_EQ(privacyBuf.strip(spec2), NO_ERROR);
-    assertBuffer(privacyBuf, data);
-}
-
-TEST_F(PrivacyBufferTest, BadDataInFdBuffer) {
-    writeToFdBuffer("iambaddata");
-    Privacy* list[] = {create_privacy(4, OTHER_TYPE, DEST_AUTOMATIC), NULL};
-    EncodedBuffer::iterator bufData = buffer.data();
-    PrivacyBuffer privacyBuf(create_message_privacy(300, list), bufData);
-    PrivacySpec spec;
-    ASSERT_EQ(privacyBuf.strip(spec), BAD_VALUE);
-}
-
-TEST_F(PrivacyBufferTest, BadDataInNestedMessage) {
-    writeToFdBuffer(STRING_FIELD_0 + MESSAGE_FIELD_5 + "aoeoe");
-    Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
-    Privacy* field5[] = {create_message_privacy(5, list), NULL};
-    EncodedBuffer::iterator bufData = buffer.data();
-    PrivacyBuffer privacyBuf(create_message_privacy(300, field5), bufData);
-    PrivacySpec spec;
-    ASSERT_EQ(privacyBuf.strip(spec), BAD_VALUE);
-}
-
-TEST_F(PrivacyBufferTest, SelfRecursionMessage) {
-    string input = "\x2a\"" + VARINT_FIELD_1 + STRING_FIELD_2 + MESSAGE_FIELD_5;
-    writeToFdBuffer(input);
-    Privacy* field5 = create_message_privacy(5, NULL);
-    Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), field5, NULL};
-    field5->children = list;
-    std::string expected = "\x2a\x1c" + STRING_FIELD_2 + "\x2a\xd" + STRING_FIELD_2;
-    assertStrip(DEST_EXPLICIT, expected, field5);
-}
-
-TEST_F(PrivacyBufferTest, AutoMessage) {
-    writeToFdBuffer(STRING_FIELD_2 + MESSAGE_FIELD_5);
-    Privacy* list[] = {create_privacy(1, OTHER_TYPE, DEST_LOCAL), NULL};
-    Privacy* autoMsg = create_privacy(5, MESSAGE_TYPE, DEST_AUTOMATIC);
-    autoMsg->children = list;
-    std::string expected = "\x2a\xd" + STRING_FIELD_2;
-    assertStripByFields(DEST_AUTOMATIC, expected, 1, autoMsg);
-}
diff --git a/cmds/incidentd/tests/PrivacyFilter_test.cpp b/cmds/incidentd/tests/PrivacyFilter_test.cpp
new file mode 100644
index 0000000..5c05aac
--- /dev/null
+++ b/cmds/incidentd/tests/PrivacyFilter_test.cpp
@@ -0,0 +1,302 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#define DEBUG false
+#include "Log.h"
+
+#include "FdBuffer.h"
+#include "PrivacyFilter.h"
+
+#include <android-base/file.h>
+#include <android-base/test_utils.h>
+#include <android/os/IncidentReportArgs.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <string.h>
+
+using namespace android;
+using namespace android::base;
+using namespace android::os;
+using namespace android::os::incidentd;
+using ::testing::StrEq;
+using ::testing::Test;
+using ::testing::internal::CaptureStdout;
+using ::testing::internal::GetCapturedStdout;
+
+const uint8_t OTHER_TYPE = 1;
+const uint8_t STRING_TYPE = 9;
+const uint8_t MESSAGE_TYPE = 11;
+const std::string STRING_FIELD_0 = "\x02\viamtestdata";
+const std::string VARINT_FIELD_1 = "\x08\x96\x01";  // 150
+const std::string STRING_FIELD_2 = "\x12\vandroidwins";
+const std::string FIX64_FIELD_3 = "\x19\xff\xff\xff\xff\xff\xff\xff\xff";  // -1
+const std::string FIX32_FIELD_4 = "\x25\xff\xff\xff\xff";                  // -1
+const std::string MESSAGE_FIELD_5 = "\x2a\x10" + VARINT_FIELD_1 + STRING_FIELD_2;
+const std::string NEGATIVE_VARINT_FIELD_6 = "\x30\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01";  // -1
+
+#if 0
+class PrivacyFilterTest : public Test {
+public:
+    virtual ~PrivacyFilterTest() {
+        // Delete in reverse order of construction, to be consistent with
+        // regular allocation/deallocation.
+        while (!privacies.empty()) {
+            delete privacies.back();
+            privacies.pop_back();
+        }
+    }
+
+    virtual void SetUp() override { ASSERT_NE(tf.fd, -1); }
+
+    void writeToFdBuffer(std::string str) {
+        ASSERT_TRUE(WriteStringToFile(str, tf.path));
+        ASSERT_EQ(NO_ERROR, buffer.read(tf.fd, 10000));
+        ASSERT_EQ(str.size(), buffer.size());
+    }
+
+    void assertBuffer(PrivacyFilter& buf, std::string expected) {
+        ASSERT_EQ(buf.size(), expected.size());
+        CaptureStdout();
+        ASSERT_EQ(buf.flush(STDOUT_FILENO), NO_ERROR);
+        ASSERT_THAT(GetCapturedStdout(), StrEq(expected));
+    }
+
+    void assertStrip(uint8_t privacyPolicy, std::string expected, Privacy* policy) {
+        PrivacySpec spec = PrivacySpec::new_spec(privacyPolicy);
+        EncodedBuffer::iterator bufData = buffer.data();
+        PrivacyFilter filter(policy, bufData);
+        ASSERT_EQ(filter.strip(spec), NO_ERROR);
+        assertBuffer(filter, expected);
+    }
+
+    void assertStripByFields(uint8_t privacyPolicy, std::string expected, int size,
+            Privacy* privacy, ...) {
+        Privacy* list[size + 1];
+        list[0] = privacy;
+        va_list args;
+        va_start(args, privacy);
+        for (int i = 1; i < size; i++) {
+            Privacy* p = va_arg(args, Privacy*);
+            list[i] = pPrivacyFilter
+        }
+        va_end(args);
+        list[size] = NULL;
+        assertStrip(privacyPolicy, expected, create_message_privacy(300, list));
+    }
+
+    Privacy* create_privacy(uint32_t field_id, uint8_t type, uint8_t privacyPolicy) {
+        Privacy* p = new_uninit_privacy();
+        p->field_id = field_id;
+        p->type = type;
+        p->children = NULL;
+        p->policy = privacyPolicy;
+        p->patterns = NULL;
+        return p;
+    }
+
+    Privacy* create_message_privacy(uint32_t field_id, Privacy** children) {
+        Privacy* p = new_uninit_privacy();
+        p->field_id = field_id;
+        p->type = MESSAGE_TYPE;
+        p->children = children;
+        p->policy = PRIVACY_POLICY_UNSET;
+        p->patterns = NULL;
+        return p;
+    }
+
+    FdBuffer buffer;
+
+private:
+    TemporaryFile tf;
+    // Littering this code with unique_ptr (or similar) is ugly, so we just
+    // mass-free everything after the test completes.
+    std::vector<Privacy*> privacies;
+
+    Privacy* new_uninit_privacy() {
+        Privacy* p = new Privacy;
+        privacies.push_back(p);
+        return p;
+    }
+};
+
+TEST_F(PrivacyFilterTest, NullPolicy) {
+    writeToFdBuffer(STRING_FIELD_0);
+    assertStrip(PRIVACY_POLICY_EXPLICIT, STRING_FIELD_0, NULL);
+}
+
+TEST_F(PrivacyFilterTest, StripUnsetField) {
+    writeToFdBuffer(STRING_FIELD_0);
+    assertStripByFields(PRIVACY_POLICY_AUTOMATIC, "", 1,
+            create_privacy(0, STRING_TYPE, PRIVACY_POLICY_UNSET));
+}
+
+TEST_F(PrivacyFilterTest, StripVarintField) {
+    writeToFdBuffer(VARINT_FIELD_1);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, "", 1,
+            create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_LOCAL));
+}
+
+TEST_F(PrivacyFilterTest, StripLengthDelimitedField_String) {
+    writeToFdBuffer(STRING_FIELD_2);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, "", 1,
+            create_privacy(2, STRING_TYPE, PRIVACY_POLICY_LOCAL));
+}
+
+TEST_F(PrivacyFilterTest, StripFixed64Field) {
+    writeToFdBuffer(FIX64_FIELD_3);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, "", 1,
+            create_privacy(3, OTHER_TYPE, PRIVACY_POLICY_LOCAL));
+}
+
+TEST_F(PrivacyFilterTest, StripFixed32Field) {
+    writeToFdBuffer(FIX32_FIELD_4);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, "", 1,
+            create_privacy(4, OTHER_TYPE, PRIVACY_POLICY_LOCAL));
+}
+
+TEST_F(PrivacyFilterTest, StripLengthDelimitedField_Message) {
+    writeToFdBuffer(MESSAGE_FIELD_5);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, "", 1,
+            create_privacy(5, MESSAGE_TYPE, PRIVACY_POLICY_LOCAL));
+}
+
+TEST_F(PrivacyFilterTest, StripNegativeVarint) {
+    writeToFdBuffer(NEGATIVE_VARINT_FIELD_6);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, "", 1,
+            create_privacy(6, OTHER_TYPE, PRIVACY_POLICY_LOCAL));
+}
+
+TEST_F(PrivacyFilterTest, NoStripVarintField) {
+    writeToFdBuffer(VARINT_FIELD_1);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, VARINT_FIELD_1, 1,
+            create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_AUTOMATIC));
+}
+
+TEST_F(PrivacyFilterTest, NoStripLengthDelimitedField_String) {
+    writeToFdBuffer(STRING_FIELD_2);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, STRING_FIELD_2, 1,
+            create_privacy(2, STRING_TYPE, PRIVACY_POLICY_AUTOMATIC));
+}
+
+TEST_F(PrivacyFilterTest, NoStripFixed64Field) {
+    writeToFdBuffer(FIX64_FIELD_3);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, FIX64_FIELD_3, 1,
+            create_privacy(3, OTHER_TYPE, PRIVACY_POLICY_AUTOMATIC));
+}
+
+TEST_F(PrivacyFilterTest, NoStripFixed32Field) {
+    writeToFdBuffer(FIX32_FIELD_4);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, FIX32_FIELD_4, 1,
+            create_privacy(4, OTHER_TYPE, PRIVACY_POLICY_AUTOMATIC));
+}
+
+TEST_F(PrivacyFilterTest, NoStripLengthDelimitedField_Message) {
+    writeToFdBuffer(MESSAGE_FIELD_5);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, MESSAGE_FIELD_5, 1,
+            create_privacy(5, MESSAGE_TYPE, PRIVACY_POLICY_AUTOMATIC));
+}
+
+TEST_F(PrivacyFilterTest, NoStripNegativeVarintField) {
+    writeToFdBuffer(NEGATIVE_VARINT_FIELD_6);
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, NEGATIVE_VARINT_FIELD_6, 1,
+            create_privacy(6, OTHER_TYPE, PRIVACY_POLICY_AUTOMATIC));
+}
+
+TEST_F(PrivacyFilterTest, StripVarintAndString) {
+    writeToFdBuffer(STRING_FIELD_0 + VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3 +
+                    FIX32_FIELD_4);
+    std::string expected = STRING_FIELD_0 + FIX64_FIELD_3 + FIX32_FIELD_4;
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, expected, 2,
+            create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_LOCAL),
+            create_privacy(2, STRING_TYPE, PRIVACY_POLICY_LOCAL));
+}
+
+TEST_F(PrivacyFilterTest, StripVarintAndFixed64) {
+    writeToFdBuffer(STRING_FIELD_0 + VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3 +
+                    FIX32_FIELD_4);
+    std::string expected = STRING_FIELD_0 + STRING_FIELD_2 + FIX32_FIELD_4;
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, expected, 2,
+            create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_LOCAL),
+            create_privacy(3, OTHER_TYPE, PRIVACY_POLICY_LOCAL));
+}
+
+TEST_F(PrivacyFilterTest, StripVarintInNestedMessage) {
+    writeToFdBuffer(STRING_FIELD_0 + MESSAGE_FIELD_5);
+    Privacy* list[] = {create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_LOCAL), NULL};
+    std::string expected = STRING_FIELD_0 + "\x2a\xd" + STRING_FIELD_2;
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, expected, 1, create_message_privacy(5, list));
+}
+
+TEST_F(PrivacyFilterTest, StripFix64AndVarintInNestedMessage) {
+    writeToFdBuffer(STRING_FIELD_0 + FIX64_FIELD_3 + MESSAGE_FIELD_5);
+    Privacy* list[] = {create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_LOCAL), NULL};
+    std::string expected = STRING_FIELD_0 + "\x2a\xd" + STRING_FIELD_2;
+    assertStripByFields(PRIVACY_POLICY_EXPLICIT, expected, 2,
+            create_privacy(3, OTHER_TYPE, PRIVACY_POLICY_LOCAL),
+            create_message_privacy(5, list));
+}
+
+TEST_F(PrivacyFilterTest, ClearAndStrip) {
+    string data = STRING_FIELD_0 + VARINT_FIELD_1;
+    writeToFdBuffer(data);
+    Privacy* list[] = {create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_LOCAL), NULL};
+    EncodedBuffer::iterator bufData = buffer.data();
+    PrivacyFilter filter(create_message_privacy(300, list), bufData);
+    PrivacySpec spec1 = PrivacySpec::new_spec(PRIVACY_POLICY_EXPLICIT);
+    PrivacySpec spec2 = PrivacySpec::new_spec(PRIVACY_POLICY_LOCAL);
+
+    ASSERT_EQ(filter.strip(spec1), NO_ERROR);
+    assertBuffer(filter, STRING_FIELD_0);
+    ASSERT_EQ(filter.strip(spec2), NO_ERROR);
+    assertBuffer(filter, data);
+}
+
+TEST_F(PrivacyFilterTest, BadDataInFdBuffer) {
+    writeToFdBuffer("iambaddata");
+    Privacy* list[] = {create_privacy(4, OTHER_TYPE, PRIVACY_POLICY_AUTOMATIC), NULL};
+    EncodedBuffer::iterator bufData = buffer.data();
+    PrivacyFilter filter(create_message_privacy(300, list), bufData);
+    PrivacySpec spec;
+    ASSERT_EQ(filter.strip(spec), BAD_VALUE);
+}
+
+TEST_F(PrivacyFilterTest, BadDataInNestedMessage) {
+    writeToFdBuffer(STRING_FIELD_0 + MESSAGE_FIELD_5 + "aoeoe");
+    Privacy* list[] = {create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_LOCAL), NULL};
+    Privacy* field5[] = {create_message_privacy(5, list), NULL};
+    EncodedBuffer::iterator bufData = buffer.data();
+    PrivacyFilter filter(create_message_privacy(300, field5), bufData);
+    PrivacySpec spec;
+    ASSERT_EQ(filter.strip(spec), BAD_VALUE);
+}
+
+TEST_F(PrivacyFilterTest, SelfRecursionMessage) {
+    string input = "\x2a\"" + VARINT_FIELD_1 + STRING_FIELD_2 + MESSAGE_FIELD_5;
+    writeToFdBuffer(input);
+    Privacy* field5 = create_message_privacy(5, NULL);
+    Privacy* list[] = {create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_LOCAL), field5, NULL};
+    field5->children = list;
+    std::string expected = "\x2a\x1c" + STRING_FIELD_2 + "\x2a\xd" + STRING_FIELD_2;
+    assertStrip(PRIVACY_POLICY_EXPLICIT, expected, field5);
+}
+
+TEST_F(PrivacyFilterTest, AutoMessage) {
+    writeToFdBuffer(STRING_FIELD_2 + MESSAGE_FIELD_5);
+    Privacy* list[] = {create_privacy(1, OTHER_TYPE, PRIVACY_POLICY_LOCAL), NULL};
+    Privacy* autoMsg = create_privacy(5, MESSAGE_TYPE, PRIVACY_POLICY_AUTOMATIC);
+    autoMsg->children = list;
+    std::string expected = "\x2a\xd" + STRING_FIELD_2;
+    assertStripByFields(PRIVACY_POLICY_AUTOMATIC, expected, 1, autoMsg);
+}
+
+#endif
diff --git a/cmds/incidentd/tests/Reporter_test.cpp b/cmds/incidentd/tests/Reporter_test.cpp
index b5e41d7..9becf17 100644
--- a/cmds/incidentd/tests/Reporter_test.cpp
+++ b/cmds/incidentd/tests/Reporter_test.cpp
@@ -17,7 +17,7 @@
 #include "Reporter.h"
 
 #include <android/os/BnIncidentReportStatusListener.h>
-#include <frameworks/base/libs/incident/proto/android/os/header.pb.h>
+#include <frameworks/base/core/proto/android/os/header.pb.h>
 
 #include <dirent.h>
 #include <string.h>
@@ -36,6 +36,7 @@
 using ::testing::Test;
 
 namespace {
+/*
 void getHeaderData(const IncidentHeaderProto& headerProto, vector<uint8_t>* out) {
     out->clear();
     auto serialized = headerProto.SerializeAsString();
@@ -43,6 +44,7 @@
     out->resize(serialized.length());
     std::copy(serialized.begin(), serialized.end(), out->begin());
 }
+*/
 }
 
 class TestListener : public IIncidentReportStatusListener {
@@ -82,6 +84,24 @@
         return Status::ok();
     };
 
+    int sectionStarted(int sectionId) const {
+        map<int, int>::const_iterator found = startSections.find(sectionId);
+        if (found != startSections.end()) {
+            return found->second;
+        } else {
+            return 0;
+        }
+    };
+
+    int sectionFinished(int sectionId) const {
+        map<int, int>::const_iterator found = finishSections.find(sectionId);
+        if (found != finishSections.end()) {
+            return found->second;
+        } else {
+            return 0;
+        }
+    };
+
 protected:
     virtual IBinder* onAsBinder() override { return nullptr; };
 };
@@ -89,8 +109,7 @@
 class ReporterTest : public Test {
 public:
     virtual void SetUp() {
-        reporter = new Reporter(td.path);
-        l = new TestListener();
+        listener = new TestListener();
     }
 
     vector<string> InspectFiles() {
@@ -115,9 +134,7 @@
 
 protected:
     TemporaryDir td;
-    ReportRequestSet requests;
-    sp<Reporter> reporter;
-    sp<TestListener> l;
+    sp<TestListener> listener;
     size_t size;
 };
 
@@ -132,18 +149,17 @@
     ASSERT_TRUE(args1.containsSection(3));
 }
 
-TEST_F(ReporterTest, ReportRequestSetEmpty) {
-    requests.setMainFd(STDOUT_FILENO);
-    ASSERT_EQ(requests.mainFd(), STDOUT_FILENO);
-}
-
+/*
 TEST_F(ReporterTest, RunReportEmpty) {
+    vector<sp<ReportRequest>> requests;
+    sp<Reporter> reporter = new Reporter(requests, td.path);
+
     ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
-    EXPECT_EQ(l->startInvoked, 0);
-    EXPECT_EQ(l->finishInvoked, 0);
-    EXPECT_TRUE(l->startSections.empty());
-    EXPECT_TRUE(l->finishSections.empty());
-    EXPECT_EQ(l->failedInvoked, 0);
+    EXPECT_EQ(0, listener->startInvoked);
+    EXPECT_EQ(0, listener->finishInvoked);
+    EXPECT_TRUE(listener->startSections.empty());
+    EXPECT_TRUE(listener->finishSections.empty());
+    EXPECT_EQ(0, listener->failedInvoked);
 }
 
 TEST_F(ReporterTest, RunReportWithHeaders) {
@@ -157,11 +173,11 @@
     vector<uint8_t> out;
     getHeaderData(header, &out);
     args2.addHeader(out);
-    sp<ReportRequest> r1 = new ReportRequest(args1, l, tf.fd);
-    sp<ReportRequest> r2 = new ReportRequest(args2, l, tf.fd);
 
-    reporter->batch.add(r1);
-    reporter->batch.add(r2);
+    sp<WorkDirectory> workDirectory = new WorkDirectory(td.path);
+    sp<ReportBatch> batch = new ReportBatch();
+    batch->addStreamingReport(args1, listener, tf.fd);
+    sp<Reporter> reporter = new Reporter(workDirectory, batch);
 
     ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
 
@@ -170,11 +186,11 @@
     EXPECT_THAT(result, StrEq("\n\x2"
                               "\b\f"));
 
-    EXPECT_EQ(l->startInvoked, 2);
-    EXPECT_EQ(l->finishInvoked, 2);
-    EXPECT_TRUE(l->startSections.empty());
-    EXPECT_TRUE(l->finishSections.empty());
-    EXPECT_EQ(l->failedInvoked, 0);
+    EXPECT_EQ(listener->startInvoked, 1);
+    EXPECT_EQ(listener->finishInvoked, 1);
+    EXPECT_FALSE(listener->startSections.empty());
+    EXPECT_FALSE(listener->finishSections.empty());
+    EXPECT_EQ(listener->failedInvoked, 0);
 }
 
 TEST_F(ReporterTest, RunReportToGivenDirectory) {
@@ -188,8 +204,10 @@
     args.addHeader(out);
     getHeaderData(header2, &out);
     args.addHeader(out);
-    sp<ReportRequest> r = new ReportRequest(args, l, -1);
-    reporter->batch.add(r);
+
+    vector<sp<ReportRequest>> requests;
+    requests.push_back(new ReportRequest(args, listener, -1));
+    sp<Reporter> reporter = new Reporter(requests, td.path);
 
     ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
     vector<string> results = InspectFiles();
@@ -204,14 +222,36 @@
 TEST_F(ReporterTest, ReportMetadata) {
     IncidentReportArgs args;
     args.addSection(1);
-    args.setDest(android::os::DEST_EXPLICIT);
-    sp<ReportRequest> r = new ReportRequest(args, l, -1);
-    reporter->batch.add(r);
+    args.setPrivacyPolicy(android::os::PRIVACY_POLICY_EXPLICIT);
+    vector<sp<ReportRequest>> requests;
+    requests.push_back(new ReportRequest(args, listener, -1));
+    sp<Reporter> reporter = new Reporter(requests, td.path);
 
     ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
-    IncidentMetadata metadata = reporter->batch.metadata();
+    IncidentMetadata metadata = reporter->metadata();
     EXPECT_EQ(IncidentMetadata_Destination_EXPLICIT, metadata.dest());
     EXPECT_EQ(1, metadata.request_size());
     EXPECT_TRUE(metadata.use_dropbox());
     EXPECT_EQ(0, metadata.sections_size());
 }
+
+TEST_F(ReporterTest, RunReportLocal_1_2) {
+    IncidentReportArgs args;
+    args.addSection(1);
+    args.addSection(2);
+    args.setPrivacyPolicy(android::os::PRIVACY_POLICY_LOCAL);
+
+    vector<sp<ReportRequest>> requests;
+    requests.push_back(new ReportRequest(args, listener, -1));
+    sp<Reporter> reporter = new Reporter(requests, td.path);
+
+    ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size));
+
+    EXPECT_EQ(1, listener->sectionStarted(1));
+    EXPECT_EQ(1, listener->sectionFinished(1));
+    EXPECT_EQ(1, listener->sectionStarted(2));
+    EXPECT_EQ(1, listener->sectionFinished(2));
+
+    // TODO: validate that a file was created in the directory
+}
+*/
diff --git a/cmds/incidentd/tests/Section_test.cpp b/cmds/incidentd/tests/Section_test.cpp
index 24454ed..858f7d0 100644
--- a/cmds/incidentd/tests/Section_test.cpp
+++ b/cmds/incidentd/tests/Section_test.cpp
@@ -20,7 +20,8 @@
 #include <android-base/test_utils.h>
 #include <android/os/IncidentReportArgs.h>
 #include <android/util/protobuf.h>
-#include <frameworks/base/libs/incident/proto/android/os/header.pb.h>
+#include <frameworks/base/core/proto/android/os/incident.pb.h>
+#include <frameworks/base/core/proto/android/os/header.pb.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <string.h>
@@ -62,7 +63,6 @@
 
 protected:
     TemporaryFile tf;
-    ReportRequestSet requests;
 
     const std::string kTestPath = GetExecutableDirectory();
     const std::string kTestDataPath = kTestPath + "/testdata/";
@@ -74,7 +74,8 @@
     virtual ~SimpleListener(){};
 
     virtual Status onReportStarted() { return Status::ok(); };
-    virtual Status onReportSectionStatus(int /*section*/, int /*status*/) { return Status::ok(); };
+    virtual Status onReportSectionStatus(int /*section*/, int /*status*/)
+            { return Status::ok(); };
     virtual Status onReportFinished() { return Status::ok(); };
     virtual Status onReportFailed() { return Status::ok(); };
 
@@ -82,67 +83,30 @@
     virtual IBinder* onAsBinder() override { return nullptr; };
 };
 
-namespace {
-void getHeaderData(const IncidentHeaderProto& headerProto, vector<uint8_t>* out) {
-    out->clear();
-    auto serialized = headerProto.SerializeAsString();
-    if (serialized.empty()) return;
-    out->resize(serialized.length());
-    std::copy(serialized.begin(), serialized.end(), out->begin());
-}
-}
-
-TEST_F(SectionTest, HeaderSection) {
-    HeaderSection hs;
-
-    IncidentReportArgs args1, args2;
-    args1.addSection(1);
-    args1.addSection(2);
-    args2.setAll(true);
-
-    IncidentHeaderProto head1, head2;
-    head1.set_reason("axe");
-    head2.set_reason("pup");
-
-    vector<uint8_t> out;
-    getHeaderData(head1, &out);
-    args1.addHeader(out);
-
-    getHeaderData(head2, &out);
-    args1.addHeader(out);
-
-    getHeaderData(head2, &out);
-    args2.addHeader(out);
-
-    requests.add(new ReportRequest(args1, new SimpleListener(), -1));
-    requests.add(new ReportRequest(args2, new SimpleListener(), tf.fd));
-    requests.setMainFd(STDOUT_FILENO);
-
-    std::string content;
-    CaptureStdout();
-    ASSERT_EQ(NO_ERROR, hs.Execute(&requests));
-    EXPECT_THAT(GetCapturedStdout(), StrEq("\n\x5"
-                                           "\x12\x3"
-                                           "axe\n\x05\x12\x03pup"));
-
-    EXPECT_TRUE(ReadFileToString(tf.path, &content));
-    EXPECT_THAT(content, StrEq("\n\x05\x12\x03pup"));
-}
-
+/*
 TEST_F(SectionTest, MetadataSection) {
     MetadataSection ms;
-    const std::string testFile = kTestDataPath + "metadata.txt";
-    std::string expect;
-    ASSERT_TRUE(ReadFileToString(testFile, &expect));
 
-    requests.setMainFd(STDOUT_FILENO);
-    requests.setMainDest(android::os::DEST_LOCAL);
-    requests.sectionStats(1)->set_success(true);
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
+
+    requestSet.setMainPrivacyPolicy(android::os::PRIVACY_POLICY_LOCAL);
+    requestSet.editSectionStats(1)->set_success(true);
 
     CaptureStdout();
-    ASSERT_EQ(NO_ERROR, ms.Execute(&requests));
-    // Notice message_lite.h ParseFromString doesn't work so we just match the bytes directly.
-    EXPECT_THAT(GetCapturedStdout(), StrEq(expect));
+    ASSERT_EQ(NO_ERROR, ms.Execute(&requestSet));
+
+    string out = GetCapturedStdout();
+    IncidentProto expectedIncident;
+    expectedIncident.ParseFromArray(out.data(), out.size());
+    ASSERT_TRUE(expectedIncident.has_metadata());
+    const IncidentMetadata& expectedMetadata = expectedIncident.metadata();
+    ASSERT_EQ(IncidentMetadata::LOCAL, expectedMetadata.dest());
+    ASSERT_EQ(1, expectedMetadata.sections_size());
+    ASSERT_EQ(1, expectedMetadata.sections(0).id());
+    ASSERT_TRUE(expectedMetadata.sections(0).has_success());
+    ASSERT_TRUE(expectedMetadata.sections(0).success());
 }
 
 TEST_F(SectionTest, FileSection) {
@@ -150,27 +114,35 @@
 
     ASSERT_TRUE(WriteStringToFile("iamtestdata", tf.path));
 
-    requests.setMainFd(STDOUT_FILENO);
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
 
     CaptureStdout();
-    ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, fs.Execute(&requestSet));
     // The input string is reversed in incident helper
     // The length is 11, in 128Varint it is "0000 1011" -> \v
     EXPECT_THAT(GetCapturedStdout(), StrEq("\xa\vatadtsetmai"));
 }
 
 TEST_F(SectionTest, FileSectionNotExist) {
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+
     FileSection fs1(NOOP_PARSER, "notexist", QUICK_TIMEOUT_MS);
-    ASSERT_EQ(NO_ERROR, fs1.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, fs1.Execute(&requestSet));
 
     FileSection fs2(NOOP_PARSER, "notexist", QUICK_TIMEOUT_MS);
-    ASSERT_EQ(NO_ERROR, fs2.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, fs2.Execute(&requestSet));
 }
 
 TEST_F(SectionTest, FileSectionTimeout) {
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+
     FileSection fs(TIMEOUT_PARSER, tf.path, QUICK_TIMEOUT_MS);
-    ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
-    ASSERT_TRUE(requests.sectionStats(TIMEOUT_PARSER)->timed_out());
+    ASSERT_EQ(NO_ERROR, fs.Execute(&requestSet));
+    ASSERT_TRUE(requestSet.getSectionStats(TIMEOUT_PARSER)->timed_out());
 }
 
 TEST_F(SectionTest, GZipSection) {
@@ -178,10 +150,12 @@
     const std::string testGzFile = testFile + ".gz";
     GZipSection gs(NOOP_PARSER, "/tmp/nonexist", testFile.c_str(), NULL);
 
-    requests.setMainFd(tf.fd);
-    requests.setMainDest(android::os::DEST_LOCAL);
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(tf.fd);
+    requestSet.setMainPrivacyPolicy(android::os::PRIVACY_POLICY_LOCAL);
 
-    ASSERT_EQ(NO_ERROR, gs.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, gs.Execute(&requestSet));
     std::string expected, gzFile, actual;
     ASSERT_TRUE(ReadFileToString(testGzFile, &gzFile));
     ASSERT_TRUE(ReadFileToString(tf.path, &actual));
@@ -200,8 +174,10 @@
 
 TEST_F(SectionTest, GZipSectionNoFileFound) {
     GZipSection gs(NOOP_PARSER, "/tmp/nonexist1", "/tmp/nonexist2", NULL);
-    requests.setMainFd(STDOUT_FILENO);
-    ASSERT_EQ(NO_ERROR, gs.Execute(&requests));
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
+    ASSERT_EQ(NO_ERROR, gs.Execute(&requestSet));
 }
 
 TEST_F(SectionTest, CommandSectionConstructor) {
@@ -220,51 +196,65 @@
 
 TEST_F(SectionTest, CommandSectionEcho) {
     CommandSection cs(REVERSE_PARSER, "/system/bin/echo", "about", NULL);
-    requests.setMainFd(STDOUT_FILENO);
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
     CaptureStdout();
-    ASSERT_EQ(NO_ERROR, cs.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, cs.Execute(&requestSet));
     EXPECT_THAT(GetCapturedStdout(), StrEq("\xa\x06\ntuoba"));
 }
 
 TEST_F(SectionTest, CommandSectionCommandTimeout) {
     CommandSection cs(NOOP_PARSER, QUICK_TIMEOUT_MS, "/system/bin/yes", NULL);
-    ASSERT_EQ(NO_ERROR, cs.Execute(&requests));
-    ASSERT_TRUE(requests.sectionStats(NOOP_PARSER)->timed_out());
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    ASSERT_EQ(NO_ERROR, cs.Execute(&requestSet));
+    ASSERT_TRUE(requestSet.getSectionStats(NOOP_PARSER)->timed_out());
 }
 
 TEST_F(SectionTest, CommandSectionIncidentHelperTimeout) {
     CommandSection cs(TIMEOUT_PARSER, QUICK_TIMEOUT_MS, "/system/bin/echo", "about", NULL);
-    requests.setMainFd(STDOUT_FILENO);
-    ASSERT_EQ(NO_ERROR, cs.Execute(&requests));
-    ASSERT_TRUE(requests.sectionStats(TIMEOUT_PARSER)->timed_out());
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
+    ASSERT_EQ(NO_ERROR, cs.Execute(&requestSet));
+    ASSERT_TRUE(requestSet.getSectionStats(TIMEOUT_PARSER)->timed_out());
 }
 
 TEST_F(SectionTest, CommandSectionBadCommand) {
     CommandSection cs(NOOP_PARSER, "echoo", "about", NULL);
-    ASSERT_EQ(NAME_NOT_FOUND, cs.Execute(&requests));
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    ASSERT_EQ(NAME_NOT_FOUND, cs.Execute(&requestSet));
 }
 
 TEST_F(SectionTest, CommandSectionBadCommandAndTimeout) {
     CommandSection cs(TIMEOUT_PARSER, QUICK_TIMEOUT_MS, "nonexistcommand", "-opt", NULL);
     // timeout will return first
-    ASSERT_EQ(NO_ERROR, cs.Execute(&requests));
-    ASSERT_TRUE(requests.sectionStats(TIMEOUT_PARSER)->timed_out());
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    ASSERT_EQ(NO_ERROR, cs.Execute(&requestSet));
+    ASSERT_TRUE(requestSet.getSectionStats(TIMEOUT_PARSER)->timed_out());
 }
 
 TEST_F(SectionTest, LogSectionBinary) {
     LogSection ls(1, LOG_ID_EVENTS);
-    requests.setMainFd(STDOUT_FILENO);
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
     CaptureStdout();
-    ASSERT_EQ(NO_ERROR, ls.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, ls.Execute(&requestSet));
     std::string results = GetCapturedStdout();
     EXPECT_FALSE(results.empty());
 }
 
 TEST_F(SectionTest, LogSectionSystem) {
     LogSection ls(1, LOG_ID_SYSTEM);
-    requests.setMainFd(STDOUT_FILENO);
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
     CaptureStdout();
-    ASSERT_EQ(NO_ERROR, ls.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, ls.Execute(&requestSet));
     std::string results = GetCapturedStdout();
     EXPECT_FALSE(results.empty());
 }
@@ -274,10 +264,12 @@
 
     ASSERT_TRUE(WriteStringToFile(VARINT_FIELD_1 + STRING_FIELD_2 + FIX64_FIELD_3, tf.path));
 
-    requests.setMainFd(STDOUT_FILENO);
+    vector<sp<ReportRequest>> requests;
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
 
     CaptureStdout();
-    ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, fs.Execute(&requestSet));
     EXPECT_THAT(GetCapturedStdout(), StrEq("\x02\r" + STRING_FIELD_2));
 }
 
@@ -287,13 +279,16 @@
 
     IncidentReportArgs args;
     args.setAll(true);
-    args.setDest(0);
+    args.setPrivacyPolicy(0);
     sp<ReportRequest> badFdRequest = new ReportRequest(args, new SimpleListener(), 1234567);
-    requests.add(badFdRequest);
-    requests.setMainFd(STDOUT_FILENO);
+
+    vector<sp<ReportRequest>> requests;
+    requests.push_back(badFdRequest);
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
 
     CaptureStdout();
-    ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, fs.Execute(&requestSet));
     EXPECT_THAT(GetCapturedStdout(), StrEq("\x02\r" + STRING_FIELD_2));
     EXPECT_EQ(badFdRequest->err, -EBADF);
 }
@@ -304,9 +299,13 @@
 
     IncidentReportArgs args;
     args.setAll(true);
-    args.setDest(0);
-    requests.add(new ReportRequest(args, new SimpleListener(), -1));
-    EXPECT_EQ(fs.Execute(&requests), -EBADF);
+    args.setPrivacyPolicy(0);
+
+    vector<sp<ReportRequest>> requests;
+    requests.push_back(new ReportRequest(args, new SimpleListener(), -1));
+    ReportRequestSet requestSet(requests);
+
+    EXPECT_EQ(fs.Execute(&requestSet), -EBADF);
 }
 
 TEST_F(SectionTest, TestMultipleRequests) {
@@ -320,17 +319,20 @@
 
     IncidentReportArgs args1, args2, args3;
     args1.setAll(true);
-    args1.setDest(android::os::DEST_LOCAL);
+    args1.setPrivacyPolicy(android::os::PRIVACY_POLICY_LOCAL);
     args2.setAll(true);
-    args2.setDest(android::os::DEST_EXPLICIT);
+    args2.setPrivacyPolicy(android::os::PRIVACY_POLICY_EXPLICIT);
     sp<SimpleListener> l = new SimpleListener();
-    requests.add(new ReportRequest(args1, l, output1.fd));
-    requests.add(new ReportRequest(args2, l, output2.fd));
-    requests.add(new ReportRequest(args3, l, output3.fd));
-    requests.setMainFd(STDOUT_FILENO);
+
+    vector<sp<ReportRequest>> requests;
+    requests.push_back(new ReportRequest(args1, l, output1.fd));
+    requests.push_back(new ReportRequest(args2, l, output2.fd));
+    requests.push_back(new ReportRequest(args3, l, output3.fd));
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
 
     CaptureStdout();
-    ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, fs.Execute(&requestSet));
     EXPECT_THAT(GetCapturedStdout(), StrEq("\x02\r" + STRING_FIELD_2));
 
     std::string content, expect;
@@ -361,18 +363,21 @@
 
     IncidentReportArgs args1, args2, args3;
     args1.setAll(true);
-    args1.setDest(android::os::DEST_EXPLICIT);
+    args1.setPrivacyPolicy(android::os::PRIVACY_POLICY_EXPLICIT);
     args2.setAll(true);
-    args2.setDest(android::os::DEST_EXPLICIT);
+    args2.setPrivacyPolicy(android::os::PRIVACY_POLICY_EXPLICIT);
     args3.setAll(true);
     sp<SimpleListener> l = new SimpleListener();
-    requests.add(new ReportRequest(args1, l, output1.fd));
-    requests.add(new ReportRequest(args2, l, output2.fd));
-    requests.add(new ReportRequest(args3, l, output3.fd));
-    requests.setMainFd(STDOUT_FILENO);
+
+    vector<sp<ReportRequest>> requests;
+    requests.push_back(new ReportRequest(args1, l, output1.fd));
+    requests.push_back(new ReportRequest(args2, l, output2.fd));
+    requests.push_back(new ReportRequest(args3, l, output3.fd));
+    ReportRequestSet requestSet(requests);
+    requestSet.setMainFd(STDOUT_FILENO);
 
     CaptureStdout();
-    ASSERT_EQ(NO_ERROR, fs.Execute(&requests));
+    ASSERT_EQ(NO_ERROR, fs.Execute(&requestSet));
     EXPECT_THAT(GetCapturedStdout(), StrEq("\x02\r" + STRING_FIELD_2));
 
     std::string content, expect;
@@ -390,3 +395,4 @@
     EXPECT_TRUE(ReadFileToString(output3.path, &content));
     EXPECT_THAT(content, StrEq(string("\x02") + c + STRING_FIELD_2));
 }
+*/
diff --git a/cmds/incidentd/tests/section_list.cpp b/cmds/incidentd/tests/section_list.cpp
index 1d7f2b6..3a45af0 100644
--- a/cmds/incidentd/tests/section_list.cpp
+++ b/cmds/incidentd/tests/section_list.cpp
@@ -1,19 +1,65 @@
 // This file is a dummy section_list.cpp used for test only.
 #include "section_list.h"
 
+#include "frameworks/base/cmds/incidentd/tests/test_proto.pb.h"
+
+
 namespace android {
 namespace os {
 namespace incidentd {
 
-const Section* SECTION_LIST[] = {NULL};
+class TestSection: public Section {
+public:
+    TestSection(int id);
+    ~TestSection();
+    virtual status_t Execute(ReportWriter* writer) const;
+};
 
-Privacy sub_field_1{1, 1, NULL, DEST_LOCAL, NULL};
-Privacy sub_field_2{2, 9, NULL, DEST_AUTOMATIC, NULL};
+TestSection::TestSection(int id)
+        :Section(id, 5000 /* ms timeout */) {
+}
+
+TestSection::~TestSection() {
+}
+
+status_t TestSection::Execute(ReportWriter* writer) const {
+    uint8_t buf[1024];
+    status_t err;
+
+    TestSectionProto proto;
+    proto.set_field_1(this->id);
+    proto.set_field_2(this->id * 10);
+
+    // Not infinitely scalable, but we know that our TestSectionProto will always
+    // fit in this many bytes.
+    if (!proto.SerializeToArray(buf, sizeof(buf))) {
+        return -1;
+    }
+    FdBuffer buffer;
+    err = buffer.write(buf, proto.ByteSize());
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    return writer->writeSection(buffer);
+}
+
+TestSection section1(1);
+TestSection section2(2);
+
+const Section* SECTION_LIST[] = {
+    &section1,
+    &section2,
+    NULL
+};
+
+Privacy sub_field_1{1, 1, NULL, PRIVACY_POLICY_LOCAL, NULL};
+Privacy sub_field_2{2, 9, NULL, PRIVACY_POLICY_AUTOMATIC, NULL};
 
 Privacy* list[] = {&sub_field_1, &sub_field_2, NULL};
 
-Privacy field_0{0, 11, list, DEST_EXPLICIT, NULL};
-Privacy field_1{1, 9, NULL, DEST_AUTOMATIC, NULL};
+Privacy field_0{0, 11, list, PRIVACY_POLICY_EXPLICIT, NULL};
+Privacy field_1{1, 9, NULL, PRIVACY_POLICY_AUTOMATIC, NULL};
 
 Privacy* final_list[] = {&field_0, &field_1};
 
@@ -23,4 +69,4 @@
 
 }  // namespace incidentd
 }  // namespace os
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/cmds/statsd/src/logd/LogListener.cpp b/cmds/incidentd/tests/test_proto.proto
similarity index 70%
copy from cmds/statsd/src/logd/LogListener.cpp
copy to cmds/incidentd/tests/test_proto.proto
index ddb26f9..f57070b 100644
--- a/cmds/statsd/src/logd/LogListener.cpp
+++ b/cmds/incidentd/tests/test_proto.proto
@@ -14,18 +14,15 @@
  * limitations under the License.
  */
 
-#include "logd/LogListener.h"
+syntax = "proto2";
 
-namespace android {
-namespace os {
-namespace statsd {
+package android.os.incidentd;
 
-LogListener::LogListener() {
+message TestSectionProto {
+    // The id of the section, written by TestSection.
+    optional int32 field_1 = 1;
+
+    // The id of the section, times 10, written by TestSection.
+    optional int32 field_2 = 2;
 }
 
-LogListener::~LogListener() {
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/media/Android.bp b/cmds/media/Android.bp
new file mode 100644
index 0000000..7879c53
--- /dev/null
+++ b/cmds/media/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2013 The Android Open Source Project
+//
+
+java_binary {
+    name: "media",
+    wrapper: "media",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/media/Android.mk b/cmds/media/Android.mk
deleted file mode 100644
index b9451c5..0000000
--- a/cmds/media/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2013 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := media_cmd
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := media
-LOCAL_SRC_FILES := media
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/media/media b/cmds/media/media
index 5c0eb2f..8ada914 100755
--- a/cmds/media/media
+++ b/cmds/media/media
@@ -3,5 +3,5 @@
 # shell.
 #
 base=/system
-export CLASSPATH=$base/framework/media_cmd.jar
+export CLASSPATH=$base/framework/media.jar
 exec app_process $base/bin com.android.commands.media.Media "$@"
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 4a6f87f..6033655 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -103,8 +103,6 @@
             runSetVirtualDisk();
         } else if ("set-isolated-storage".equals(op)) {
             runIsolatedStorage();
-        } else if ("set-legacy-greylist".equals(op)) {
-            runLegacyGreylist();
         } else {
             throw new IllegalArgumentException();
         }
@@ -306,12 +304,6 @@
         mSm.setDebugFlags(value, mask);
     }
 
-    public void runLegacyGreylist() throws RemoteException {
-        final boolean legacyGreylist = Boolean.parseBoolean(nextArg());
-        mSm.setDebugFlags(legacyGreylist ? StorageManager.DEBUG_LEGACY_GREYLIST : 0,
-                StorageManager.DEBUG_LEGACY_GREYLIST);
-    }
-
     public void runIdleMaint() throws RemoteException {
         final boolean im_run = "run".equals(nextArg());
         if (im_run) {
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index ce07d6d..017cb6d 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -81,7 +81,7 @@
         "src/external/StatsPullerManager.cpp",
         "src/external/puller_util.cpp",
         "src/logd/LogEvent.cpp",
-        "src/logd/LogListener.cpp",
+        "src/logd/LogEventQueue.cpp",
         "src/matchers/CombinationLogMatchingTracker.cpp",
         "src/matchers/EventMatcherWizard.cpp",
         "src/matchers/matcher_util.cpp",
@@ -118,6 +118,7 @@
 
     static_libs: [
         "libhealthhalutils",
+        "libplatformprotos",
     ],
 
     shared_libs: [
@@ -225,6 +226,7 @@
         "tests/indexed_priority_queue_test.cpp",
         "tests/LogEntryMatcher_test.cpp",
         "tests/LogEvent_test.cpp",
+        "tests/log_event/LogEventQueue_test.cpp",
         "tests/MetricsManager_test.cpp",
         "tests/StatsLogProcessor_test.cpp",
         "tests/StatsService_test.cpp",
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index a6699e7..df84b6a 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -407,12 +407,12 @@
         outData->clear();
         outData->resize(proto.size());
         size_t pos = 0;
-        auto iter = proto.data();
-        while (iter.readBuffer() != NULL) {
-            size_t toRead = iter.currentToRead();
-            std::memcpy(&((*outData)[pos]), iter.readBuffer(), toRead);
+        sp<android::util::ProtoReader> reader = proto.data();
+        while (reader->readBuffer() != NULL) {
+            size_t toRead = reader->currentToRead();
+            std::memcpy(&((*outData)[pos]), reader->readBuffer(), toRead);
             pos += toRead;
-            iter.rp()->move(toRead);
+            reader->move(toRead);
         }
     }
 
@@ -602,6 +602,19 @@
 
 void StatsLogProcessor::WriteMetricsActivationToDisk(int64_t currentTimeNs) {
     std::lock_guard<std::mutex> lock(mMetricsMutex);
+
+    const int64_t timeNs = getElapsedRealtimeNs();
+    // Do not write to disk if we already have in the last few seconds.
+    // This is to avoid overwriting files that would have the same name if we
+    //   write twice in the same second.
+    if (static_cast<unsigned long long> (timeNs) <
+            mLastActiveMetricsWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
+        ALOGI("Statsd skipping writing active metrics to disk. Already wrote data in last %d seconds",
+                WRITE_DATA_COOL_DOWN_SEC);
+        return;
+    }
+    mLastActiveMetricsWriteNs = timeNs;
+
     ProtoOutputStream proto;
 
     for (const auto& pair : mMetricsManagers) {
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index e92b897..305a4ce 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -66,7 +66,7 @@
 
     void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
                       const bool include_current_partial_bucket, const bool erase_data,
-                      const DumpReportReason dumpReportReason, 
+                      const DumpReportReason dumpReportReason,
                       const DumpLatency dumpLatency,
                       vector<uint8_t>* outData);
     void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
@@ -207,6 +207,9 @@
     // Last time we wrote data to disk.
     int64_t mLastWriteTimeNs = 0;
 
+    // Last time we wrote active metrics to disk.
+    int64_t mLastActiveMetricsWriteNs = 0;
+
 #ifdef VERY_VERBOSE_PRINTING
     bool mPrintAllLogs = false;
 #endif
@@ -257,6 +260,9 @@
     FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
     FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index f78ae38..1433252 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -50,6 +50,7 @@
 using android::util::FIELD_COUNT_REPEATED;
 using android::util::FIELD_TYPE_INT64;
 using android::util::FIELD_TYPE_MESSAGE;
+using android::util::ProtoReader;
 
 namespace android {
 namespace os {
@@ -64,8 +65,6 @@
 
 // for StatsDataDumpProto
 const int FIELD_ID_REPORTS_LIST = 1;
-// for TrainInfo experiment id serialization
-const int FIELD_ID_EXPERIMENT_ID = 1;
 
 static binder::Status ok() {
     return binder::Status::ok();
@@ -131,34 +130,36 @@
     }                                                             \
 }
 
-StatsService::StatsService(const sp<Looper>& handlerLooper)
-    : mAnomalyAlarmMonitor(new AlarmMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
-       [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
-           if (sc != nullptr) {
-               sc->setAnomalyAlarm(timeMillis);
-               StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
-           }
-       },
-       [](const sp<IStatsCompanionService>& sc) {
-           if (sc != nullptr) {
-               sc->cancelAnomalyAlarm();
-               StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
-           }
-       })),
-   mPeriodicAlarmMonitor(new AlarmMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
-      [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
-           if (sc != nullptr) {
-               sc->setAlarmForSubscriberTriggering(timeMillis);
-               StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
-           }
-      },
-      [](const sp<IStatsCompanionService>& sc) {
-           if (sc != nullptr) {
-               sc->cancelAlarmForSubscriberTriggering();
-               StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
-           }
-
-      }))  {
+StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue)
+    : mAnomalyAlarmMonitor(new AlarmMonitor(
+              MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
+              [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
+                  if (sc != nullptr) {
+                      sc->setAnomalyAlarm(timeMillis);
+                      StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
+                  }
+              },
+              [](const sp<IStatsCompanionService>& sc) {
+                  if (sc != nullptr) {
+                      sc->cancelAnomalyAlarm();
+                      StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged();
+                  }
+              })),
+      mPeriodicAlarmMonitor(new AlarmMonitor(
+              MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
+              [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
+                  if (sc != nullptr) {
+                      sc->setAlarmForSubscriberTriggering(timeMillis);
+                      StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
+                  }
+              },
+              [](const sp<IStatsCompanionService>& sc) {
+                  if (sc != nullptr) {
+                      sc->cancelAlarmForSubscriberTriggering();
+                      StatsdStats::getInstance().noteRegisteredPeriodicAlarmChanged();
+                  }
+              })),
+      mEventQueue(queue) {
     mUidMap = UidMap::getInstance();
     mPullerManager = new StatsPullerManager();
     StatsPuller::SetUidMap(mUidMap);
@@ -200,11 +201,33 @@
     mConfigManager->AddListener(mProcessor);
 
     init_system_properties();
+
+    if (mEventQueue != nullptr) {
+        std::thread pushedEventThread([this] { readLogs(); });
+        pushedEventThread.detach();
+    }
 }
 
 StatsService::~StatsService() {
 }
 
+/* Runs on a dedicated thread to process pushed events. */
+void StatsService::readLogs() {
+    // Read forever..... long live statsd
+    while (1) {
+        // Block until an event is available.
+        auto event = mEventQueue->waitPop();
+        // Pass it to StatsLogProcess to all configs/metrics
+        // At this point, the LogEventQueue is not blocked, so that the socketListener
+        // can read events from the socket and write to buffer to avoid data drop.
+        mProcessor->OnLogEvent(event.get());
+        // The ShellSubscriber is only used by shell for local debugging.
+        if (mShellSubscriber != nullptr) {
+            mShellSubscriber->onLogEvent(*event);
+        }
+    }
+}
+
 void StatsService::init_system_properties() {
     mEngBuild = false;
     const prop_info* buildType = __system_property_find("ro.build.type");
@@ -1005,9 +1028,11 @@
     ALOGI("StatsService::Terminating");
     if (mProcessor != nullptr) {
         mProcessor->WriteDataToDisk(TERMINATION_SIGNAL_RECEIVED, FAST);
+        mProcessor->WriteMetricsActivationToDisk(getElapsedRealtimeNs());
     }
 }
 
+// Test only interface!!!
 void StatsService::OnLogEvent(LogEvent* event) {
     mProcessor->OnLogEvent(event);
     if (mShellSubscriber != nullptr) {
@@ -1180,7 +1205,7 @@
 Status StatsService::sendBinaryPushStateChangedAtom(const android::String16& trainName,
                                                     int64_t trainVersionCode, int options,
                                                     int32_t state,
-                                                    const std::vector<int64_t>& experimentIds) {
+                                                    const std::vector<int64_t>& experimentIdsIn) {
     uid_t uid = IPCThreadState::self()->getCallingUid();
     // For testing
     if (uid == AID_ROOT || uid == AID_SYSTEM || uid == AID_SHELL) {
@@ -1200,7 +1225,7 @@
 
     bool readTrainInfoSuccess = false;
     InstallTrainInfo trainInfo;
-    if (trainVersionCode == -1 || experimentIds.empty() || trainName.size() == 0) {
+    if (trainVersionCode == -1 || experimentIdsIn.empty() || trainName.size() == 0) {
         readTrainInfoSuccess = StorageManager::readTrainInfo(trainInfo);
     }
 
@@ -1208,27 +1233,19 @@
         trainVersionCode = trainInfo.trainVersionCode;
     }
 
-    vector<uint8_t> experimentIdsProtoBuffer;
-    if (readTrainInfoSuccess && experimentIds.empty()) {
-        experimentIdsProtoBuffer = trainInfo.experimentIds;
+    // Find the right experiment IDs
+    std::vector<int64_t> experimentIds;
+    if (readTrainInfoSuccess && experimentIdsIn.empty()) {
+        experimentIds = trainInfo.experimentIds;
     } else {
-        ProtoOutputStream proto;
-        for (const auto& expId : experimentIds) {
-            proto.write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_EXPERIMENT_ID,
-                        (long long)expId);
-        }
-
-        experimentIdsProtoBuffer.resize(proto.size());
-        size_t pos = 0;
-        auto iter = proto.data();
-        while (iter.readBuffer() != NULL) {
-            size_t toRead = iter.currentToRead();
-            std::memcpy(&(experimentIdsProtoBuffer[pos]), iter.readBuffer(), toRead);
-            pos += toRead;
-            iter.rp()->move(toRead);
-        }
+        experimentIds = experimentIdsIn;
     }
 
+    // Flatten the experiment IDs to proto
+    vector<uint8_t> experimentIdsProtoBuffer;
+    writeExperimentIdsToProto(experimentIds, &experimentIdsProtoBuffer);
+
+    // Find the right train name
     std::string trainNameUtf8;
     if (readTrainInfoSuccess && trainName.size() == 0) {
         trainNameUtf8 = trainInfo.trainName;
@@ -1243,7 +1260,34 @@
     LogEvent event(trainNameUtf8, trainVersionCode, requiresStaging, rollbackEnabled,
                    requiresLowLatencyMonitor, state, experimentIdsProtoBuffer, userId);
     mProcessor->OnLogEvent(&event);
-    StorageManager::writeTrainInfo(trainVersionCode, trainNameUtf8, state, experimentIdsProtoBuffer);
+    StorageManager::writeTrainInfo(trainVersionCode, trainNameUtf8, state, experimentIds);
+    return Status::ok();
+}
+
+Status StatsService::getRegisteredExperimentIds(std::vector<int64_t>* experimentIdsOut) {
+    uid_t uid = IPCThreadState::self()->getCallingUid();
+
+    // Caller must be granted these permissions
+    if (!checkCallingPermission(String16(kPermissionDump))) {
+        return exception(binder::Status::EX_SECURITY,
+                         StringPrintf("UID %d lacks permission %s", uid, kPermissionDump));
+    }
+    if (!checkCallingPermission(String16(kPermissionUsage))) {
+        return exception(binder::Status::EX_SECURITY,
+                         StringPrintf("UID %d lacks permission %s", uid, kPermissionUsage));
+    }
+    // TODO: add verifier permission
+
+    // Read the latest train info
+    InstallTrainInfo trainInfo;
+    if (!StorageManager::readTrainInfo(trainInfo)) {
+        // No train info means no experiment IDs, return an empty list
+        experimentIdsOut->clear();
+        return Status::ok();
+    }
+
+    // Copy the experiment IDs to the out vector
+    experimentIdsOut->assign(trainInfo.experimentIds.begin(), trainInfo.experimentIds.end());
     return Status::ok();
 }
 
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index d24565a..929d260 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -22,7 +22,7 @@
 #include "anomaly/AlarmMonitor.h"
 #include "config/ConfigManager.h"
 #include "external/StatsPullerManager.h"
-#include "logd/LogListener.h"
+#include "logd/LogEventQueue.h"
 #include "packages/UidMap.h"
 #include "shell/ShellSubscriber.h"
 #include "statscompanion_util.h"
@@ -52,11 +52,10 @@
 using android::hardware::Return;
 
 class StatsService : public BnStatsManager,
-                     public LogListener,
                      public IStats,
                      public IBinder::DeathRecipient {
 public:
-    StatsService(const sp<Looper>& handlerLooper);
+    StatsService(const sp<Looper>& handlerLooper, std::shared_ptr<LogEventQueue> queue);
     virtual ~StatsService();
 
     /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */
@@ -92,7 +91,7 @@
     void Terminate();
 
     /**
-     * Called by LogReader when there's a log event to process.
+     * Test ONLY interface. In real world, StatsService reads from LogEventQueue.
      */
     virtual void OnLogEvent(LogEvent* event);
 
@@ -194,6 +193,11 @@
             int32_t state, const std::vector<int64_t>& experimentIds) override;
 
     /**
+     * Binder call to get registered experiment IDs.
+     */
+    virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut);
+
+    /**
      * Binder call to get SpeakerImpedance atom.
      */
     virtual Return<void> reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) override;
@@ -278,6 +282,9 @@
      */
     void print_cmd_help(int out);
 
+    /* Runs on its dedicated thread to process pushed stats event from socket. */
+    void readLogs();
+
     /**
      * Trigger a broadcast.
      */
@@ -410,6 +417,8 @@
 
     sp<ShellSubscriber> mShellSubscriber;
 
+    std::shared_ptr<LogEventQueue> mEventQueue;
+
     FRIEND_TEST(StatsServiceTest, TestAddConfig_simple);
     FRIEND_TEST(StatsServiceTest, TestAddConfig_empty);
     FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid);
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index c2b81e4..dc4413f 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -41,6 +41,7 @@
 import "frameworks/base/core/proto/android/service/procstats_enum.proto";
 import "frameworks/base/core/proto/android/service/usb.proto";
 import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto";
+import "frameworks/base/core/proto/android/stats/connectivity/resolv_stats.proto";
 import "frameworks/base/core/proto/android/stats/enums.proto";
 import "frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto";
 import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto";
@@ -187,7 +188,7 @@
         WifiEnabledStateChanged wifi_enabled_state_changed = 113;
         WifiRunningStateChanged wifi_running_state_changed = 114;
         AppCompacted app_compacted = 115;
-        NetworkDnsEventReported network_dns_event_reported = 116;
+        NetworkDnsEventReported network_dns_event_reported = 116 [(log_from_module) = "resolv"];
         DocsUIPickerLaunchedFromReported docs_ui_picker_launched_from_reported = 117;
         DocsUIPickResultReported docs_ui_pick_result_reported = 118;
         DocsUISearchModeReported docs_ui_search_mode_reported = 119;
@@ -254,10 +255,15 @@
         PrivacyIndicatorsInteracted privacy_indicators_interacted = 180;
         AppInstallOnExternalStorageReported app_install_on_external_storage_reported = 181;
         NetworkStackReported network_stack_reported = 182;
+        AppMovedStorageReported app_moved_storage_reported = 183;
+        BiometricEnrolled biometric_enrolled = 184;
+        SystemServerWatchdogOccurred system_server_watchdog_occurred = 185;
+        TombStoneOccurred tomb_stone_occurred = 186;
+        BluetoothClassOfDeviceReported bluetooth_class_of_device_reported = 187;
     }
 
     // Pulled events will start at field 10000.
-    // Next: 10057
+    // Next: 10058
     oneof pulled {
         WifiBytesTransfer wifi_bytes_transfer = 10000;
         WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -316,6 +322,7 @@
         GpuStatsGlobalInfo gpu_stats_global_info = 10054;
         GpuStatsAppInfo gpu_stats_app_info = 10055;
         SystemIonHeapSize system_ion_heap_size = 10056;
+        AppsOnExternalStorageInfo apps_on_external_storage_info = 10057;
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP.
@@ -2136,6 +2143,29 @@
 }
 
 /**
+ * Logs when Class of Device (CoD) value is learnt for a device during pairing or connection
+ *
+ * Logged from:
+ *   packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
+ *   packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.java
+ *
+ */
+message BluetoothClassOfDeviceReported {
+    // An identifier that can be used to match events for this device.
+    // Currently, this is a salted hash of the MAC address of this Bluetooth device.
+    // Salt: Randomly generated 256 bit value
+    // Hash algorithm: HMAC-SHA256
+    // Size: 32 byte
+    // Default: null or empty if this is a server listener socket
+    optional bytes obfuscated_id = 1 [(android.os.statsd.log_mode) = MODE_BYTES];
+    // Class of Device (CoD) value including both Major, Minor device class and service class
+    // Defined in: https://www.bluetooth.com/specifications/assigned-numbers/baseband
+    // Also defined in: https://developer.android.com/reference/android/bluetooth/BluetoothClass
+    // Default: 0
+    optional int32 class_of_device = 2;
+}
+
+/**
  * Logs when something is plugged into or removed from the USB-C connector.
  *
  * Logged from:
@@ -3152,6 +3182,23 @@
     optional android.hardware.biometrics.IssueEnum issue = 2;
 }
 
+/**
+ * Logs when a biometric enrollment occurs.
+ *
+ * Logged from:
+ *   frameworks/base/services/core/java/com/android/server/biometrics
+ */
+message BiometricEnrolled {
+    // Biometric modality that was used.
+    optional android.hardware.biometrics.ModalityEnum modality = 1;
+    // The associated user. Eg: 0 for owners, 10+ for others. Defined in android/os/UserHandle.java
+    optional int32 user = 2;
+    // The amount of time the enrollment took in milliseconds.
+    optional int64 latency_millis = 3;
+    // Whether or not the enrollment was successful.
+    optional bool success = 4;
+}
+
 message Notification {
 
     // Type of notification event.
@@ -3278,6 +3325,9 @@
         INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_INITIATED = 18;
         INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_SUCCESS = 19;
         INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_FAILURE = 20;
+        INSTALL_STAGED_CANCEL_REQUESTED = 21;
+        INSTALL_STAGED_CANCEL_SUCCESS = 22;
+        INSTALL_STAGED_CANCEL_FAILURE = 23;
     }
     optional State state = 6;
     // Possible experiment ids for monitoring this push.
@@ -3445,6 +3495,47 @@
     optional string package_name = 2;
 }
 
+/**
+ * Logs information about a package that is moved from the internal to external storage and vice
+ * versa.
+ * It logs the package name, the type of the external storage where the package is installed
+ * (if moved to external storage, or UNKNOWN if moved to internal storage),
+ * and the move type: if it's from internal to external or the other way around.
+ *
+ * Logged from:
+        frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
+ */
+message AppMovedStorageReported {
+    enum MoveType {
+        UNKNOWN = 0;
+        TO_EXTERNAL = 1;
+        TO_INTERNAL = 2;
+    }
+    // The type of the external storage.
+    optional android.stats.storage.ExternalStorageType external_storage_type = 1;
+    // The type of move.
+    optional MoveType move_type = 2;
+    // The name of the package that was moved.
+    optional string package_name = 3;
+}
+
+/**
+ * Logs when system server watchdog occurs.
+ * Logged from:
+ *      frameworks/base/services/core/java/com/android/server/Watchdog.java
+ */
+message SystemServerWatchdogOccurred {
+    optional string subject = 1;
+}
+
+/**
+ * Logs when new file added to tombstones.
+ * Logged from:
+ *      frameworks/base/core/java/com/android/server/BootReceiver.java
+ */
+message TombStoneOccurred {
+}
+
 //////////////////////////////////////////////////////////////////////
 // Pulled atoms below this line //
 //////////////////////////////////////////////////////////////////////
@@ -4949,53 +5040,39 @@
 }
 
 /**
- * Logs the latency period(in microseconds) and the return code of
- * the DNS(Domain Name System) lookups.
- * These 4 methods(GETADDRINFO,GETHOSTBYNAME,GETHOSTBYADDR,RES_NSEND)
- * to get info(address or hostname) from DNS server(or DNS cache).
- * Logged from:
- *   /system/netd/server/DnsProxyListener.cpp
+ * Logs a DNS lookup operation initiated by the system resolver on behalf of an application
+ * invoking native APIs such as getaddrinfo() or Java APIs such as Network#getAllByName().
+ *
+ * The top-level message represents the entire lookup operation, which may result one or more
+ * queries to the recursive DNS resolvers. Those are individually logged in DnsQueryEvent to
+ * enable computing error rates and network latency and timeouts broken up by query type,
+ * transport, network interface, etc.
  */
 message NetworkDnsEventReported {
-    // The types of the DNS lookups, as defined in
-    //system/netd/server/binder/android/net/metrics/INetdEventListener.aidl
-    enum EventType {
-        EVENT_UNKNOWN = 0;
-        EVENT_GETADDRINFO = 1;
-        EVENT_GETHOSTBYNAME = 2;
-        EVENT_GETHOSTBYADDR = 3;
-        EVENT_RES_NSEND = 4;
-    }
-    optional EventType event_type = 1;
 
-    // The return value of the DNS resolver for each DNS lookups.
-    //bionic/libc/include/netdb.h
-    //system/netd/resolv/include/netd_resolv/resolv.h
-    enum ReturnCode {
-        EAI_NO_ERROR = 0;
-        EAI_ADDRFAMILY = 1;
-        EAI_AGAIN = 2;
-        EAI_BADFLAGS = 3;
-        EAI_FAIL = 4;
-        EAI_FAMILY = 5;
-        EAI_MEMORY = 6;
-        EAI_NODATA = 7;
-        EAI_NONAME = 8;
-        EAI_SERVICE = 9;
-        EAI_SOCKTYPE = 10;
-        EAI_SYSTEM = 11;
-        EAI_BADHINTS = 12;
-        EAI_PROTOCOL = 13;
-        EAI_OVERFLOW = 14;
-        RESOLV_TIMEOUT = 255;
-        EAI_MAX = 256;
-    }
-    optional ReturnCode return_code = 2;
+    optional android.stats.connectivity.EventType event_type = 1;
 
-    // The latency period(in microseconds) it took for this DNS lookup to complete.
+    optional android.stats.connectivity.ReturnCode return_code = 2;
+
+    // The latency in microseconds of the entire DNS lookup operation.
     optional int32 latency_micros = 3;
+
+    optional android.stats.connectivity.DnsQueryEventRe dns_query_event_re = 4 [(log_mode) = MODE_BYTES];
+
+    // ResNSend flags defined in android/multinetwork.h
+    optional int32 flags = 5;
+
+    optional android.net.NetworkCapabilitiesProto.Transport network_type = 6;
+
+    // The DNS over TLS mode on a specific netId.
+    optional android.stats.connectivity.PrivateDnsModes private_dns_modes = 7;
+
+    // Additional pass-through fields opaque to statsd.
+    // The DNS resolver Mainline module can add new fields here without requiring an OS update.
+    optional android.stats.connectivity.DnsCallEvent dns_call_event = 8 [(log_mode) = MODE_BYTES];
 }
 
+
 /**
  * Logs when a data stall event occurs.
  *
@@ -5556,6 +5633,9 @@
     // Normalized screen position of the bubble stack. The range is between 0 and 1.
     optional float normalized_x_position = 7;
     optional float normalized_y_position = 8;
+
+    // Whether the bubble is unread. If it is unread, a dot is shown in the bubble stack icon.
+    optional bool is_unread = 9;
 }
 
 /**
@@ -5738,6 +5818,9 @@
         INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_INITIATED = 18;
         INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_SUCCESS = 19;
         INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_FAILURE = 20;
+        INSTALL_STAGED_CANCEL_REQUESTED = 21;
+        INSTALL_STAGED_CANCEL_SUCCESS = 22;
+        INSTALL_STAGED_CANCEL_FAILURE = 23;
     }
     optional Status status = 4;
 }
@@ -5863,6 +5946,20 @@
  *     frameworks/base/packages/NetworkStack/
  */
 message NetworkStackReported {
-    optional int32 eventId = 1;
+    // The id that indicates the event reported from NetworkStack.
+    optional int32 event_id = 1;
+    // The data for the reported events.
     optional android.stats.connectivity.NetworkStackEventData network_stack_event = 2 [(log_mode) = MODE_BYTES];
 }
+
+/**
+ * Logs the apps that are installed on the external storage.
+ * Pulled from:
+ *   StatsCompanionService
+ */
+message AppsOnExternalStorageInfo {
+    // The type of the external storage.
+    optional android.stats.storage.ExternalStorageType external_storage_type = 1;
+    // The name of the package that is installed on the external storage.
+    optional string package_name = 2;
+}
diff --git a/cmds/statsd/src/external/GpuStatsPuller.cpp b/cmds/statsd/src/external/GpuStatsPuller.cpp
index 130bd85..3fa932f 100644
--- a/cmds/statsd/src/external/GpuStatsPuller.cpp
+++ b/cmds/statsd/src/external/GpuStatsPuller.cpp
@@ -29,6 +29,8 @@
 namespace os {
 namespace statsd {
 
+using android::util::ProtoReader;
+
 GpuStatsPuller::GpuStatsPuller(const int tagId) : StatsPuller(tagId) {
 }
 
@@ -116,11 +118,11 @@
     if (!proto.size()) return "";
 
     std::string byteString;
-    auto iter = proto.data();
-    while (iter.readBuffer() != nullptr) {
-        const size_t toRead = iter.currentToRead();
-        byteString.append((char*)iter.readBuffer(), toRead);
-        iter.rp()->move(toRead);
+    sp<ProtoReader> reader = proto.data();
+    while (reader->readBuffer() != nullptr) {
+        const size_t toRead = reader->currentToRead();
+        byteString.append((char*)reader->readBuffer(), toRead);
+        reader->move(toRead);
     }
 
     if (byteString.size() != proto.size()) return "";
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 2abfc24..13eee5d 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -251,6 +251,9 @@
         // GpuStatsAppInfo
         {android::util::GPU_STATS_APP_INFO,
          {.puller = new GpuStatsPuller(android::util::GPU_STATS_APP_INFO)}},
+        // AppsOnExternalStorageInfo
+        {android::util::APPS_ON_EXTERNAL_STORAGE_INFO,
+         {.puller = new StatsCompanionServicePuller(android::util::APPS_ON_EXTERNAL_STORAGE_INFO)}},
 };
 
 StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 9a00637..74a4c87 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -50,6 +50,7 @@
 const int FIELD_ID_PERIODIC_ALARM_STATS = 12;
 const int FIELD_ID_SYSTEM_SERVER_RESTART = 15;
 const int FIELD_ID_LOGGER_ERROR_STATS = 16;
+const int FIELD_ID_OVERFLOW = 18;
 
 const int FIELD_ID_ATOM_STATS_TAG = 1;
 const int FIELD_ID_ATOM_STATS_COUNT = 2;
@@ -60,6 +61,13 @@
 const int FIELD_ID_LOG_LOSS_STATS_TIME = 1;
 const int FIELD_ID_LOG_LOSS_STATS_COUNT = 2;
 const int FIELD_ID_LOG_LOSS_STATS_ERROR = 3;
+const int FIELD_ID_LOG_LOSS_STATS_TAG = 4;
+const int FIELD_ID_LOG_LOSS_STATS_UID = 5;
+const int FIELD_ID_LOG_LOSS_STATS_PID = 6;
+
+const int FIELD_ID_OVERFLOW_COUNT = 1;
+const int FIELD_ID_OVERFLOW_MAX_HISTORY = 2;
+const int FIELD_ID_OVERFLOW_MIN_HISTORY = 3;
 
 const int FIELD_ID_CONFIG_STATS_UID = 1;
 const int FIELD_ID_CONFIG_STATS_ID = 2;
@@ -183,12 +191,13 @@
     noteConfigResetInternalLocked(key);
 }
 
-void StatsdStats::noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError) {
+void StatsdStats::noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
+                              int32_t lastTag, int32_t uid, int32_t pid) {
     lock_guard<std::mutex> lock(mLock);
     if (mLogLossStats.size() == kMaxLoggerErrors) {
         mLogLossStats.pop_front();
     }
-    mLogLossStats.emplace_back(wallClockTimeSec, count, lastError);
+    mLogLossStats.emplace_back(wallClockTimeSec, count, lastError, lastTag, uid, pid);
 }
 
 void StatsdStats::noteBroadcastSent(const ConfigKey& key) {
@@ -231,6 +240,22 @@
     noteDataDropped(key, totalBytes, getWallClockSec());
 }
 
+void StatsdStats::noteEventQueueOverflow(int64_t oldestEventTimestampNs) {
+    lock_guard<std::mutex> lock(mLock);
+
+    mOverflowCount++;
+
+    int64_t history = getElapsedRealtimeNs() - oldestEventTimestampNs;
+
+    if (history > mMaxQueueHistoryNs) {
+        mMaxQueueHistoryNs = history;
+    }
+
+    if (history < mMinQueueHistoryNs) {
+        mMinQueueHistoryNs = history;
+    }
+}
+
 void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec) {
     lock_guard<std::mutex> lock(mLock);
     auto it = mConfigStats.find(key);
@@ -530,6 +555,9 @@
     mPeriodicAlarmRegisteredStats = 0;
     mSystemServerRestartSec.clear();
     mLogLossStats.clear();
+    mOverflowCount = 0;
+    mMinQueueHistoryNs = kInt64Max;
+    mMaxQueueHistoryNs = 0;
     for (auto& config : mConfigStats) {
         config.second->broadcast_sent_time_sec.clear();
         config.second->activation_time_sec.clear();
@@ -716,9 +744,15 @@
     }
 
     for (const auto& loss : mLogLossStats) {
-        dprintf(out, "Log loss: %lld (wall clock sec) - %d (count) %d (last error)\n",
-                (long long)loss.mWallClockSec, loss.mCount, loss.mLastError);
+        dprintf(out,
+                "Log loss: %lld (wall clock sec) - %d (count), %d (last error), %d (last tag), %d "
+                "(uid), %d (pid)\n",
+                (long long)loss.mWallClockSec, loss.mCount, loss.mLastError, loss.mLastTag,
+                loss.mUid, loss.mPid);
     }
+
+    dprintf(out, "Event queue overflow: %d; MaxHistoryNs: %lld; MinHistoryNs: %lld\n",
+            mOverflowCount, (long long)mMaxQueueHistoryNs, (long long)mMinQueueHistoryNs);
 }
 
 void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* proto) {
@@ -891,6 +925,19 @@
         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TIME, error.mWallClockSec);
         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_COUNT, error.mCount);
         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_ERROR, error.mLastError);
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TAG, error.mLastTag);
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_UID, error.mUid);
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_PID, error.mPid);
+        proto.end(token);
+    }
+
+    if (mOverflowCount > 0) {
+        uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_OVERFLOW);
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_OVERFLOW_COUNT, (int32_t)mOverflowCount);
+        proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MAX_HISTORY,
+                    (long long)mMaxQueueHistoryNs);
+        proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MIN_HISTORY,
+                    (long long)mMinQueueHistoryNs);
         proto.end(token);
     }
 
@@ -904,12 +951,12 @@
     output->resize(bufferSize);
 
     size_t pos = 0;
-    auto it = proto.data();
-    while (it.readBuffer() != NULL) {
-        size_t toRead = it.currentToRead();
-        std::memcpy(&((*output)[pos]), it.readBuffer(), toRead);
+    sp<android::util::ProtoReader> reader = proto.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&((*output)[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        it.rp()->move(toRead);
+        reader->move(toRead);
     }
 
     if (reset) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 7c2d846..88ecccc 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -160,6 +160,8 @@
     // Max platform atom tag number.
     static const int32_t kMaxPlatformAtomTag = 100000;
 
+    static const int64_t kInt64Max = 0x7fffffffffffffffLL;
+
     /**
      * Report a new config has been received and report the static stats about the config.
      *
@@ -336,7 +338,8 @@
     /**
      * Records statsd skipped an event.
      */
-    void noteLogLost(int32_t wallClockTimeSec, int32_t count, int lastError);
+    void noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
+                     int32_t lastAtomTag, int32_t uid, int32_t pid);
 
     /**
      * Records that the pull of an atom has failed
@@ -418,6 +421,10 @@
      */
     void noteBucketUnknownCondition(int64_t metricId);
 
+    /* Reports one event has been dropped due to queue overflow, and the oldest event timestamp in
+     * the queue */
+    void noteEventQueueOverflow(int64_t oldestEventTimestampNs);
+
     /**
      * Reset the historical stats. Including all stats in icebox, and the tracked stats about
      * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
@@ -503,15 +510,35 @@
     std::map<int64_t, AtomMetricStats> mAtomMetricStats;
 
     struct LogLossStats {
-        LogLossStats(int32_t sec, int32_t count, int32_t error)
-            : mWallClockSec(sec), mCount(count), mLastError(error) {
+        LogLossStats(int32_t sec, int32_t count, int32_t error, int32_t tag, int32_t uid,
+                     int32_t pid)
+            : mWallClockSec(sec),
+              mCount(count),
+              mLastError(error),
+              mLastTag(tag),
+              mUid(uid),
+              mPid(pid) {
         }
         int32_t mWallClockSec;
         int32_t mCount;
         // error code defined in linux/errno.h
         int32_t mLastError;
+        int32_t mLastTag;
+        int32_t mUid;
+        int32_t mPid;
     };
 
+    // Max of {(now - oldestEventTimestamp) when overflow happens}.
+    // This number is helpful to understand how SLOW statsd can be.
+    int64_t mMaxQueueHistoryNs = 0;
+
+    // Min of {(now - oldestEventTimestamp) when overflow happens}.
+    // This number is helpful to understand how FAST the events floods to statsd.
+    int64_t mMinQueueHistoryNs = kInt64Max;
+
+    // Total number of events that are lost due to queue overflow.
+    int32_t mOverflowCount = 0;
+
     // Timestamps when we detect log loss, and the number of logs lost.
     std::list<LogLossStats> mLogLossStats;
 
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index d9f5415..ca874b5 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -27,6 +27,9 @@
 namespace os {
 namespace statsd {
 
+// for TrainInfo experiment id serialization
+const int FIELD_ID_EXPERIMENT_ID = 1;
+
 using namespace android::util;
 using android::util::ProtoOutputStream;
 using std::string;
@@ -118,6 +121,7 @@
 
 LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs) {
     mLogdTimestampNs = wallClockTimestampNs;
+    mElapsedTimestampNs = elapsedTimestampNs;
     mTagId = tagId;
     mLogUid = 0;
     mContext = create_android_logger(1937006964); // the event tag shared by all stats logs
@@ -241,12 +245,15 @@
 
     mValues.push_back(
             FieldValue(Field(mTagId, getSimpleField(1)), Value(trainInfo.trainVersionCode)));
-    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainInfo.experimentIds)));
+    std::vector<uint8_t> experimentIdsProto;
+    writeExperimentIdsToProto(trainInfo.experimentIds, &experimentIdsProto);
+    mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(experimentIdsProto)));
     mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value(trainInfo.trainName)));
     mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value(trainInfo.status)));
 }
 
-LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, 0) {}
+LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, timestampNs) {
+}
 
 LogEvent::LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid) {
     mLogdTimestampNs = timestampNs;
@@ -671,6 +678,24 @@
     writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
 }
 
+void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut) {
+    ProtoOutputStream proto;
+    for (const auto& expId : experimentIds) {
+        proto.write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_EXPERIMENT_ID,
+                    (long long)expId);
+    }
+
+    protoOut->resize(proto.size());
+    size_t pos = 0;
+    sp<ProtoReader> reader = proto.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(protoOut->data() + pos, reader->readBuffer(), toRead);
+        pos += toRead;
+        reader->move(toRead);
+    }
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 753a9a5..531ce29 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -60,8 +60,9 @@
     int64_t trainVersionCode;
     std::string trainName;
     int32_t status;
-    std::vector<uint8_t> experimentIds;
+    std::vector<int64_t> experimentIds;
 };
+
 /**
  * Wrapper for the log_msg structure.
  */
@@ -239,6 +240,8 @@
     uint32_t mLogUid;
 };
 
+void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut);
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/src/logd/LogEventQueue.cpp b/cmds/statsd/src/logd/LogEventQueue.cpp
new file mode 100644
index 0000000..146464b
--- /dev/null
+++ b/cmds/statsd/src/logd/LogEventQueue.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define DEBUG false  // STOPSHIP if true
+#include "Log.h"
+
+#include "LogEventQueue.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+using std::unique_lock;
+using std::unique_ptr;
+
+unique_ptr<LogEvent> LogEventQueue::waitPop() {
+    std::unique_lock<std::mutex> lock(mMutex);
+
+    if (mQueue.empty()) {
+        mCondition.wait(lock, [this] { return !this->mQueue.empty(); });
+    }
+
+    unique_ptr<LogEvent> item = std::move(mQueue.front());
+    mQueue.pop();
+
+    return item;
+}
+
+bool LogEventQueue::push(unique_ptr<LogEvent> item, int64_t* oldestTimestampNs) {
+    bool success;
+    {
+        std::unique_lock<std::mutex> lock(mMutex);
+        if (mQueue.size() < mQueueLimit) {
+            mQueue.push(std::move(item));
+            success = true;
+        } else {
+            // safe operation as queue must not be empty.
+            *oldestTimestampNs = mQueue.front()->GetElapsedTimestampNs();
+            success = false;
+        }
+    }
+
+    mCondition.notify_one();
+    return success;
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/logd/LogEventQueue.h b/cmds/statsd/src/logd/LogEventQueue.h
new file mode 100644
index 0000000..b4fd63f
--- /dev/null
+++ b/cmds/statsd/src/logd/LogEventQueue.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "LogEvent.h"
+
+#include <condition_variable>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <thread>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/**
+ * A zero copy thread safe queue buffer for producing and consuming LogEvent.
+ */
+class LogEventQueue {
+public:
+    explicit LogEventQueue(size_t maxSize) : mQueueLimit(maxSize){};
+
+    /**
+     * Blocking read one event from the queue.
+     */
+    std::unique_ptr<LogEvent> waitPop();
+
+    /**
+     * Puts a LogEvent ptr to the end of the queue.
+     * Returns false on failure when the queue is full, and output the oldest event timestamp
+     * in the queue.
+     */
+    bool push(std::unique_ptr<LogEvent> event, int64_t* oldestTimestampNs);
+
+private:
+    const size_t mQueueLimit;
+    std::condition_variable mCondition;
+    std::mutex mMutex;
+    std::queue<std::unique_ptr<LogEvent>> mQueue;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/logd/LogListener.h b/cmds/statsd/src/logd/LogListener.h
deleted file mode 100644
index d8b06e9..0000000
--- a/cmds/statsd/src/logd/LogListener.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "logd/LogEvent.h"
-
-#include <utils/RefBase.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Callback for LogReader
- */
-class LogListener : public virtual android::RefBase {
-public:
-    LogListener();
-    virtual ~LogListener();
-
-    virtual void OnLogEvent(LogEvent* msg) = 0;
-};
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index eddc86e..68082c2 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -80,8 +80,11 @@
 
     ::android::hardware::configureRpcThreadpool(1 /*threads*/, false /*willJoin*/);
 
+    std::shared_ptr<LogEventQueue> eventQueue =
+            std::make_shared<LogEventQueue>(2000 /*buffer limit. Buffer is NOT pre-allocated*/);
+
     // Create the service
-    gStatsService = new StatsService(looper);
+    gStatsService = new StatsService(looper, eventQueue);
     if (defaultServiceManager()->addService(String16("stats"), gStatsService, false,
                 IServiceManager::DUMP_FLAG_PRIORITY_NORMAL | IServiceManager::DUMP_FLAG_PROTO)
             != 0) {
@@ -101,13 +104,13 @@
 
     gStatsService->Startup();
 
-    sp<StatsSocketListener> socketListener = new StatsSocketListener(gStatsService);
+    sp<StatsSocketListener> socketListener = new StatsSocketListener(eventQueue);
 
-        ALOGI("using statsd socket");
-        // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
-        if (socketListener->startListener(600)) {
-            exit(1);
-        }
+    ALOGI("Statsd starts to listen to socket.");
+    // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
+    if (socketListener->startListener(600)) {
+        exit(1);
+    }
 
     // Loop forever -- the reports run on this thread in a handler, and the
     // binder calls remain responsive in their pool of one thread.
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index 5435c84..69816cb 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -90,12 +90,12 @@
     std::unique_ptr<std::vector<uint8_t>> buffer(new std::vector<uint8_t>(bufferSize));
 
     size_t pos = 0;
-    auto it = protoOutput.data();
-    while (it.readBuffer() != NULL) {
-        size_t toRead = it.currentToRead();
-        std::memcpy(&((*buffer)[pos]), it.readBuffer(), toRead);
+    sp<android::util::ProtoReader> reader = protoOutput.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&((*buffer)[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        it.rp()->move(toRead);
+        reader->move(toRead);
     }
 
     return buffer;
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index 4cf5333..5ed95ed 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -70,11 +70,11 @@
 bool MetricProducer::evaluateActiveStateLocked(int64_t elapsedTimestampNs) {
     bool isActive = mEventActivationMap.empty();
     for (auto& it : mEventActivationMap) {
-        if (it.second.state == ActivationState::kActive &&
-            elapsedTimestampNs > it.second.ttl_ns + it.second.activation_ns) {
-            it.second.state = ActivationState::kNotActive;
+        if (it.second->state == ActivationState::kActive &&
+            elapsedTimestampNs > it.second->ttl_ns + it.second->activation_ns) {
+            it.second->state = ActivationState::kNotActive;
         }
-        if (it.second.state == ActivationState::kActive) {
+        if (it.second->state == ActivationState::kActive) {
             isActive = true;
         }
     }
@@ -92,7 +92,8 @@
     }
 }
 
-void MetricProducer::addActivation(int activationTrackerIndex, int64_t ttl_seconds) {
+void MetricProducer::addActivation(int activationTrackerIndex, int64_t ttl_seconds,
+                                   int deactivationTrackerIndex) {
     std::lock_guard<std::mutex> lock(mMutex);
     // When a metric producer does not depend on any activation, its mIsActive is true.
     // Therefore, if this is the 1st activation, mIsActive will turn to false. Otherwise it does not
@@ -100,7 +101,12 @@
     if  (mEventActivationMap.empty()) {
         mIsActive = false;
     }
-    mEventActivationMap[activationTrackerIndex].ttl_ns = ttl_seconds * NS_PER_SEC;
+    std::shared_ptr<Activation> activation = std::make_shared<Activation>();
+    activation->ttl_ns = ttl_seconds * NS_PER_SEC;
+    mEventActivationMap.emplace(activationTrackerIndex, activation);
+    if (-1 != deactivationTrackerIndex) {
+        mEventDeactivationMap.emplace(deactivationTrackerIndex, activation);
+    }
 }
 
 void MetricProducer::activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs) {
@@ -109,27 +115,35 @@
         return;
     }
     if (mActivationType == MetricActivation::ACTIVATE_ON_BOOT &&
-        it->second.state == ActivationState::kNotActive) {
-        it->second.state = ActivationState::kActiveOnBoot;
+        it->second->state == ActivationState::kNotActive) {
+        it->second->state = ActivationState::kActiveOnBoot;
         return;
     }
-    it->second.activation_ns = elapsedTimestampNs;
-    it->second.state = ActivationState::kActive;
+    it->second->activation_ns = elapsedTimestampNs;
+    it->second->state = ActivationState::kActive;
     mIsActive = true;
 }
 
+void MetricProducer::cancelEventActivationLocked(int deactivationTrackerIndex) {
+    auto it = mEventDeactivationMap.find(deactivationTrackerIndex);
+    if (it == mEventDeactivationMap.end()) {
+        return;
+    }
+    it->second->state = ActivationState::kNotActive;
+}
+
 void MetricProducer::setActiveLocked(int64_t currentTimeNs, int64_t remainingTtlNs) {
     if (mEventActivationMap.size() == 0) {
         return;
     }
     for (auto& pair : mEventActivationMap) {
         auto& activation = pair.second;
-        if (activation.ttl_ns >= remainingTtlNs) {
-            activation.activation_ns = currentTimeNs + remainingTtlNs - activation.ttl_ns;
-            activation.state = kActive;
+        if (activation->ttl_ns >= remainingTtlNs) {
+            activation->activation_ns = currentTimeNs + remainingTtlNs - activation->ttl_ns;
+            activation->state = kActive;
             mIsActive = true;
-            VLOG("setting new activation time to %lld, %lld, %lld",
-                 (long long)activation.activation_ns, (long long)currentTimeNs,
+            VLOG("setting new activation->time to %lld, %lld, %lld",
+                 (long long)activation->activation_ns, (long long)currentTimeNs,
                  (long long)remainingTtlNs);
             return;
         }
@@ -140,8 +154,8 @@
 int64_t MetricProducer::getRemainingTtlNsLocked(int64_t currentTimeNs) const {
     int64_t maxTtl = 0;
     for (const auto& activation : mEventActivationMap) {
-        if (activation.second.state == kActive) {
-            maxTtl = std::max(maxTtl, activation.second.ttl_ns + activation.second.activation_ns -
+        if (activation.second->state == kActive) {
+            maxTtl = std::max(maxTtl, activation.second->ttl_ns + activation.second->activation_ns -
                                               currentTimeNs);
         }
     }
@@ -153,9 +167,9 @@
         return;
     }
     for (auto& activation : mEventActivationMap) {
-        if (activation.second.state == kActiveOnBoot) {
-            activation.second.state = kActive;
-            activation.second.activation_ns = currentTimeNs;
+        if (activation.second->state == kActiveOnBoot) {
+            activation.second->state = kActive;
+            activation.second->activation_ns = currentTimeNs;
             mIsActive = true;
         }
     }
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 046f996..70fbd47 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -228,6 +228,11 @@
         activateLocked(activationTrackerIndex, elapsedTimestampNs);
     }
 
+    void cancelEventActivation(int deactivationTrackerIndex) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        cancelEventActivationLocked(deactivationTrackerIndex);
+    }
+
     bool isActive() const {
         std::lock_guard<std::mutex> lock(mMutex);
         return isActiveLocked();
@@ -238,7 +243,8 @@
         prepActiveForBootIfNecessaryLocked(currentTimeNs);
     }
 
-    void addActivation(int activationTrackerIndex, int64_t ttl_seconds);
+    void addActivation(int activationTrackerIndex, int64_t ttl_seconds,
+                       int deactivationTrackerIndex = -1);
 
     inline void setActivationType(const MetricActivation::ActivationType& activationType) {
         mActivationType = activationType;
@@ -263,6 +269,7 @@
     bool evaluateActiveStateLocked(int64_t elapsedTimestampNs);
 
     void activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs);
+    void cancelEventActivationLocked(int deactivationTrackerIndex);
 
     inline bool isActiveLocked() const {
         return mIsActive;
@@ -391,13 +398,19 @@
     };
     // When the metric producer has multiple activations, these activations are ORed to determine
     // whether the metric producer is ready to generate metrics.
-    std::unordered_map<int, Activation> mEventActivationMap;
+    std::unordered_map<int, std::shared_ptr<Activation>> mEventActivationMap;
+
+    // Maps index of atom matcher for deactivation to Activation struct.
+    std::unordered_map<int, std::shared_ptr<Activation>> mEventDeactivationMap;
 
     bool mIsActive;
 
     MetricActivation::ActivationType mActivationType;
 
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
 
     FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
     FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 4b3bfd3..095f9dd 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -74,7 +74,8 @@
             timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchers, mAllConditionTrackers,
             mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers,
             mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
-            mActivationAtomTrackerToMetricMap, mMetricIndexesWithActivation, mNoReportMetricIds);
+            mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap,
+            mMetricIndexesWithActivation, mNoReportMetricIds);
 
     mHashStringsInReport = config.hash_strings_in_metric_report();
     mVersionStringsInReport = config.version_strings_in_metric_report();
@@ -255,7 +256,7 @@
 
 bool MetricsManager::checkLogCredentials(const LogEvent& event) {
     if (android::util::AtomsInfo::kWhitelistedAtoms.find(event.GetTagId()) !=
-      android::util::AtomsInfo::kWhitelistedAtoms.end()) 
+      android::util::AtomsInfo::kWhitelistedAtoms.end())
     {
         return true;
     }
@@ -344,24 +345,61 @@
     int64_t eventTimeNs = event.GetElapsedTimestampNs();
 
     bool isActive = mIsAlwaysActive;
-    for (int metric : mMetricIndexesWithActivation) {
-        mAllMetricProducers[metric]->flushIfExpire(eventTimeNs);
-        isActive |= mAllMetricProducers[metric]->isActive();
+
+    // Set of metrics that are still active after flushing.
+    unordered_set<int> activeMetricsIndices;
+
+    // Update state of all metrics w/ activation conditions as of eventTimeNs.
+    for (int metricIndex : mMetricIndexesWithActivation) {
+        const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
+        metric->flushIfExpire(eventTimeNs);
+        if (metric->isActive()) {
+            // If this metric w/ activation condition is still active after
+            // flushing, remember it.
+            activeMetricsIndices.insert(metricIndex);
+        }
     }
 
-    mIsActive = isActive;
+    mIsActive = isActive || !activeMetricsIndices.empty();
 
     if (mTagIds.find(tagId) == mTagIds.end()) {
-        // not interesting...
+        // Not interesting...
         return;
     }
 
     vector<MatchingState> matcherCache(mAllAtomMatchers.size(), MatchingState::kNotComputed);
 
+    // Evaluate all atom matchers.
     for (auto& matcher : mAllAtomMatchers) {
         matcher->onLogEvent(event, mAllAtomMatchers, matcherCache);
     }
 
+    // Set of metrics that received an activation cancellation.
+    unordered_set<int> metricIndicesWithCanceledActivations;
+
+    // Determine which metric activations received a cancellation and cancel them.
+    for (const auto& it : mDeactivationAtomTrackerToMetricMap) {
+        if (matcherCache[it.first] == MatchingState::kMatched) {
+            for (int metricIndex : it.second) {
+                mAllMetricProducers[metricIndex]->cancelEventActivation(it.first);
+                metricIndicesWithCanceledActivations.insert(metricIndex);
+            }
+        }
+    }
+
+    // Determine whether any metrics are no longer active after cancelling metric activations.
+    for (const int metricIndex : metricIndicesWithCanceledActivations) {
+        const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
+        metric->flushIfExpire(eventTimeNs);
+        if (!metric->isActive()) {
+            activeMetricsIndices.erase(metricIndex);
+        }
+    }
+
+    isActive |= !activeMetricsIndices.empty();
+
+
+    // Determine which metric activations should be turned on and turn them on
     for (const auto& it : mActivationAtomTrackerToMetricMap) {
         if (matcherCache[it.first] == MatchingState::kMatched) {
             for (int metricIndex : it.second) {
@@ -406,12 +444,12 @@
         if (pair != mConditionToMetricMap.end()) {
             auto& metricList = pair->second;
             for (auto metricIndex : metricList) {
-                // metric cares about non sliced condition, and it's changed.
+                // Metric cares about non sliced condition, and it's changed.
                 // Push the new condition to it directly.
                 if (!mAllMetricProducers[metricIndex]->isConditionSliced()) {
                     mAllMetricProducers[metricIndex]->onConditionChanged(conditionCache[i],
                                                                          eventTimeNs);
-                    // metric cares about sliced conditions, and it may have changed. Send
+                    // Metric cares about sliced conditions, and it may have changed. Send
                     // notification, and the metric can query the sliced conditions that are
                     // interesting to it.
                 } else {
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 3904460..d317f8e 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -225,18 +225,21 @@
 
     // The following map is initialized from the statsd_config.
 
-    // maps from the index of the LogMatchingTracker to index of MetricProducer.
+    // Maps from the index of the LogMatchingTracker to index of MetricProducer.
     std::unordered_map<int, std::vector<int>> mTrackerToMetricMap;
 
-    // maps from LogMatchingTracker to ConditionTracker
+    // Maps from LogMatchingTracker to ConditionTracker
     std::unordered_map<int, std::vector<int>> mTrackerToConditionMap;
 
-    // maps from ConditionTracker to MetricProducer
+    // Maps from ConditionTracker to MetricProducer
     std::unordered_map<int, std::vector<int>> mConditionToMetricMap;
 
-    // maps from life span triggering event to MetricProducers.
+    // Maps from life span triggering event to MetricProducers.
     std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap;
 
+    // Maps deactivation triggering event to MetricProducers.
+    std::unordered_map<int, std::vector<int>> mDeactivationAtomTrackerToMetricMap;
+
     std::vector<int> mMetricIndexesWithActivation;
 
     void initLogSourceWhiteList();
@@ -281,6 +284,9 @@
     FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
     FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
 
     FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
     FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 463b5a0..082382c 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -711,6 +711,7 @@
                            const unordered_map<int64_t, int> &metricProducerMap,
                            vector<sp<MetricProducer>>& allMetricProducers,
                            unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
+                           unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
                            vector<int>& metricsWithActivation) {
     for (int i = 0; i < config.metric_activation_size(); ++i) {
         const MetricActivation& metric_activation = config.metric_activation(i);
@@ -725,8 +726,8 @@
             ALOGE("Invalid metric tracker index.");
             return false;
         }
-        allMetricProducers[metricTrackerIndex]->setActivationType(
-                metric_activation.activation_type());
+        const sp<MetricProducer>& metric = allMetricProducers[metricTrackerIndex];
+        metric->setActivationType(metric_activation.activation_type());
         metricsWithActivation.push_back(metricTrackerIndex);
         for (int j = 0; j < metric_activation.event_activation_size(); ++j) {
             const EventActivation& activation = metric_activation.event_activation(j);
@@ -738,8 +739,22 @@
             const int atomMatcherIndex = logTrackerIt->second;
             activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(
                 metricTrackerIndex);
-            allMetricProducers[metricTrackerIndex]->addActivation(
-                atomMatcherIndex, activation.ttl_seconds());
+
+            if (activation.has_deactivation_atom_matcher_id()) {
+                auto deactivationAtomMatcherIt =
+                        logEventTrackerMap.find(activation.deactivation_atom_matcher_id());
+                if (deactivationAtomMatcherIt == logEventTrackerMap.end()) {
+                    ALOGE("Atom matcher not found for event deactivation.");
+                    return false;
+                }
+                const int deactivationMatcherIndex = deactivationAtomMatcherIt->second;
+                deactivationAtomTrackerToMetricMap[deactivationMatcherIndex]
+                        .push_back(metricTrackerIndex);
+                metric->addActivation(atomMatcherIndex, activation.ttl_seconds(),
+                                      deactivationMatcherIndex);
+            } else {
+                metric->addActivation(atomMatcherIndex, activation.ttl_seconds());
+            }
         }
     }
     return true;
@@ -759,6 +774,7 @@
                       unordered_map<int, std::vector<int>>& trackerToMetricMap,
                       unordered_map<int, std::vector<int>>& trackerToConditionMap,
                       unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
+                      unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
                       vector<int>& metricsWithActivation,
                       std::set<int64_t>& noReportMetricIds) {
     unordered_map<int64_t, int> logTrackerMap;
@@ -795,7 +811,8 @@
         return false;
     }
     if (!initMetricActivations(key, config, currentTimeNs, logTrackerMap, metricProducerMap,
-            allMetricProducers, activationAtomTrackerToMetricMap, metricsWithActivation)) {
+            allMetricProducers, activationAtomTrackerToMetricMap,
+            deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
         ALOGE("initMetricActivations failed");
         return false;
     }
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
index 9ffceda..028231f 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/metrics_manager_util.h
@@ -108,8 +108,9 @@
                       std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
                       std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
                       std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
-                      unordered_map<int, std::vector<int>>& lifeSpanEventTrackerToMetricMap,
-                      vector<int>& metricsWithLifeSpan,
+                      unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
+                      unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
+                      vector<int>& metricsWithActivation,
                       std::set<int64_t>& noReportMetricIds);
 
 bool isStateTracker(const SimplePredicate& simplePredicate, std::vector<Matcher>* primaryKeys);
diff --git a/cmds/statsd/src/socket/StatsSocketListener.cpp b/cmds/statsd/src/socket/StatsSocketListener.cpp
index 6bb8cda..92200f9 100755
--- a/cmds/statsd/src/socket/StatsSocketListener.cpp
+++ b/cmds/statsd/src/socket/StatsSocketListener.cpp
@@ -41,8 +41,8 @@
 
 static const int kLogMsgHeaderSize = 28;
 
-StatsSocketListener::StatsSocketListener(const sp<LogListener>& listener)
-    : SocketListener(getLogSocket(), false /*start listen*/), mListener(listener) {
+StatsSocketListener::StatsSocketListener(std::shared_ptr<LogEventQueue> queue)
+    : SocketListener(getLogSocket(), false /*start listen*/), mQueue(queue) {
 }
 
 StatsSocketListener::~StatsSocketListener() {
@@ -106,13 +106,21 @@
     // Note that all normal stats logs are in the format of event_list, so there won't be confusion.
     //
     // TODO(b/80538532): In addition to log it in StatsdStats, we should properly reset the config.
-    if (n == sizeof(android_log_event_int_t)) {
-        android_log_event_int_t* int_event = reinterpret_cast<android_log_event_int_t*>(ptr);
-        if (int_event->payload.type == EVENT_TYPE_INT) {
-            ALOGE("Found dropped events: %d error %d", int_event->payload.data,
-                  int_event->header.tag);
-            StatsdStats::getInstance().noteLogLost((int32_t)getWallClockSec(),
-                                                   int_event->payload.data, int_event->header.tag);
+    if (n == sizeof(android_log_event_long_t)) {
+        android_log_event_long_t* long_event = reinterpret_cast<android_log_event_long_t*>(ptr);
+        if (long_event->payload.type == EVENT_TYPE_LONG) {
+            int64_t composed_long = long_event->payload.data;
+
+            // format:
+            // |last_tag|dropped_count|
+            int32_t dropped_count = (int32_t)(0xffffffff & composed_long);
+            int32_t last_atom_tag = (int32_t)((0xffffffff00000000 & (uint64_t)composed_long) >> 32);
+
+            ALOGE("Found dropped events: %d error %d last atom tag %d from uid %d", dropped_count,
+                  long_event->header.tag, last_atom_tag, cred->uid);
+            StatsdStats::getInstance().noteLogLost((int32_t)getWallClockSec(), dropped_count,
+                                                   long_event->header.tag, last_atom_tag, cred->uid,
+                                                   cred->pid);
             return true;
         }
     }
@@ -126,10 +134,11 @@
     msg.entry.uid = cred->uid;
 
     memcpy(msg.buf + kLogMsgHeaderSize, ptr, n + 1);
-    LogEvent event(msg);
 
-    // Call the listener
-    mListener->OnLogEvent(&event);
+    int64_t oldestTimestamp;
+    if (!mQueue->push(std::make_unique<LogEvent>(msg), &oldestTimestamp)) {
+        StatsdStats::getInstance().noteEventQueueOverflow(oldestTimestamp);
+    }
 
     return true;
 }
diff --git a/cmds/statsd/src/socket/StatsSocketListener.h b/cmds/statsd/src/socket/StatsSocketListener.h
index b8185d2..2167a56 100644
--- a/cmds/statsd/src/socket/StatsSocketListener.h
+++ b/cmds/statsd/src/socket/StatsSocketListener.h
@@ -17,7 +17,7 @@
 
 #include <sysutils/SocketListener.h>
 #include <utils/RefBase.h>
-#include "logd/LogListener.h"
+#include "logd/LogEventQueue.h"
 
 // DEFAULT_OVERFLOWUID is defined in linux/highuid.h, which is not part of
 // the uapi headers for userspace to use.  This value is filled in on the
@@ -35,7 +35,7 @@
 
 class StatsSocketListener : public SocketListener, public virtual android::RefBase {
 public:
-    explicit StatsSocketListener(const sp<LogListener>& listener);
+    explicit StatsSocketListener(std::shared_ptr<LogEventQueue> queue);
 
     virtual ~StatsSocketListener();
 
@@ -47,7 +47,7 @@
     /**
      * Who is going to get the events when they're read.
      */
-    sp<LogListener> mListener;
+    std::shared_ptr<LogEventQueue> mQueue;
 };
 }  // namespace statsd
 }  // namespace os
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 166e087..1dfc433 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -455,8 +455,19 @@
         optional int32 detected_time_sec = 1;
         optional int32 count = 2;
         optional int32 last_error = 3;
+        optional int32 last_tag = 4;
+        optional int32 uid = 5;
+        optional int32 pid = 6;
     }
     repeated LogLossStats detected_log_loss = 16;
+
+    message EventQueueOverflow {
+        optional int32 count = 1;
+        optional int64 max_queue_history_ns = 2;
+        optional int64 min_queue_history_ns = 3;
+    }
+
+    optional EventQueueOverflow queue_overflow = 18;
 }
 
 message AlertTriggerDetails {
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index 59d4865..cdef874 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -80,11 +80,11 @@
 template<class T>
 bool parseProtoOutputStream(util::ProtoOutputStream& protoOutput, T* message) {
     std::string pbBytes;
-    auto iter = protoOutput.data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-         pbBytes.append(reinterpret_cast<const char*>(iter.readBuffer()), toRead);
-        iter.rp()->move(toRead);
+    sp<android::util::ProtoReader> reader = protoOutput.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+         pbBytes.append(reinterpret_cast<const char*>(reader->readBuffer()), toRead);
+        reader->move(toRead);
     }
     return message->ParseFromArray(pbBytes.c_str(), pbBytes.size());
 }
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 0e91f52..257e65e 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -380,6 +380,7 @@
 message EventActivation {
   optional int64 atom_matcher_id = 1;
   optional int64 ttl_seconds = 2;
+  optional int64 deactivation_atom_matcher_id = 3;
 }
 
 message MetricActivation {
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 65b183c..cf8b974 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -36,9 +36,17 @@
 using android::util::FIELD_TYPE_MESSAGE;
 using std::map;
 
+/**
+ * NOTE: these directories are protected by SELinux, any changes here must also update
+ * the SELinux policies.
+ */
 #define STATS_DATA_DIR "/data/misc/stats-data"
 #define STATS_SERVICE_DIR "/data/misc/stats-service"
 #define TRAIN_INFO_DIR "/data/misc/train-info"
+#define TRAIN_INFO_PATH "/data/misc/train-info/train-info.bin"
+
+// Magic word at the start of the train info file, change this if changing the file format
+const uint32_t TRAIN_INFO_FILE_MAGIC = 0xff7447ff;
 
 // for ConfigMetricsReportList
 const int FIELD_ID_REPORTS = 2;
@@ -96,27 +104,42 @@
 }
 
 bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& trainName,
-                                    int32_t status, const std::vector<uint8_t>& experimentIds) {
+                                    int32_t status, const std::vector<int64_t>& experimentIds) {
     std::lock_guard<std::mutex> lock(sTrainInfoMutex);
 
     deleteAllFiles(TRAIN_INFO_DIR);
 
-    string file_name = StringPrintf("%s/%lld", TRAIN_INFO_DIR, (long long)trainVersionCode);
-
-    int fd = open(file_name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
+    int fd = open(TRAIN_INFO_PATH, O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
     if (fd == -1) {
-        VLOG("Attempt to access %s but failed", file_name.c_str());
+        VLOG("Attempt to access %s but failed", TRAIN_INFO_PATH);
         return false;
     }
 
     size_t result;
 
+    // Write the magic word
+    result = write(fd, &TRAIN_INFO_FILE_MAGIC, sizeof(TRAIN_INFO_FILE_MAGIC));
+    if (result != sizeof(TRAIN_INFO_FILE_MAGIC)) {
+        VLOG("Failed to wrtie train info magic");
+        close(fd);
+        return false;
+    }
+
+    // Write the train version
+    const size_t trainVersionCodeByteCount = sizeof(trainVersionCode);
+    result = write(fd, &trainVersionCode, trainVersionCodeByteCount);
+    if (result != trainVersionCodeByteCount) {
+        VLOG("Failed to wrtie train version code");
+        close(fd);
+        return false;
+    }
+
     // Write # of bytes in trainName to file
     const size_t trainNameSize = trainName.size();
     const size_t trainNameSizeByteCount = sizeof(trainNameSize);
     result = write(fd, (uint8_t*)&trainNameSize, trainNameSizeByteCount);
     if (result != trainNameSizeByteCount) {
-        VLOG("Failed to write train name size for %s", file_name.c_str());
+        VLOG("Failed to write train name size");
         close(fd);
         return false;
     }
@@ -124,7 +147,7 @@
     // Write trainName to file
     result = write(fd, trainName.c_str(), trainNameSize);
     if (result != trainNameSize) {
-        VLOG("Failed to write train name for%s", file_name.c_str());
+        VLOG("Failed to write train name");
         close(fd);
         return false;
     }
@@ -133,34 +156,38 @@
     const size_t statusByteCount = sizeof(status);
     result = write(fd, (uint8_t*)&status, statusByteCount);
     if (result != statusByteCount) {
-        VLOG("Failed to write status for %s", file_name.c_str());
+        VLOG("Failed to write status");
         close(fd);
         return false;
     }
 
-    // Write experiment id size to file.
-    const size_t experimentIdSize = experimentIds.size();
-    const size_t experimentIdsSizeByteCount = sizeof(experimentIdSize);
-    result = write(fd, (uint8_t*) &experimentIdSize, experimentIdsSizeByteCount);
-    if (result != experimentIdsSizeByteCount) {
-        VLOG("Failed to write experiment id size for %s", file_name.c_str());
+    // Write experiment id count to file.
+    const size_t experimentIdsCount = experimentIds.size();
+    const size_t experimentIdsCountByteCount = sizeof(experimentIdsCount);
+    result = write(fd, (uint8_t*) &experimentIdsCount, experimentIdsCountByteCount);
+    if (result != experimentIdsCountByteCount) {
+        VLOG("Failed to write experiment id count");
         close(fd);
         return false;
     }
 
     // Write experimentIds to file
-    result = write(fd, experimentIds.data(), experimentIds.size());
-    if (result == experimentIds.size()) {
-        VLOG("Successfully wrote %s", file_name.c_str());
-    } else {
-        VLOG("Failed to write experiment ids for %s", file_name.c_str());
-        close(fd);
-        return false;
+    for (size_t i = 0; i < experimentIdsCount; i++) {
+        const int64_t experimentId = experimentIds[i];
+        const size_t experimentIdByteCount = sizeof(experimentId);
+        result = write(fd, &experimentId, experimentIdByteCount);
+        if (result == experimentIdByteCount) {
+            VLOG("Successfully wrote experiment IDs");
+        } else {
+            VLOG("Failed to write experiment ids");
+            close(fd);
+            return false;
+        }
     }
 
     result = fchown(fd, AID_STATSD, AID_STATSD);
     if (result) {
-        VLOG("Failed to chown %s to statsd", file_name.c_str());
+        VLOG("Failed to chown train info file to statsd");
         close(fd);
         return false;
     }
@@ -172,88 +199,96 @@
 bool StorageManager::readTrainInfo(InstallTrainInfo& trainInfo) {
     std::lock_guard<std::mutex> lock(sTrainInfoMutex);
 
-    unique_ptr<DIR, decltype(&closedir)> dir(opendir(TRAIN_INFO_DIR), closedir);
-
-    if (dir == NULL) {
-        VLOG("Directory does not exist: %s", TRAIN_INFO_DIR);
+    int fd = open(TRAIN_INFO_PATH, O_RDONLY | O_CLOEXEC);
+    if (fd == -1) {
+        VLOG("Failed to open train-info.bin");
         return false;
     }
 
-    dirent* de;
-    while ((de = readdir(dir.get()))) {
-        char* name = de->d_name;
-        if (name[0] == '.') {
-            continue;
-        }
-
-        size_t result;
-
-        trainInfo.trainVersionCode = StrToInt64(name);
-        string fullPath = StringPrintf("%s/%s", TRAIN_INFO_DIR, name);
-        int fd = open(fullPath.c_str(), O_RDONLY | O_CLOEXEC);
-        if (fd == -1) {
-            return false;
-        }
-
-        // Read # of bytes taken by trainName in the file.
-        size_t trainNameSize;
-        result = read(fd, &trainNameSize, sizeof(size_t));
-        if (result != sizeof(size_t)) {
-            VLOG("Failed to read train name size from file %s", fullPath.c_str());
-            close(fd);
-            return false;
-        }
-
-        // Read trainName
-        trainInfo.trainName.resize(trainNameSize);
-        result = read(fd, trainInfo.trainName.data(), trainNameSize);
-        if (result != trainNameSize) {
-            VLOG("Failed to read train name from file %s", fullPath.c_str());
-            close(fd);
-            return false;
-        }
-
-        // Read status
-        const size_t statusByteCount = sizeof(trainInfo.status);
-        result = read(fd, &trainInfo.status, statusByteCount);
-        if (result != statusByteCount) {
-            VLOG("Failed to read train status from file %s", fullPath.c_str());
-            close(fd);
-            return false;
-        }
-
-        // Read experiment ids size.
-        size_t experimentIdSize;
-        result = read(fd, &experimentIdSize, sizeof(size_t));
-        if (result != sizeof(size_t)) {
-            VLOG("Failed to read train experiment id size from file %s", fullPath.c_str());
-            close(fd);
-            return false;
-        }
-
-        // Read experimentIds
-        trainInfo.experimentIds.resize(experimentIdSize);
-        result = read(fd, trainInfo.experimentIds.data(), experimentIdSize);
-        if (result != experimentIdSize) {
-            VLOG("Failed to read train experiment ids from file %s", fullPath.c_str());
-            close(fd);
-            return false;
-        }
-
-        // Expect to be at EOF.
-        char c;
-        result = read(fd, &c, 1);
-        if (result != 0) {
-            VLOG("Failed to read train info from file %s. Did not get expected EOF.", fullPath.c_str());
-            close(fd);
-            return false;
-        }
-
-        VLOG("Read train info file successful: %s", fullPath.c_str());
+    // Read the magic word
+    uint32_t magic;
+    size_t result = read(fd, &magic, sizeof(magic));
+    if (result != sizeof(magic)) {
+        VLOG("Failed to read train info magic");
         close(fd);
-        return true;
+        return false;
     }
-    return false;
+
+    if (magic != TRAIN_INFO_FILE_MAGIC) {
+        VLOG("Train info magic was 0x%08x, expected 0x%08x", magic, TRAIN_INFO_FILE_MAGIC);
+        close(fd);
+        return false;
+    }
+
+    // Read the train version code
+    const size_t trainVersionCodeByteCount(sizeof(trainInfo.trainVersionCode));
+    result = read(fd, &trainInfo.trainVersionCode, trainVersionCodeByteCount);
+    if (result != trainVersionCodeByteCount) {
+        VLOG("Failed to read train version code from train info file");
+        close(fd);
+        return false;
+    }
+
+    // Read # of bytes taken by trainName in the file.
+    size_t trainNameSize;
+    result = read(fd, &trainNameSize, sizeof(size_t));
+    if (result != sizeof(size_t)) {
+        VLOG("Failed to read train name size from train info file");
+        close(fd);
+        return false;
+    }
+
+    // Read trainName
+    trainInfo.trainName.resize(trainNameSize);
+    result = read(fd, trainInfo.trainName.data(), trainNameSize);
+    if (result != trainNameSize) {
+        VLOG("Failed to read train name from train info file");
+        close(fd);
+        return false;
+    }
+
+    // Read status
+    const size_t statusByteCount = sizeof(trainInfo.status);
+    result = read(fd, &trainInfo.status, statusByteCount);
+    if (result != statusByteCount) {
+        VLOG("Failed to read train status from train info file");
+        close(fd);
+        return false;
+    }
+
+    // Read experiment ids count.
+    size_t experimentIdsCount;
+    result = read(fd, &experimentIdsCount, sizeof(size_t));
+    if (result != sizeof(size_t)) {
+        VLOG("Failed to read train experiment id count from train info file");
+        close(fd);
+        return false;
+    }
+
+    // Read experimentIds
+    for (size_t i = 0; i < experimentIdsCount; i++) {
+        int64_t experimentId;
+        result = read(fd, &experimentId, sizeof(experimentId));
+        if (result != sizeof(experimentId)) {
+            VLOG("Failed to read train experiment id from train info file");
+            close(fd);
+            return false;
+        }
+        trainInfo.experimentIds.push_back(experimentId);
+    }
+
+    // Expect to be at EOF.
+    char c;
+    result = read(fd, &c, 1);
+    if (result != 0) {
+        VLOG("Failed to read train info from file. Did not get expected EOF.");
+        close(fd);
+        return false;
+    }
+
+    VLOG("Read train info file successful");
+    close(fd);
+    return true;
 }
 
 void StorageManager::deleteFile(const char* file) {
diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h
index 88280cf..dfcea65 100644
--- a/cmds/statsd/src/storage/StorageManager.h
+++ b/cmds/statsd/src/storage/StorageManager.h
@@ -29,11 +29,6 @@
 
 using android::util::ProtoOutputStream;
 
-struct TrainInfo {
-    int64_t trainVersionCode;
-    std::vector<uint8_t> experimentIds;
-};
-
 class StorageManager : public virtual RefBase {
 public:
     /**
@@ -45,7 +40,7 @@
      * Writes train info.
      */
     static bool writeTrainInfo(int64_t trainVersionCode, const std::string& trainName,
-                               int32_t status, const std::vector<uint8_t>& experimentIds);
+                               int32_t status, const std::vector<int64_t>& experimentIds);
 
     /**
      * Reads train info.
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
index 7c2d242..ff1cb4f 100644
--- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp
+++ b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
@@ -120,12 +120,12 @@
 
     protoData->resize(headerProto.size());
     size_t pos = 0;
-    auto iter = headerProto.data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-        std::memcpy(&((*protoData)[pos]), iter.readBuffer(), toRead);
+    sp<android::util::ProtoReader> reader = headerProto.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&((*protoData)[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        iter.rp()->move(toRead);
+        reader->move(toRead);
     }
 }
 }  // namespace
@@ -152,15 +152,15 @@
     uint8_t dest;
     switch (config.dest()) {
         case IncidentdDetails_Destination_AUTOMATIC:
-            dest = android::os::DEST_AUTOMATIC;
+            dest = android::os::PRIVACY_POLICY_AUTOMATIC;
             break;
         case IncidentdDetails_Destination_EXPLICIT:
-            dest = android::os::DEST_EXPLICIT;
+            dest = android::os::PRIVACY_POLICY_EXPLICIT;
             break;
         default:
-            dest = android::os::DEST_AUTOMATIC;
+            dest = android::os::PRIVACY_POLICY_AUTOMATIC;
     }
-    incidentReport.setDest(dest);
+    incidentReport.setPrivacyPolicy(dest);
 
     incidentReport.setReceiverPkg(config.receiver_pkg());
 
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
index a9305ac..f1cad92 100644
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -24,6 +24,8 @@
 
 #ifdef __ANDROID__
 
+using android::util::ProtoReader;
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -252,12 +254,12 @@
         vector<uint8_t> outData;
         outData.resize(protoOut.size());
         size_t pos = 0;
-        auto iter = protoOut.data();
-        while (iter.readBuffer() != NULL) {
-            size_t toRead = iter.currentToRead();
-            std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+        sp<ProtoReader> reader = protoOut.data();
+        while (reader->readBuffer() != NULL) {
+            size_t toRead = reader->currentToRead();
+            std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
             pos += toRead;
-            iter.rp()->move(toRead);
+            reader->move(toRead);
         }
 
         DimensionsValue result;
@@ -343,12 +345,12 @@
     vector<uint8_t> outData;
     outData.resize(protoOut.size());
     size_t pos = 0;
-    auto iter = protoOut.data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-        std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+    sp<ProtoReader> reader = protoOut.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        iter.rp()->move(toRead);
+        reader->move(toRead);
     }
 
     DimensionsValue result;
@@ -405,12 +407,12 @@
     vector<uint8_t> outData;
     outData.resize(protoOut.size());
     size_t pos = 0;
-    auto iter = protoOut.data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-        std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+    sp<ProtoReader> reader = protoOut.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        iter.rp()->move(toRead);
+        reader->move(toRead);
     }
 
     DimensionsValueTuple result;
@@ -458,12 +460,12 @@
     vector<uint8_t> outData;
     outData.resize(protoOutput.size());
     size_t pos = 0;
-    auto iter = protoOutput.data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-        std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+    sp<ProtoReader> reader = protoOutput.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        iter.rp()->move(toRead);
+        reader->move(toRead);
     }
 
     Atom result;
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index eec3c73..504ee22 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -26,6 +26,7 @@
 
 using std::string;
 using util::ProtoOutputStream;
+using util::ProtoReader;
 
 TEST(LogEventTest, TestLogParsing) {
     LogEvent event1(1, 2000);
@@ -590,12 +591,12 @@
     std::vector<uint8_t> outData;
     outData.resize(proto.size());
     size_t pos = 0;
-    auto iter = proto.data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-        std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+    sp<ProtoReader> reader = proto.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        iter.rp()->move(toRead);
+        reader->move(toRead);
     }
 
     std::string result_str(outData.begin(), outData.end());
@@ -629,12 +630,12 @@
     std::vector<uint8_t> outData;
     outData.resize(proto.size());
     size_t pos = 0;
-    auto iter = proto.data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-        std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+    sp<ProtoReader> reader = proto.data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        iter.rp()->move(toRead);
+        reader->move(toRead);
     }
 
     std::string result_str(outData.begin(), outData.end());
@@ -644,6 +645,22 @@
     EXPECT_EQ(orig_str, result_str);
 }
 
+TEST(LogEventTest, TestWriteExperimentIdsToProto) {
+    std::vector<int64_t> expIds;
+    expIds.push_back(5038);
+    std::vector<uint8_t> proto;
+
+    writeExperimentIdsToProto(expIds, &proto);
+
+    EXPECT_EQ(proto.size(), 3);
+    // Proto wire format for field ID 1, varint
+    EXPECT_EQ(proto[0], 0x08);
+    // varint of 5038, 2 bytes long
+    EXPECT_EQ(proto[1], 0xae);
+    EXPECT_EQ(proto[2], 0x27);
+}
+
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index f8184d8..71adc57 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -282,8 +282,9 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
-    vector<int> metricsWithLifeSpan;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+    vector<int> metricsWithActivation;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
@@ -291,8 +292,8 @@
                                  allAtomMatchers, allConditionTrackers, allMetricProducers,
                                  allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
                                  trackerToMetricMap, trackerToConditionMap,
-                                 lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
-                                 noReportMetricIds));
+                                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                                 metricsWithActivation, noReportMetricIds));
     EXPECT_EQ(1u, allMetricProducers.size());
     EXPECT_EQ(1u, allAnomalyTrackers.size());
     EXPECT_EQ(1u, noReportMetricIds.size());
@@ -313,8 +314,9 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
-    vector<int> metricsWithLifeSpan;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+    vector<int> metricsWithActivation;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
@@ -322,8 +324,8 @@
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
                                   trackerToMetricMap, trackerToConditionMap,
-                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
-                                  noReportMetricIds));
+                                  activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                                  metricsWithActivation, noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
@@ -341,8 +343,9 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
-    vector<int> metricsWithLifeSpan;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+    vector<int> metricsWithActivation;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
@@ -350,8 +353,8 @@
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
                                   trackerToMetricMap, trackerToConditionMap,
-                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
-                                  noReportMetricIds));
+                                  activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                                  metricsWithActivation, noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestMissingMatchers) {
@@ -369,16 +372,17 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
-    vector<int> metricsWithLifeSpan;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+    vector<int> metricsWithActivation;
     std::set<int64_t> noReportMetricIds;
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
                                   trackerToMetricMap, trackerToConditionMap,
-                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
-                                  noReportMetricIds));
+                                  activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                                  metricsWithActivation, noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestMissingPredicate) {
@@ -396,16 +400,17 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
-    vector<int> metricsWithLifeSpan;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+    vector<int> metricsWithActivation;
     std::set<int64_t> noReportMetricIds;
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
                                   trackerToMetricMap, trackerToConditionMap,
-                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
-                                  noReportMetricIds));
+                                  activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                                  metricsWithActivation, noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestCirclePredicateDependency) {
@@ -423,8 +428,9 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
-    vector<int> metricsWithLifeSpan;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+    vector<int> metricsWithActivation;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
@@ -432,8 +438,8 @@
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
                                   trackerToMetricMap, trackerToConditionMap,
-                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
-                                  noReportMetricIds));
+                                  activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                                  metricsWithActivation, noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
@@ -451,8 +457,9 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
-    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
-    vector<int> metricsWithLifeSpan;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
+    vector<int> metricsWithActivation;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
@@ -460,8 +467,8 @@
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
                                   trackerToMetricMap, trackerToConditionMap,
-                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
-                                  noReportMetricIds));
+                                  activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
+                                  metricsWithActivation, noReportMetricIds));
 }
 
 #else
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index 88aa180..91e282a 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -610,26 +610,26 @@
     // Assert that all 3 metrics with activation are inactive and that the ttls were properly set.
     EXPECT_FALSE(metricProducer1003->isActive());
     const auto& activation1003 = metricProducer1003->mEventActivationMap.begin()->second;
-    EXPECT_EQ(100 * NS_PER_SEC, activation1003.ttl_ns);
-    EXPECT_EQ(0, activation1003.activation_ns);
+    EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns);
+    EXPECT_EQ(0, activation1003->activation_ns);
     EXPECT_FALSE(metricProducer1005->isActive());
     const auto& activation1005 = metricProducer1005->mEventActivationMap.begin()->second;
-    EXPECT_EQ(100 * NS_PER_SEC, activation1005.ttl_ns);
-    EXPECT_EQ(0, activation1005.activation_ns);
+    EXPECT_EQ(100 * NS_PER_SEC, activation1005->ttl_ns);
+    EXPECT_EQ(0, activation1005->activation_ns);
     EXPECT_FALSE(metricProducer1006->isActive());
     const auto& activation1006 = metricProducer1006->mEventActivationMap.begin()->second;
-    EXPECT_EQ(200 * NS_PER_SEC, activation1006.ttl_ns);
-    EXPECT_EQ(0, activation1006.activation_ns);
+    EXPECT_EQ(200 * NS_PER_SEC, activation1006->ttl_ns);
+    EXPECT_EQ(0, activation1006->activation_ns);
 
     processor2->LoadMetricsActivationFromDisk();
 
     // After loading activations from disk, assert that all 3 metrics are active.
     EXPECT_TRUE(metricProducer1003->isActive());
-    EXPECT_EQ(timeBase2 + ttl3 - activation1003.ttl_ns, activation1003.activation_ns);
+    EXPECT_EQ(timeBase2 + ttl3 - activation1003->ttl_ns, activation1003->activation_ns);
     EXPECT_TRUE(metricProducer1005->isActive());
-    EXPECT_EQ(timeBase2 + ttl5 - activation1005.ttl_ns, activation1005.activation_ns);
+    EXPECT_EQ(timeBase2 + ttl5 - activation1005->ttl_ns, activation1005->activation_ns);
     EXPECT_TRUE(metricProducer1006->isActive());
-    EXPECT_EQ(timeBase2 + ttl6 - activation1006.ttl_ns, activation1003.activation_ns);
+    EXPECT_EQ(timeBase2 + ttl6 - activation1006->ttl_ns, activation1003->activation_ns);
 
     // Make sure no more broadcasts have happened.
     EXPECT_EQ(broadcastCount, 1);
@@ -696,17 +696,17 @@
     EXPECT_TRUE(metricProducer2->isActive());
 
     const auto& activation1 = metricProducer1->mEventActivationMap.begin()->second;
-    EXPECT_EQ(100 * NS_PER_SEC, activation1.ttl_ns);
-    EXPECT_EQ(0, activation1.activation_ns);
-    EXPECT_EQ(kNotActive, activation1.state);
+    EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
+    EXPECT_EQ(0, activation1->activation_ns);
+    EXPECT_EQ(kNotActive, activation1->state);
 
     std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")};
     auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1);
     processor->OnLogEvent(event.get());
 
     EXPECT_FALSE(metricProducer1->isActive());
-    EXPECT_EQ(0, activation1.activation_ns);
-    EXPECT_EQ(kActiveOnBoot, activation1.state);
+    EXPECT_EQ(0, activation1->activation_ns);
+    EXPECT_EQ(kActiveOnBoot, activation1->state);
 
     int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
 
@@ -746,14 +746,14 @@
     EXPECT_TRUE(metricProducer1002->isActive());
 
     const auto& activation1001 = metricProducer1001->mEventActivationMap.begin()->second;
-    EXPECT_EQ(100 * NS_PER_SEC, activation1001.ttl_ns);
-    EXPECT_EQ(0, activation1001.activation_ns);
-    EXPECT_EQ(kNotActive, activation1001.state);
+    EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns);
+    EXPECT_EQ(0, activation1001->activation_ns);
+    EXPECT_EQ(kNotActive, activation1001->state);
 
     processor2->LoadMetricsActivationFromDisk();
 
     EXPECT_TRUE(metricProducer1001->isActive());
-    EXPECT_EQ(timeBase2 + ttl1 - activation1001.ttl_ns, activation1001.activation_ns);
+    EXPECT_EQ(timeBase2 + ttl1 - activation1001->ttl_ns, activation1001->activation_ns);
 }
 
 #else
diff --git a/cmds/statsd/tests/StatsService_test.cpp b/cmds/statsd/tests/StatsService_test.cpp
index 560fb9f..7c00531 100644
--- a/cmds/statsd/tests/StatsService_test.cpp
+++ b/cmds/statsd/tests/StatsService_test.cpp
@@ -33,7 +33,7 @@
 #ifdef __ANDROID__
 
 TEST(StatsServiceTest, TestAddConfig_simple) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     StatsdConfig config;
     config.set_id(12345);
     string serialized = config.SerializeAsString();
@@ -43,7 +43,7 @@
 }
 
 TEST(StatsServiceTest, TestAddConfig_empty) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     string serialized = "";
 
     EXPECT_TRUE(
@@ -51,7 +51,7 @@
 }
 
 TEST(StatsServiceTest, TestAddConfig_invalid) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     string serialized = "Invalid config!";
 
     EXPECT_FALSE(
@@ -69,7 +69,7 @@
 
     int32_t uid;
 
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     service.mEngBuild = true;
 
     // "-1"
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
index c04a40c..d9fa4e9 100644
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ b/cmds/statsd/tests/UidMap_test.cpp
@@ -33,6 +33,7 @@
 namespace statsd {
 
 using android::util::ProtoOutputStream;
+using android::util::ProtoReader;
 
 #ifdef __ANDROID__
 const string kApp1 = "app1.sharing.1";
@@ -179,12 +180,12 @@
     vector<uint8_t> bytes;
     bytes.resize(proto->size());
     size_t pos = 0;
-    auto iter = proto->data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-        std::memcpy(&((bytes)[pos]), iter.readBuffer(), toRead);
+    sp<ProtoReader> reader = proto->data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        iter.rp()->move(toRead);
+        reader->move(toRead);
     }
     results->ParseFromArray(bytes.data(), bytes.size());
 }
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
index 7fb43f8a..bf52bb0 100644
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
@@ -31,9 +31,9 @@
 StatsdConfig CreateStatsdConfig() {
     StatsdConfig config;
     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
     auto crashMatcher = CreateProcessCrashAtomMatcher();
     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
-    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
 
     *config.add_atom_matcher() = saverModeMatcher;
     *config.add_atom_matcher() = crashMatcher;
@@ -60,13 +60,149 @@
     return config;
 }
 
+StatsdConfig CreateStatsdConfigWithOneDeactivation() {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
+    auto crashMatcher = CreateProcessCrashAtomMatcher();
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
+
+    *config.add_atom_matcher() = saverModeMatcher;
+    *config.add_atom_matcher() = crashMatcher;
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = brightnessChangedMatcher;
+
+    int64_t metricId = 123456;
+    auto countMetric = config.add_count_metric();
+    countMetric->set_id(metricId);
+    countMetric->set_what(crashMatcher.id());
+    countMetric->set_bucket(FIVE_MINUTES);
+    countMetric->mutable_dimensions_in_what()->set_field(
+        android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
+
+    auto metric_activation1 = config.add_metric_activation();
+    metric_activation1->set_metric_id(metricId);
+    auto event_activation1 = metric_activation1->add_event_activation();
+    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
+    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
+    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
+    auto event_activation2 = metric_activation1->add_event_activation();
+    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
+    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
+
+    return config;
+}
+
+StatsdConfig CreateStatsdConfigWithTwoDeactivations() {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
+    auto crashMatcher = CreateProcessCrashAtomMatcher();
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
+    auto brightnessChangedMatcher2 = CreateScreenBrightnessChangedAtomMatcher();
+    brightnessChangedMatcher2.set_id(StringToId("ScreenBrightnessChanged2"));
+
+    *config.add_atom_matcher() = saverModeMatcher;
+    *config.add_atom_matcher() = crashMatcher;
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = brightnessChangedMatcher;
+    *config.add_atom_matcher() = brightnessChangedMatcher2;
+
+    int64_t metricId = 123456;
+    auto countMetric = config.add_count_metric();
+    countMetric->set_id(metricId);
+    countMetric->set_what(crashMatcher.id());
+    countMetric->set_bucket(FIVE_MINUTES);
+    countMetric->mutable_dimensions_in_what()->set_field(
+        android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
+
+    auto metric_activation1 = config.add_metric_activation();
+    metric_activation1->set_metric_id(metricId);
+    auto event_activation1 = metric_activation1->add_event_activation();
+    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
+    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
+    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
+    auto event_activation2 = metric_activation1->add_event_activation();
+    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
+    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
+    event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
+
+    return config;
+}
+
+StatsdConfig CreateStatsdConfigWithTwoMetricsTwoDeactivations() {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
+    auto crashMatcher = CreateProcessCrashAtomMatcher();
+    auto foregroundMatcher = CreateMoveToForegroundAtomMatcher();
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto brightnessChangedMatcher = CreateScreenBrightnessChangedAtomMatcher();
+    auto brightnessChangedMatcher2 = CreateScreenBrightnessChangedAtomMatcher();
+    brightnessChangedMatcher2.set_id(StringToId("ScreenBrightnessChanged2"));
+
+    *config.add_atom_matcher() = saverModeMatcher;
+    *config.add_atom_matcher() = crashMatcher;
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = brightnessChangedMatcher;
+    *config.add_atom_matcher() = brightnessChangedMatcher2;
+    *config.add_atom_matcher() = foregroundMatcher;
+
+    int64_t metricId = 123456;
+    auto countMetric = config.add_count_metric();
+    countMetric->set_id(metricId);
+    countMetric->set_what(crashMatcher.id());
+    countMetric->set_bucket(FIVE_MINUTES);
+    countMetric->mutable_dimensions_in_what()->set_field(
+        android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
+    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
+
+    int64_t metricId2 = 234567;
+    countMetric = config.add_count_metric();
+    countMetric->set_id(metricId2);
+    countMetric->set_what(foregroundMatcher.id());
+    countMetric->set_bucket(FIVE_MINUTES);
+    countMetric->mutable_dimensions_in_what()->set_field(
+        android::util::ACTIVITY_FOREGROUND_STATE_CHANGED);
+    countMetric->mutable_dimensions_in_what()->add_child()->set_field(1);  // uid field
+
+    auto metric_activation1 = config.add_metric_activation();
+    metric_activation1->set_metric_id(metricId);
+    auto event_activation1 = metric_activation1->add_event_activation();
+    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
+    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
+    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
+    auto event_activation2 = metric_activation1->add_event_activation();
+    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
+    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
+    event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
+
+    metric_activation1 = config.add_metric_activation();
+    metric_activation1->set_metric_id(metricId2);
+    event_activation1 = metric_activation1->add_event_activation();
+    event_activation1->set_atom_matcher_id(saverModeMatcher.id());
+    event_activation1->set_ttl_seconds(60 * 6);  // 6 minutes
+    event_activation1->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
+    event_activation2 = metric_activation1->add_event_activation();
+    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
+    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
+    event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher2.id());
+
+    return config;
+}
+
 }  // namespace
 
 TEST(MetricActivationE2eTest, TestCountMetric) {
     auto config = CreateStatsdConfig();
 
-    int64_t bucketStartTimeNs = 10000000000;
-    int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
+    int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
+    int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
 
     int uid = 12345;
     int64_t cfgId = 98765;
@@ -108,12 +244,12 @@
     EXPECT_EQ(eventActivationMap.size(), 2u);
     EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
-    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0].activation_ns, 0);
-    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2].activation_ns, 0);
-    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
 
     std::unique_ptr<LogEvent> event;
 
@@ -131,12 +267,12 @@
     EXPECT_EQ(broadcastCount, 1);
     EXPECT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2].activation_ns, 0);
-    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
 
     // First processed event.
     event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
@@ -148,12 +284,12 @@
     processor.OnLogEvent(event.get());
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2].activation_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
 
     // 2nd processed event.
     // The activation by screen_on event expires, but the one by battery save mode is still active.
@@ -161,12 +297,12 @@
     processor.OnLogEvent(event.get());
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2].activation_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
     // No new broadcast since the config should still be active.
     EXPECT_EQ(broadcastCount, 1);
 
@@ -182,14 +318,14 @@
     // New broadcast since the config is no longer active.
     EXPECT_EQ(broadcastCount, 2);
     EXPECT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[2].activation_ns, bucketStartTimeNs + 20);
-    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
 
-    // Re-activate.
+    // Re-activate metric via screen on.
     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
                                           bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     processor.OnLogEvent(event.get());
@@ -198,13 +334,14 @@
     EXPECT_EQ(broadcastCount, 3);
     EXPECT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
-    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kNotActive);
-    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
-    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
-    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kActive);
-    EXPECT_EQ(eventActivationMap[2].activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
-    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
 
+    // 4th processed event.
     event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
     processor.OnLogEvent(event.get());
 
@@ -272,9 +409,1192 @@
               data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
               data.bucket_info(0).end_bucket_elapsed_nanos());
-
 }
 
+TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation) {
+    auto config = CreateStatsdConfigWithOneDeactivation();
+
+    int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
+    int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
+
+    int uid = 12345;
+    int64_t cfgId = 98765;
+    ConfigKey cfgKey(uid, cfgId);
+
+    sp<UidMap> m = new UidMap();
+    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> subscriberAlarmMonitor;
+    vector<int64_t> activeConfigsBroadcast;
+
+    long timeBase1 = 1;
+    int broadcastCount = 0;
+    StatsLogProcessor processor(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor,
+            bucketStartTimeNs, [](const ConfigKey& key) { return true; },
+            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
+                    const vector<int64_t>& activeConfigs) {
+                broadcastCount++;
+                EXPECT_EQ(broadcastUid, uid);
+                activeConfigsBroadcast.clear();
+                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(),
+                        activeConfigs.begin(), activeConfigs.end());
+                return true;
+            });
+
+    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
+
+    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    auto& eventActivationMap = metricProducer->mEventActivationMap;
+    auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
+
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
+    // triggered by screen on event (tracker index 2).
+    EXPECT_EQ(eventActivationMap.size(), 2u);
+    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
+    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap.size(), 1u);
+    EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    std::unique_ptr<LogEvent> event;
+
+    event = CreateAppCrashEvent(111, bucketStartTimeNs + 5);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 0);
+
+    // Activated by battery save mode.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 1);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    // First processed event.
+    event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
+    processor.OnLogEvent(event.get());
+
+    // Activated by screen on event.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+                                          bucketStartTimeNs + 20);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    // 2nd processed event.
+    // The activation by screen_on event expires, but the one by battery save mode is still active.
+    event = CreateAppCrashEvent(333, bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    // No new broadcast since the config should still be active.
+    EXPECT_EQ(broadcastCount, 1);
+
+    // 3rd processed event.
+    event = CreateAppCrashEvent(444, bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
+    processor.OnLogEvent(event.get());
+
+    // All activations expired.
+    event = CreateAppCrashEvent(555, bucketStartTimeNs + NS_PER_SEC * 60 * 8);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    // New broadcast since the config is no longer active.
+    EXPECT_EQ(broadcastCount, 2);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    // Re-activate metric via screen on.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+                                          bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 3);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    // 4th processed event.
+    event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
+    processor.OnLogEvent(event.get());
+
+    // Re-enable battery saver mode activation.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 3);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    // 5th processed event.
+    event = CreateAppCrashEvent(777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
+    processor.OnLogEvent(event.get());
+
+    // Cancel battery saver mode activation.
+    event = CreateScreenBrightnessChangedEvent(64, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 3);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    // Screen-on activation expired.
+    event = CreateAppCrashEvent(888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    // New broadcast since the config is no longer active.
+    EXPECT_EQ(broadcastCount, 4);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    event = CreateAppCrashEvent(999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
+    processor.OnLogEvent(event.get());
+
+    // Re-enable battery saver mode activation.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 5);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    // Cancel battery saver mode activation.
+    event = CreateScreenBrightnessChangedEvent(140, bucketStartTimeNs + NS_PER_SEC * 60 * 16);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 6);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_TRUE(buffer.size() > 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStartEndTimestamp(&reports);
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(5, reports.reports(0).metrics(0).count_metrics().data_size());
+
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+    sortMetricDataByDimensionsValue(
+            reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(5, countMetrics.data_size());
+
+    auto data = countMetrics.data(0);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(1);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(2);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    // Partial bucket as metric is deactivated.
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(3);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
+              data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 13,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(4);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
+              data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 13,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+}
+
+TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations) {
+    auto config = CreateStatsdConfigWithTwoDeactivations();
+
+    int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
+    int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
+
+    int uid = 12345;
+    int64_t cfgId = 98765;
+    ConfigKey cfgKey(uid, cfgId);
+
+    sp<UidMap> m = new UidMap();
+    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> subscriberAlarmMonitor;
+    vector<int64_t> activeConfigsBroadcast;
+
+    long timeBase1 = 1;
+    int broadcastCount = 0;
+    StatsLogProcessor processor(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor,
+            bucketStartTimeNs, [](const ConfigKey& key) { return true; },
+            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
+                    const vector<int64_t>& activeConfigs) {
+                broadcastCount++;
+                EXPECT_EQ(broadcastUid, uid);
+                activeConfigsBroadcast.clear();
+                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(),
+                        activeConfigs.begin(), activeConfigs.end());
+                return true;
+            });
+
+    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
+
+    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    auto& eventActivationMap = metricProducer->mEventActivationMap;
+    auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
+
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
+    // triggered by screen on event (tracker index 2).
+    EXPECT_EQ(eventActivationMap.size(), 2u);
+    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
+    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap.size(), 2u);
+    EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
+    EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    std::unique_ptr<LogEvent> event;
+
+    event = CreateAppCrashEvent(111, bucketStartTimeNs + 5);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 0);
+
+    // Activated by battery save mode.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 1);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    // First processed event.
+    event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
+    processor.OnLogEvent(event.get());
+
+    // Activated by screen on event.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+                                          bucketStartTimeNs + 20);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    // 2nd processed event.
+    // The activation by screen_on event expires, but the one by battery save mode is still active.
+    event = CreateAppCrashEvent(333, bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    // No new broadcast since the config should still be active.
+    EXPECT_EQ(broadcastCount, 1);
+
+    // 3rd processed event.
+    event = CreateAppCrashEvent(444, bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
+    processor.OnLogEvent(event.get());
+
+    // All activations expired.
+    event = CreateAppCrashEvent(555, bucketStartTimeNs + NS_PER_SEC * 60 * 8);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    // New broadcast since the config is no longer active.
+    EXPECT_EQ(broadcastCount, 2);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    // Re-activate metric via screen on.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+                                          bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 3);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    // 4th processed event.
+    event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
+    processor.OnLogEvent(event.get());
+
+    // Re-enable battery saver mode activation.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 3);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    // 5th processed event.
+    event = CreateAppCrashEvent(777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
+    processor.OnLogEvent(event.get());
+
+    // Cancel battery saver mode and screen on activation.
+    event = CreateScreenBrightnessChangedEvent(64, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    // New broadcast since the config is no longer active.
+    EXPECT_EQ(broadcastCount, 4);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    // Screen-on activation expired.
+    event = CreateAppCrashEvent(888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 4);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    event = CreateAppCrashEvent(999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
+    processor.OnLogEvent(event.get());
+
+    // Re-enable battery saver mode activation.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 5);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    // Cancel battery saver mode and screen on activation.
+    event = CreateScreenBrightnessChangedEvent(140, bucketStartTimeNs + NS_PER_SEC * 60 * 16);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 6);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_TRUE(buffer.size() > 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStartEndTimestamp(&reports);
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(5, reports.reports(0).metrics(0).count_metrics().data_size());
+
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+    sortMetricDataByDimensionsValue(
+            reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(5, countMetrics.data_size());
+
+    auto data = countMetrics.data(0);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(1);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(2);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    // Partial bucket as metric is deactivated.
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(3);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
+              data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(4);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
+              data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+}
+
+TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations) {
+    auto config = CreateStatsdConfigWithTwoMetricsTwoDeactivations();
+
+    int64_t bucketStartTimeNs = NS_PER_SEC * 10; // 10 secs
+    int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000LL * 1000LL;
+
+    int uid = 12345;
+    int64_t cfgId = 98765;
+    ConfigKey cfgKey(uid, cfgId);
+
+    sp<UidMap> m = new UidMap();
+    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> subscriberAlarmMonitor;
+    vector<int64_t> activeConfigsBroadcast;
+
+    long timeBase1 = 1;
+    int broadcastCount = 0;
+    StatsLogProcessor processor(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor,
+            bucketStartTimeNs, [](const ConfigKey& key) { return true; },
+            [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
+                    const vector<int64_t>& activeConfigs) {
+                broadcastCount++;
+                EXPECT_EQ(broadcastUid, uid);
+                activeConfigsBroadcast.clear();
+                activeConfigsBroadcast.insert(activeConfigsBroadcast.end(),
+                        activeConfigs.begin(), activeConfigs.end());
+                return true;
+            });
+
+    processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
+
+    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
+    EXPECT_TRUE(metricsManager->isConfigValid());
+    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 2);
+    sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
+    auto& eventActivationMap = metricProducer->mEventActivationMap;
+    auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
+    sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[1];
+    auto& eventActivationMap2 = metricProducer2->mEventActivationMap;
+    auto& eventDeactivationMap2 = metricProducer2->mEventDeactivationMap;
+
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_FALSE(metricProducer2->mIsActive);
+    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
+    // triggered by screen on event (tracker index 2).
+    EXPECT_EQ(eventActivationMap.size(), 2u);
+    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
+    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap.size(), 2u);
+    EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
+    EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+
+    EXPECT_EQ(eventActivationMap2.size(), 2u);
+    EXPECT_TRUE(eventActivationMap2.find(0) != eventActivationMap2.end());
+    EXPECT_TRUE(eventActivationMap2.find(2) != eventActivationMap2.end());
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2.size(), 2u);
+    EXPECT_TRUE(eventDeactivationMap2.find(3) != eventDeactivationMap2.end());
+    EXPECT_TRUE(eventDeactivationMap2.find(4) != eventDeactivationMap2.end());
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    std::unique_ptr<LogEvent> event;
+
+    event = CreateAppCrashEvent(111, bucketStartTimeNs + 5);
+    processor.OnLogEvent(event.get());
+    event = CreateMoveToForegroundEvent(1111, bucketStartTimeNs + 5);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_FALSE(metricProducer2->mIsActive);
+    EXPECT_EQ(broadcastCount, 0);
+
+    // Activated by battery save mode.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_EQ(broadcastCount, 1);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_TRUE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, 0);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    // First processed event.
+    event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
+    processor.OnLogEvent(event.get());
+    event = CreateMoveToForegroundEvent(2222, bucketStartTimeNs + 15);
+    processor.OnLogEvent(event.get());
+
+    // Activated by screen on event.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+                                          bucketStartTimeNs + 20);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_TRUE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    // 2nd processed event.
+    // The activation by screen_on event expires, but the one by battery save mode is still active.
+    event = CreateAppCrashEvent(333, bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
+    processor.OnLogEvent(event.get());
+    event = CreateMoveToForegroundEvent(3333, bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_TRUE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+    // No new broadcast since the config should still be active.
+    EXPECT_EQ(broadcastCount, 1);
+
+    // 3rd processed event.
+    event = CreateAppCrashEvent(444, bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
+    processor.OnLogEvent(event.get());
+    event = CreateMoveToForegroundEvent(4444, bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
+    processor.OnLogEvent(event.get());
+
+    // All activations expired.
+    event = CreateAppCrashEvent(555, bucketStartTimeNs + NS_PER_SEC * 60 * 8);
+    processor.OnLogEvent(event.get());
+    event = CreateMoveToForegroundEvent(5555, bucketStartTimeNs + NS_PER_SEC * 60 * 8);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    // New broadcast since the config is no longer active.
+    EXPECT_EQ(broadcastCount, 2);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_FALSE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    // Re-activate metric via screen on.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+                                          bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_EQ(broadcastCount, 3);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_TRUE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    // 4th processed event.
+    event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
+    processor.OnLogEvent(event.get());
+    event = CreateMoveToForegroundEvent(6666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
+    processor.OnLogEvent(event.get());
+
+    // Re-enable battery saver mode activation.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_EQ(broadcastCount, 3);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_TRUE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    // 5th processed event.
+    event = CreateAppCrashEvent(777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
+    processor.OnLogEvent(event.get());
+    event = CreateMoveToForegroundEvent(7777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
+    processor.OnLogEvent(event.get());
+
+    // Cancel battery saver mode and screen on activation.
+    event = CreateScreenBrightnessChangedEvent(64, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 60);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    // New broadcast since the config is no longer active.
+    EXPECT_EQ(broadcastCount, 4);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_FALSE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    // Screen-on activation expired.
+    event = CreateAppCrashEvent(888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
+    processor.OnLogEvent(event.get());
+    event = CreateMoveToForegroundEvent(8888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_EQ(broadcastCount, 4);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_FALSE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    event = CreateAppCrashEvent(999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
+    processor.OnLogEvent(event.get());
+    event = CreateMoveToForegroundEvent(9999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
+    processor.OnLogEvent(event.get());
+
+    // Re-enable battery saver mode activation.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_EQ(broadcastCount, 5);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_TRUE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    // Cancel battery saver mode and screen on activation.
+    event = CreateScreenBrightnessChangedEvent(140, bucketStartTimeNs + NS_PER_SEC * 60 * 16);
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_EQ(broadcastCount, 6);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4], eventActivationMap[2]);
+    EXPECT_FALSE(metricProducer2->mIsActive);
+    EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[0]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
+    EXPECT_EQ(eventActivationMap2[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap2[2]->activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
+    EXPECT_EQ(eventDeactivationMap2[3], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4], eventActivationMap2[2]);
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor.onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_TRUE(buffer.size() > 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStartEndTimestamp(&reports);
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(2, reports.reports(0).metrics_size());
+    EXPECT_EQ(5, reports.reports(0).metrics(0).count_metrics().data_size());
+    EXPECT_EQ(5, reports.reports(0).metrics(1).count_metrics().data_size());
+
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+
+    sortMetricDataByDimensionsValue(
+            reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(5, countMetrics.data_size());
+
+    auto data = countMetrics.data(0);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(1);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(2);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    // Partial bucket as metric is deactivated.
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(3);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
+              data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(4);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
+              data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+
+   countMetrics.clear_data();
+    sortMetricDataByDimensionsValue(
+            reports.reports(0).metrics(1).count_metrics(), &countMetrics);
+    EXPECT_EQ(5, countMetrics.data_size());
+
+    data = countMetrics.data(0);
+    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(2222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(1);
+    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(3333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(2);
+    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(4444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    // Partial bucket as metric is deactivated.
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(3);
+    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(6666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
+              data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(4);
+    EXPECT_EQ(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(7777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
+              data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 11,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+}
 
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index 3dff7f5..309d251 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -111,7 +111,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     SendConfig(service, MakeConfig());
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
@@ -126,7 +126,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     SendConfig(service, MakeConfig());
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
@@ -146,7 +146,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     SendConfig(service, MakeConfig());
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
@@ -171,7 +171,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     SendConfig(service, MakeConfig());
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
@@ -195,7 +195,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     // Partial buckets don't occur when app is first installed.
     service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
     SendConfig(service, MakeValueMetricConfig(0));
@@ -213,7 +213,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     // Partial buckets don't occur when app is first installed.
     service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
     SendConfig(service, MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */));
@@ -237,7 +237,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     // Partial buckets don't occur when app is first installed.
     service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
     SendConfig(service, MakeGaugeMetricConfig(0));
@@ -255,7 +255,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) {
-    StatsService service(nullptr);
+    StatsService service(nullptr, nullptr);
     // Partial buckets don't occur when app is first installed.
     service.mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""));
     SendConfig(service, MakeGaugeMetricConfig(60 * NS_PER_SEC /* One minute */));
diff --git a/cmds/statsd/tests/external/IncidentReportArgs_test.cpp b/cmds/statsd/tests/external/IncidentReportArgs_test.cpp
index c170b12..38bc194 100644
--- a/cmds/statsd/tests/external/IncidentReportArgs_test.cpp
+++ b/cmds/statsd/tests/external/IncidentReportArgs_test.cpp
@@ -36,7 +36,7 @@
     args.addHeader(header1);
     args.addHeader(header2);
 
-    args.setDest(1);
+    args.setPrivacyPolicy(1);
 
     args.setReceiverPkg("com.android.os");
     args.setReceiverCls("com.android.os.Receiver");
@@ -56,10 +56,10 @@
     sections.insert(1000);
     sections.insert(1001);
     EXPECT_EQ(sections, args2.sections());
-    EXPECT_EQ(1, args2.dest());
+    EXPECT_EQ(1, args2.getPrivacyPolicy());
 
-    EXPECT_EQ(String16("com.android.os"), args2.receiverPkg());
-    EXPECT_EQ(String16("com.android.os.Receiver"), args2.receiverCls());
+    EXPECT_EQ(string("com.android.os"), args2.receiverPkg());
+    EXPECT_EQ(string("com.android.os.Receiver"), args2.receiverCls());
 
     vector<vector<uint8_t>> headers;
     headers.push_back(header1);
@@ -69,4 +69,4 @@
 
 }  // namespace statsd
 }  // namespace os
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp b/cmds/statsd/tests/log_event/LogEventQueue_test.cpp
new file mode 100644
index 0000000..f27d129
--- /dev/null
+++ b/cmds/statsd/tests/log_event/LogEventQueue_test.cpp
@@ -0,0 +1,100 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "logd/LogEventQueue.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <thread>
+
+#include <stdio.h>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+using namespace android;
+using namespace testing;
+
+using std::unique_ptr;
+
+#ifdef __ANDROID__
+TEST(LogEventQueue_test, TestGoodConsumer) {
+    LogEventQueue queue(50);
+    int64_t timeBaseNs = 100;
+    std::thread writer([&queue, timeBaseNs] {
+        for (int i = 0; i < 100; i++) {
+            int64_t oldestEventNs;
+            bool success = queue.push(std::make_unique<LogEvent>(10, timeBaseNs + i * 1000),
+                                      &oldestEventNs);
+            EXPECT_TRUE(success);
+            std::this_thread::sleep_for(std::chrono::milliseconds(1));
+        }
+    });
+
+    std::thread reader([&queue, timeBaseNs] {
+        for (int i = 0; i < 100; i++) {
+            auto event = queue.waitPop();
+            EXPECT_TRUE(event != nullptr);
+            // All events are in right order.
+            EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs());
+        }
+    });
+
+    reader.join();
+    writer.join();
+}
+
+TEST(LogEventQueue_test, TestSlowConsumer) {
+    LogEventQueue queue(50);
+    int64_t timeBaseNs = 100;
+    std::thread writer([&queue, timeBaseNs] {
+        int failure_count = 0;
+        int64_t oldestEventNs;
+        for (int i = 0; i < 100; i++) {
+            bool success = queue.push(std::make_unique<LogEvent>(10, timeBaseNs + i * 1000),
+                                      &oldestEventNs);
+            if (!success) failure_count++;
+            std::this_thread::sleep_for(std::chrono::milliseconds(1));
+        }
+
+        // There is some remote chance that reader thread not get chance to run before writer thread
+        // ends. That's why the following comparison is not "==".
+        // There will be at least 45 events lost due to overflow.
+        EXPECT_TRUE(failure_count >= 45);
+        // The oldest event must be at least the 6th event.
+        EXPECT_TRUE(oldestEventNs <= (100 + 5 * 1000));
+    });
+
+    std::thread reader([&queue, timeBaseNs] {
+        // The consumer quickly processed 5 events, then it got stuck (not reading anymore).
+        for (int i = 0; i < 5; i++) {
+            auto event = queue.waitPop();
+            EXPECT_TRUE(event != nullptr);
+            // All events are in right order.
+            EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs());
+        }
+    });
+
+    reader.join();
+    writer.join();
+}
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 90b9e81..afa05a9 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -26,6 +26,7 @@
 
 using namespace testing;
 using android::sp;
+using android::util::ProtoReader;
 using std::make_shared;
 using std::set;
 using std::shared_ptr;
@@ -2730,12 +2731,12 @@
     vector<uint8_t> bytes;
     bytes.resize(proto->size());
     size_t pos = 0;
-    auto iter = proto->data();
-    while (iter.readBuffer() != NULL) {
-        size_t toRead = iter.currentToRead();
-        std::memcpy(&((bytes)[pos]), iter.readBuffer(), toRead);
+    sp<ProtoReader> reader = proto->data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
         pos += toRead;
-        iter.rp()->move(toRead);
+        reader->move(toRead);
     }
 
     StatsLogReport report;
diff --git a/config/hiddenapi-greylist-packages.txt b/config/hiddenapi-greylist-packages.txt
new file mode 100644
index 0000000..cae3bd9
--- /dev/null
+++ b/config/hiddenapi-greylist-packages.txt
@@ -0,0 +1,2 @@
+org.ccil.cowan.tagsoup
+org.ccil.cowan.tagsoup.jaxp
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 95bdc36..c267e77 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -2488,108 +2488,3 @@
 Lorg/apache/xpath/XPathContext;->setCurrentNodeStack(Lorg/apache/xml/utils/IntStack;)V
 Lorg/apache/xpath/XPathContext;->setSecureProcessing(Z)V
 Lorg/apache/xpath/XPathContext;->setVarStack(Lorg/apache/xpath/VariableStack;)V
-Lorg/ccil/cowan/tagsoup/AttributesImpl;-><init>(Lorg/xml/sax/Attributes;)V
-Lorg/ccil/cowan/tagsoup/AttributesImpl;->addAttribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
-Lorg/ccil/cowan/tagsoup/AttributesImpl;->data:[Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/AttributesImpl;->length:I
-Lorg/ccil/cowan/tagsoup/AttributesImpl;->setAttribute(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
-Lorg/ccil/cowan/tagsoup/AttributesImpl;->setValue(ILjava/lang/String;)V
-Lorg/ccil/cowan/tagsoup/AutoDetector;->autoDetectingReader(Ljava/io/InputStream;)Ljava/io/Reader;
-Lorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V
-Lorg/ccil/cowan/tagsoup/Element;->anonymize()V
-Lorg/ccil/cowan/tagsoup/Element;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl;
-Lorg/ccil/cowan/tagsoup/Element;->canContain(Lorg/ccil/cowan/tagsoup/Element;)Z
-Lorg/ccil/cowan/tagsoup/Element;->clean()V
-Lorg/ccil/cowan/tagsoup/Element;->flags()I
-Lorg/ccil/cowan/tagsoup/Element;->localName()Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Element;->name()Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Element;->namespace()Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Element;->next()Lorg/ccil/cowan/tagsoup/Element;
-Lorg/ccil/cowan/tagsoup/Element;->parent()Lorg/ccil/cowan/tagsoup/ElementType;
-Lorg/ccil/cowan/tagsoup/Element;->preclosed:Z
-Lorg/ccil/cowan/tagsoup/Element;->setAttribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
-Lorg/ccil/cowan/tagsoup/Element;->setNext(Lorg/ccil/cowan/tagsoup/Element;)V
-Lorg/ccil/cowan/tagsoup/Element;->theAtts:Lorg/ccil/cowan/tagsoup/AttributesImpl;
-Lorg/ccil/cowan/tagsoup/Element;->theNext:Lorg/ccil/cowan/tagsoup/Element;
-Lorg/ccil/cowan/tagsoup/Element;->theType:Lorg/ccil/cowan/tagsoup/ElementType;
-Lorg/ccil/cowan/tagsoup/ElementType;-><init>(Ljava/lang/String;IIILorg/ccil/cowan/tagsoup/Schema;)V
-Lorg/ccil/cowan/tagsoup/ElementType;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl;
-Lorg/ccil/cowan/tagsoup/ElementType;->setAttribute(Lorg/ccil/cowan/tagsoup/AttributesImpl;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
-Lorg/ccil/cowan/tagsoup/ElementType;->theAtts:Lorg/ccil/cowan/tagsoup/AttributesImpl;
-Lorg/ccil/cowan/tagsoup/ElementType;->theFlags:I
-Lorg/ccil/cowan/tagsoup/ElementType;->theLocalName:Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/ElementType;->theMemberOf:I
-Lorg/ccil/cowan/tagsoup/ElementType;->theModel:I
-Lorg/ccil/cowan/tagsoup/ElementType;->theName:Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/ElementType;->theNamespace:Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/ElementType;->theParent:Lorg/ccil/cowan/tagsoup/ElementType;
-Lorg/ccil/cowan/tagsoup/ElementType;->theSchema:Lorg/ccil/cowan/tagsoup/Schema;
-Lorg/ccil/cowan/tagsoup/HTMLScanner;-><init>()V
-Lorg/ccil/cowan/tagsoup/HTMLSchema;-><init>()V
-Lorg/ccil/cowan/tagsoup/jaxp/SAXFactoryImpl;-><init>()V
-Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;-><init>()V
-Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;->newInstance(Ljava/util/Map;)Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;
-Lorg/ccil/cowan/tagsoup/Parser;-><init>()V
-Lorg/ccil/cowan/tagsoup/Parser;->bogonsEmpty:Z
-Lorg/ccil/cowan/tagsoup/Parser;->CDATAElements:Z
-Lorg/ccil/cowan/tagsoup/Parser;->cleanPublicid(Ljava/lang/String;)Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Parser;->defaultAttributes:Z
-Lorg/ccil/cowan/tagsoup/Parser;->etagchars:[C
-Lorg/ccil/cowan/tagsoup/Parser;->expandEntities(Ljava/lang/String;)Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Parser;->getInputStream(Ljava/lang/String;Ljava/lang/String;)Ljava/io/InputStream;
-Lorg/ccil/cowan/tagsoup/Parser;->ignorableWhitespace:Z
-Lorg/ccil/cowan/tagsoup/Parser;->ignoreBogons:Z
-Lorg/ccil/cowan/tagsoup/Parser;->lookupEntity([CII)I
-Lorg/ccil/cowan/tagsoup/Parser;->makeName([CII)Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Parser;->pop()V
-Lorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V
-Lorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V
-Lorg/ccil/cowan/tagsoup/Parser;->restart(Lorg/ccil/cowan/tagsoup/Element;)V
-Lorg/ccil/cowan/tagsoup/Parser;->restartablyPop()V
-Lorg/ccil/cowan/tagsoup/Parser;->rootBogons:Z
-Lorg/ccil/cowan/tagsoup/Parser;->schemaProperty:Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Parser;->split(Ljava/lang/String;)[Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Parser;->theAttributeName:Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Parser;->theAutoDetector:Lorg/ccil/cowan/tagsoup/AutoDetector;
-Lorg/ccil/cowan/tagsoup/Parser;->theContentHandler:Lorg/xml/sax/ContentHandler;
-Lorg/ccil/cowan/tagsoup/Parser;->theDoctypeIsPresent:Z
-Lorg/ccil/cowan/tagsoup/Parser;->theDoctypeSystemId:Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Parser;->theFeatures:Ljava/util/HashMap;
-Lorg/ccil/cowan/tagsoup/Parser;->theLexicalHandler:Lorg/xml/sax/ext/LexicalHandler;
-Lorg/ccil/cowan/tagsoup/Parser;->theNewElement:Lorg/ccil/cowan/tagsoup/Element;
-Lorg/ccil/cowan/tagsoup/Parser;->thePCDATA:Lorg/ccil/cowan/tagsoup/Element;
-Lorg/ccil/cowan/tagsoup/Parser;->thePITarget:Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Parser;->theSaved:Lorg/ccil/cowan/tagsoup/Element;
-Lorg/ccil/cowan/tagsoup/Parser;->theScanner:Lorg/ccil/cowan/tagsoup/Scanner;
-Lorg/ccil/cowan/tagsoup/Parser;->theSchema:Lorg/ccil/cowan/tagsoup/Schema;
-Lorg/ccil/cowan/tagsoup/Parser;->theStack:Lorg/ccil/cowan/tagsoup/Element;
-Lorg/ccil/cowan/tagsoup/Parser;->trimquotes(Ljava/lang/String;)Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Parser;->virginStack:Z
-Lorg/ccil/cowan/tagsoup/PYXScanner;-><init>()V
-Lorg/ccil/cowan/tagsoup/PYXWriter;-><init>(Ljava/io/Writer;)V
-Lorg/ccil/cowan/tagsoup/ScanHandler;->aname([CII)V
-Lorg/ccil/cowan/tagsoup/ScanHandler;->aval([CII)V
-Lorg/ccil/cowan/tagsoup/ScanHandler;->entity([CII)V
-Lorg/ccil/cowan/tagsoup/ScanHandler;->eof([CII)V
-Lorg/ccil/cowan/tagsoup/ScanHandler;->etag([CII)V
-Lorg/ccil/cowan/tagsoup/ScanHandler;->gi([CII)V
-Lorg/ccil/cowan/tagsoup/ScanHandler;->pcdata([CII)V
-Lorg/ccil/cowan/tagsoup/ScanHandler;->pi([CII)V
-Lorg/ccil/cowan/tagsoup/ScanHandler;->stagc([CII)V
-Lorg/ccil/cowan/tagsoup/Scanner;->startCDATA()V
-Lorg/ccil/cowan/tagsoup/Schema;->elementType(Ljava/lang/String;III)V
-Lorg/ccil/cowan/tagsoup/Schema;->getElementType(Ljava/lang/String;)Lorg/ccil/cowan/tagsoup/ElementType;
-Lorg/ccil/cowan/tagsoup/Schema;->getEntity(Ljava/lang/String;)I
-Lorg/ccil/cowan/tagsoup/Schema;->getPrefix()Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Schema;->getURI()Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Schema;->parent(Ljava/lang/String;Ljava/lang/String;)V
-Lorg/ccil/cowan/tagsoup/Schema;->theElementTypes:Ljava/util/HashMap;
-Lorg/ccil/cowan/tagsoup/Schema;->theEntities:Ljava/util/HashMap;
-Lorg/ccil/cowan/tagsoup/Schema;->thePrefix:Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/Schema;->theRoot:Lorg/ccil/cowan/tagsoup/ElementType;
-Lorg/ccil/cowan/tagsoup/Schema;->theURI:Ljava/lang/String;
-Lorg/ccil/cowan/tagsoup/XMLWriter;-><init>(Ljava/io/Writer;)V
-Lorg/ccil/cowan/tagsoup/XMLWriter;->htmlMode:Z
-Lorg/ccil/cowan/tagsoup/XMLWriter;->setOutput(Ljava/io/Writer;)V
-Lorg/ccil/cowan/tagsoup/XMLWriter;->setOutputProperty(Ljava/lang/String;Ljava/lang/String;)V
-Lorg/ccil/cowan/tagsoup/XMLWriter;->setPrefix(Ljava/lang/String;Ljava/lang/String;)V
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b039a60..883bcb8 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -157,8 +157,9 @@
  * creating a window for you in which you can place your UI with
  * {@link #setContentView}.  While activities are often presented to the user
  * as full-screen windows, they can also be used in other ways: as floating
- * windows (via a theme with {@link android.R.attr#windowIsFloating} set)
- * or embedded inside of another activity (using {@link ActivityGroup}).
+ * windows (via a theme with {@link android.R.attr#windowIsFloating} set),
+ * <a href="https://developer.android.com/guide/topics/ui/multi-window">
+ * Multi-Window mode</a> or embedded into other windows.
  *
  * There are two methods almost all subclasses of Activity will implement:
  *
@@ -169,10 +170,11 @@
  *     to retrieve the widgets in that UI that you need to interact with
  *     programmatically.
  *
- *     <li> {@link #onPause} is where you deal with the user leaving your
- *     activity.  Most importantly, any changes made by the user should at this
- *     point be committed (usually to the
- *     {@link android.content.ContentProvider} holding the data).
+ *     <li> {@link #onPause} is where you deal with the user pausing active
+ *     interaction with the activity. Any changes made by the user should at
+ *     this point be committed (usually to the
+ *     {@link android.content.ContentProvider} holding the data). In this
+ *     state the activity is still visible on screen.
  * </ul>
  *
  * <p>To be of use with {@link android.content.Context#startActivity Context.startActivity()}, all
@@ -220,32 +222,31 @@
  * <a name="ActivityLifecycle"></a>
  * <h3>Activity Lifecycle</h3>
  *
- * <p>Activities in the system are managed as an <em>activity stack</em>.
- * When a new activity is started, it is placed on the top of the stack
- * and becomes the running activity -- the previous activity always remains
+ * <p>Activities in the system are managed as
+ * <a href="https://developer.android.com/guide/components/activities/tasks-and-back-stack">
+ * activity stacks</a>. When a new activity is started, it is usually placed on the top of the
+ * current stack and becomes the running activity -- the previous activity always remains
  * below it in the stack, and will not come to the foreground again until
- * the new activity exits.</p>
+ * the new activity exits. There can be one or multiple activity stacks visible
+ * on screen.</p>
  *
  * <p>An activity has essentially four states:</p>
  * <ul>
- *     <li> If an activity is in the foreground of the screen (at the top of
- *         the stack),
- *         it is <em>active</em> or  <em>running</em>. </li>
- *     <li>If an activity has lost focus but is still visible (that is, a new non-full-sized
- *         or transparent activity has focus on top of your activity), it
- *         is <em>paused</em>. A paused activity is completely alive (it
- *         maintains all state and member information and remains attached to
- *         the window manager), but can be killed by the system in extreme
- *         low memory situations.
+ *     <li>If an activity is in the foreground of the screen (at the highest position of the topmost
+ *         stack), it is <em>active</em> or <em>running</em>. This is usually the activity that the
+ *         user is currently interacting with.</li>
+ *     <li>If an activity has lost focus but is still presented to the user, it is <em>visible</em>.
+ *         It is possible if a new non-full-sized or transparent activity has focus on top of your
+ *         activity, another activity has higher position in multi-window mode, or the activity
+ *         itself is not focusable in current windowing mode. Such activity is completely alive (it
+ *         maintains all state and member information and remains attached to the window manager).
  *     <li>If an activity is completely obscured by another activity,
- *         it is <em>stopped</em>. It still retains all state and member information,
- *         however, it is no longer visible to the user so its window is hidden
- *         and it will often be killed by the system when memory is needed
- *         elsewhere.</li>
- *     <li>If an activity is paused or stopped, the system can drop the activity
- *         from memory by either asking it to finish, or simply killing its
- *         process.  When it is displayed again to the user, it must be
- *         completely restarted and restored to its previous state.</li>
+ *         it is <em>stopped</em> or <em>hidden</em>. It still retains all state and member
+ *         information, however, it is no longer visible to the user so its window is hidden
+ *         and it will often be killed by the system when memory is needed elsewhere.</li>
+ *     <li>The system can drop the activity from memory by either asking it to finish,
+ *         or simply killing its process, making it <em>destroyed</em>. When it is displayed again
+ *         to the user, it must be completely restarted and restored to its previous state.</li>
  * </ul>
  *
  * <p>The following diagram shows the important state paths of an Activity.
@@ -283,7 +284,7 @@
  * <li>The <b>foreground lifetime</b> of an activity happens between a call to
  * {@link android.app.Activity#onResume} until a corresponding call to
  * {@link android.app.Activity#onPause}.  During this time the activity is
- * in front of all other activities and interacting with the user.  An activity
+ * in visible, active and interacting with the user.  An activity
  * can frequently go between the resumed and paused states -- for example when
  * the device goes to sleep, when an activity result is delivered, when a new
  * intent is delivered -- so the code in these methods should be fairly
@@ -296,7 +297,8 @@
  * activities will implement {@link android.app.Activity#onCreate}
  * to do their initial setup; many will also implement
  * {@link android.app.Activity#onPause} to commit changes to data and
- * otherwise prepare to stop interacting with the user.  You should always
+ * prepare to pause interacting with the user, and {@link android.app.Activity#onStop}
+ * to handle no longer being visible on screen. You should always
  * call up to your superclass when implementing these methods.</p>
  *
  * </p>
@@ -364,17 +366,17 @@
  *         <td align="left" border="0">{@link android.app.Activity#onResume onResume()}</td>
  *         <td>Called when the activity will start
  *             interacting with the user.  At this point your activity is at
- *             the top of the activity stack, with user input going to it.
+ *             the top of its activity stack, with user input going to it.
  *             <p>Always followed by <code>onPause()</code>.</td>
  *         <td align="center">No</td>
  *         <td align="center"><code>onPause()</code></td>
  *     </tr>
  *
  *     <tr><td align="left" border="0">{@link android.app.Activity#onPause onPause()}</td>
- *         <td>Called when the system is about to start resuming a previous
- *             activity.  This is typically used to commit unsaved changes to
- *             persistent data, stop animations and other things that may be consuming
- *             CPU, etc.  Implementations of this method must be very quick because
+ *         <td>Called when the activity loses foreground state, is no longer focusable or before
+ *             transition to stopped/hidden or destroyed state. The activity is still visible to
+ *             user, so it's recommended to keep it visually active and continue updating the UI.
+ *             Implementations of this method must be very quick because
  *             the next activity will not be resumed until this method returns.
  *             <p>Followed by either <code>onResume()</code> if the activity
  *             returns back to the front, or <code>onStop()</code> if it becomes
@@ -385,11 +387,10 @@
  *     </tr>
  *
  *     <tr><td colspan="2" align="left" border="0">{@link android.app.Activity#onStop onStop()}</td>
- *         <td>Called when the activity is no longer visible to the user, because
- *             another activity has been resumed and is covering this one.  This
- *             may happen either because a new activity is being started, an existing
- *             one is being brought in front of this one, or this one is being
- *             destroyed.
+ *         <td>Called when the activity is no longer visible to the user.  This may happen either
+ *             because a new activity is being started on top, an existing one is being brought in
+ *             front of this one, or this one is being destroyed. This is typically used to stop
+ *             animations and refreshing the UI, etc.
  *             <p>Followed by either <code>onRestart()</code> if
  *             this activity is coming back to interact with the user, or
  *             <code>onDestroy()</code> if this activity is going away.</td>
@@ -446,8 +447,9 @@
  * <p>For those methods that are not marked as being killable, the activity's
  * process will not be killed by the system starting from the time the method
  * is called and continuing after it returns.  Thus an activity is in the killable
- * state, for example, between after <code>onPause()</code> to the start of
- * <code>onResume()</code>.</p>
+ * state, for example, between after <code>onStop()</code> to the start of
+ * <code>onResume()</code>. Keep in mind that under extreme memory pressure the
+ * system can kill the application process at any time.</p>
  *
  * <a name="ConfigurationChanges"></a>
  * <h3>Configuration Changes</h3>
@@ -582,8 +584,8 @@
  * <p>This model is designed to prevent data loss when a user is navigating
  * between activities, and allows the system to safely kill an activity (because
  * system resources are needed somewhere else) at any time after it has been
- * paused.  Note this implies
- * that the user pressing BACK from your activity does <em>not</em>
+ * stopped (or paused on platform versions before {@link android.os.Build.VERSION_CODES#HONEYCOMB}).
+ * Note this implies that the user pressing BACK from your activity does <em>not</em>
  * mean "cancel" -- it means to leave the activity with its current contents
  * saved away.  Canceling edits in an activity must be provided through
  * some other mechanism, such as an explicit "revert" or "undo" option.</p>
@@ -684,11 +686,12 @@
  * reached a memory paging state, so this is required in order to keep the user
  * interface responsive.
  * <li> <p>A <b>visible activity</b> (an activity that is visible to the user
- * but not in the foreground, such as one sitting behind a foreground dialog)
+ * but not in the foreground, such as one sitting behind a foreground dialog
+ * or next to other activities in multi-window mode)
  * is considered extremely important and will not be killed unless that is
  * required to keep the foreground activity running.
  * <li> <p>A <b>background activity</b> (an activity that is not visible to
- * the user and has been paused) is no longer critical, so the system may
+ * the user and has been stopped) is no longer critical, so the system may
  * safely kill its process to reclaim memory for other foreground or
  * visible processes.  If its process needs to be killed, when the user navigates
  * back to the activity (making it visible on the screen again), its
@@ -1685,7 +1688,12 @@
     /**
      * Called after {@link #onCreate} &mdash; or after {@link #onRestart} when
      * the activity had been stopped, but is now again being displayed to the
-     * user.  It will be followed by {@link #onResume}.
+     * user. It will usually be followed by {@link #onResume}. This is a good place to begin
+     * drawing visual elements, running animations, etc.
+     *
+     * <p>You can call {@link #finish} from within this function, in
+     * which case {@link #onStop} will be immediately called after {@link #onStart} without the
+     * lifecycle transitions in-between ({@link #onResume}, {@link #onPause}, etc) executing.
      *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
@@ -1751,14 +1759,15 @@
 
     /**
      * Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or
-     * {@link #onPause}, for your activity to start interacting with the user.
-     * This is a good place to begin animations, open exclusive-access devices
-     * (such as the camera), etc.
+     * {@link #onPause}, for your activity to start interacting with the user. This is an indicator
+     * that the activity became active and ready to receive input. It is on top of an activity stack
+     * and visible to user.
      *
-     * <p>Keep in mind that onResume is not the best indicator that your activity
-     * is visible to the user; a system window such as the keyguard may be in
-     * front.  Use {@link #onWindowFocusChanged} to know for certain that your
-     * activity is visible to the user (for example, to resume a game).
+     * <p>On platform versions prior to {@link android.os.Build.VERSION_CODES#Q} this is also a good
+     * place to try to open exclusive-access devices or to get access to singleton resources.
+     * Starting  with {@link android.os.Build.VERSION_CODES#Q} there can be multiple resumed
+     * activities in the system simultaneously, so {@link #onTopResumedActivityChanged(boolean)}
+     * should be used for that purpose instead.
      *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
@@ -1768,6 +1777,7 @@
      * @see #onRestart
      * @see #onPostResume
      * @see #onPause
+     * @see #onTopResumedActivityChanged(boolean)
      */
     @CallSuper
     protected void onResume() {
@@ -1816,7 +1826,7 @@
     }
 
     /**
-     * Called when activity gets or looses the top resumed position in the system.
+     * Called when activity gets or loses the top resumed position in the system.
      *
      * <p>Starting with {@link android.os.Build.VERSION_CODES#Q} multiple activities can be resumed
      * at the same time in multi-window and multi-display modes. This callback should be used
@@ -1981,8 +1991,12 @@
      * called on the existing instance with the Intent that was used to
      * re-launch it.
      *
-     * <p>An activity will always be paused before receiving a new intent, so
-     * you can count on {@link #onResume} being called after this method.
+     * <p>An activity can never receive a new intent in the resumed state. You can count on
+     * {@link #onResume} being called after this method, though not necessarily immediately after
+     * the completion this callback. If the activity was resumed, it will be paused and new intent
+     * will be delivered, followed by {@link #onResume}. If the activity wasn't in the resumed
+     * state, then new intent can be delivered immediately, with {@link #onResume()} called
+     * sometime later when activity becomes active again.
      *
      * <p>Note that {@link #getIntent} still returns the original Intent.  You
      * can use {@link #setIntent} to update it to this new Intent.
@@ -2048,14 +2062,13 @@
      * returns to activity A, the state of the user interface can be restored
      * via {@link #onCreate} or {@link #onRestoreInstanceState}.
      *
-     * <p>Do not confuse this method with activity lifecycle callbacks such as
-     * {@link #onPause}, which is always called when an activity is being placed
-     * in the background or on its way to destruction, or {@link #onStop} which
-     * is called before destruction.  One example of when {@link #onPause} and
-     * {@link #onStop} is called and not this method is when a user navigates back
-     * from activity B to activity A: there is no need to call {@link #onSaveInstanceState}
-     * on B because that particular instance will never be restored, so the
-     * system avoids calling it.  An example when {@link #onPause} is called and
+     * <p>Do not confuse this method with activity lifecycle callbacks such as {@link #onPause},
+     * which is always called when the user no longer actively interacts with an activity, or
+     * {@link #onStop} which is called when activity becomes invisible. One example of when
+     * {@link #onPause} and {@link #onStop} is called and not this method is when a user navigates
+     * back from activity B to activity A: there is no need to call {@link #onSaveInstanceState}
+     * on B because that particular instance will never be restored,
+     * so the system avoids calling it.  An example when {@link #onPause} is called and
      * not {@link #onSaveInstanceState} is when activity B is launched in front of activity A:
      * the system may avoid calling {@link #onSaveInstanceState} on activity A if it isn't
      * killed during the lifetime of B since the state of the user interface of
@@ -2154,9 +2167,8 @@
 
 
     /**
-     * Called as part of the activity lifecycle when an activity is going into
-     * the background, but has not (yet) been killed.  The counterpart to
-     * {@link #onResume}.
+     * Called as part of the activity lifecycle when the user no longer actively interacts with the
+     * activity, but it is still visible on screen. The counterpart to {@link #onResume}.
      *
      * <p>When activity B is launched in front of activity A, this callback will
      * be invoked on A.  B will not be created until A's {@link #onPause} returns,
@@ -2166,22 +2178,20 @@
      * activity is editing, to present a "edit in place" model to the user and
      * making sure nothing is lost if there are not enough resources to start
      * the new activity without first killing this one.  This is also a good
-     * place to do things like stop animations and other things that consume a
-     * noticeable amount of CPU in order to make the switch to the next activity
-     * as fast as possible, or to close resources that are exclusive access
-     * such as the camera.
+     * place to stop things that consume a noticeable amount of CPU in order to
+     * make the switch to the next activity as fast as possible.
      *
-     * <p>In situations where the system needs more memory it may kill paused
-     * processes to reclaim resources.  Because of this, you should be sure
-     * that all of your state is saved by the time you return from
-     * this function.  In general {@link #onSaveInstanceState} is used to save
-     * per-instance state in the activity and this method is used to store
-     * global persistent data (in content providers, files, etc.)
+     * <p>On platform versions prior to {@link android.os.Build.VERSION_CODES#Q} this is also a good
+     * place to try to close exclusive-access devices or to release access to singleton resources.
+     * Starting with {@link android.os.Build.VERSION_CODES#Q} there can be multiple resumed
+     * activities in the system at the same time, so {@link #onTopResumedActivityChanged(boolean)}
+     * should be used for that purpose instead.
      *
-     * <p>After receiving this call you will usually receive a following call
-     * to {@link #onStop} (after the next activity has been resumed and
-     * displayed), however in some cases there will be a direct call back to
-     * {@link #onResume} without going through the stopped state.
+     * <p>If an activity is launched on top, after receiving this call you will usually receive a
+     * following call to {@link #onStop} (after the next activity has been resumed and displayed
+     * above). However in some cases there will be a direct call back to {@link #onResume} without
+     * going through the stopped state. An activity can also rest in paused state in some cases when
+     * in multi-window mode, still visible to user.
      *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
@@ -2364,7 +2374,8 @@
     /**
      * Called when you are no longer visible to the user.  You will next
      * receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
-     * depending on later user activity.
+     * depending on later user activity. This is a good place to stop
+     * refreshing UI, running animations and other visual things.
      *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
@@ -3716,18 +3727,18 @@
 
     /**
      * Called when the current {@link Window} of the activity gains or loses
-     * focus.  This is the best indicator of whether this activity is visible
-     * to the user.  The default implementation clears the key tracking
-     * state, so should always be called.
+     * focus. This is the best indicator of whether this activity is the entity
+     * with which the user actively interacts. The default implementation
+     * clears the key tracking state, so should always be called.
      *
      * <p>Note that this provides information about global focus state, which
-     * is managed independently of activity lifecycles.  As such, while focus
+     * is managed independently of activity lifecycle.  As such, while focus
      * changes will generally have some relation to lifecycle changes (an
      * activity that is stopped will not generally get window focus), you
      * should not rely on any particular order between the callbacks here and
      * those in the other lifecycle methods such as {@link #onResume}.
      *
-     * <p>As a general rule, however, a resumed activity will have window
+     * <p>As a general rule, however, a foreground activity will have window
      * focus...  unless it has displayed other dialogs or popups that take
      * input focus, in which case the activity itself will not have focus
      * when the other windows have it.  Likewise, the system may display
@@ -3735,11 +3746,24 @@
      * a system alert) which will temporarily take window input focus without
      * pausing the foreground activity.
      *
+     * <p>Starting with {@link android.os.Build.VERSION_CODES#Q} there can be
+     * multiple resumed activities at the same time in multi-window mode, so
+     * resumed state does not guarantee window focus even if there are no
+     * overlays above.
+     *
+     * <p>If the intent is to know when an activity is the topmost active, the
+     * one the user interacted with last among all activities but not including
+     * non-activity windows like dialogs and popups, then
+     * {@link #onTopResumedActivityChanged(boolean)} should be used. On platform
+     * versions prior to {@link android.os.Build.VERSION_CODES#Q},
+     * {@link #onResume} is the best indicator.
+     *
      * @param hasFocus Whether the window of this activity has focus.
      *
      * @see #hasWindowFocus()
      * @see #onResume
      * @see View#onWindowFocusChanged(boolean)
+     * @see #onTopResumedActivityChanged(boolean)
      */
     public void onWindowFocusChanged(boolean hasFocus) {
     }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 023371d..395c867 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -513,71 +513,75 @@
     /** @hide Process is hosting a foreground service with location type. */
     public static final int PROCESS_STATE_FOREGROUND_SERVICE_LOCATION = 3;
 
+    /** @hide Process is bound to a TOP app. This is ranked below SERVICE_LOCATION so that
+     * it doesn't get the capability of location access while-in-use. */
+    public static final int PROCESS_STATE_BOUND_TOP = 4;
+
     /** @hide Process is hosting a foreground service. */
     @UnsupportedAppUsage
-    public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
+    public static final int PROCESS_STATE_FOREGROUND_SERVICE = 5;
 
     /** @hide Process is hosting a foreground service due to a system binding. */
     @UnsupportedAppUsage
-    public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 5;
+    public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 6;
 
     /** @hide Process is important to the user, and something they are aware of. */
-    public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6;
+    public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 7;
 
     /** @hide Process is important to the user, but not something they are aware of. */
     @UnsupportedAppUsage
-    public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7;
+    public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 8;
 
     /** @hide Process is in the background transient so we will try to keep running. */
-    public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 8;
+    public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 9;
 
     /** @hide Process is in the background running a backup/restore operation. */
-    public static final int PROCESS_STATE_BACKUP = 9;
+    public static final int PROCESS_STATE_BACKUP = 10;
 
     /** @hide Process is in the background running a service.  Unlike oom_adj, this level
      * is used for both the normal running in background state and the executing
      * operations state. */
     @UnsupportedAppUsage
-    public static final int PROCESS_STATE_SERVICE = 10;
+    public static final int PROCESS_STATE_SERVICE = 11;
 
     /** @hide Process is in the background running a receiver.   Note that from the
      * perspective of oom_adj, receivers run at a higher foreground level, but for our
      * prioritization here that is not necessary and putting them below services means
      * many fewer changes in some process states as they receive broadcasts. */
     @UnsupportedAppUsage
-    public static final int PROCESS_STATE_RECEIVER = 11;
+    public static final int PROCESS_STATE_RECEIVER = 12;
 
     /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
-    public static final int PROCESS_STATE_TOP_SLEEPING = 12;
+    public static final int PROCESS_STATE_TOP_SLEEPING = 13;
 
     /** @hide Process is in the background, but it can't restore its state so we want
      * to try to avoid killing it. */
-    public static final int PROCESS_STATE_HEAVY_WEIGHT = 13;
+    public static final int PROCESS_STATE_HEAVY_WEIGHT = 14;
 
     /** @hide Process is in the background but hosts the home activity. */
     @UnsupportedAppUsage
-    public static final int PROCESS_STATE_HOME = 14;
+    public static final int PROCESS_STATE_HOME = 15;
 
     /** @hide Process is in the background but hosts the last shown activity. */
-    public static final int PROCESS_STATE_LAST_ACTIVITY = 15;
+    public static final int PROCESS_STATE_LAST_ACTIVITY = 16;
 
     /** @hide Process is being cached for later use and contains activities. */
     @UnsupportedAppUsage
-    public static final int PROCESS_STATE_CACHED_ACTIVITY = 16;
+    public static final int PROCESS_STATE_CACHED_ACTIVITY = 17;
 
     /** @hide Process is being cached for later use and is a client of another cached
      * process that contains activities. */
-    public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 17;
+    public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 18;
 
     /** @hide Process is being cached for later use and has an activity that corresponds
      * to an existing recent task. */
-    public static final int PROCESS_STATE_CACHED_RECENT = 18;
+    public static final int PROCESS_STATE_CACHED_RECENT = 19;
 
     /** @hide Process is being cached for later use and is empty. */
-    public static final int PROCESS_STATE_CACHED_EMPTY = 19;
+    public static final int PROCESS_STATE_CACHED_EMPTY = 20;
 
     /** @hide Process does not exist. */
-    public static final int PROCESS_STATE_NONEXISTENT = 20;
+    public static final int PROCESS_STATE_NONEXISTENT = 21;
 
     // NOTE: If PROCESS_STATEs are added, then new fields must be added
     // to frameworks/base/core/proto/android/app/enums.proto and the following method must
@@ -602,6 +606,8 @@
                 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
             case PROCESS_STATE_TOP:
                 return AppProtoEnums.PROCESS_STATE_TOP;
+            case PROCESS_STATE_BOUND_TOP:
+                return AppProtoEnums.PROCESS_STATE_BOUND_TOP;
             case PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
             case PROCESS_STATE_FOREGROUND_SERVICE:
                 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
@@ -4037,7 +4043,7 @@
      * continues running even if the process is killed and restarted.  To remove the watch,
      * use {@link #clearWatchHeapLimit()}.
      *
-     * <p>This API only work if the calling process has been marked as
+     * <p>This API only works if the calling process has been marked as
      * {@link ApplicationInfo#FLAG_DEBUGGABLE} or this is running on a debuggable
      * (userdebug or eng) build.</p>
      *
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index 7eab5db..4ef554d 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -19,6 +19,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
@@ -146,6 +147,7 @@
         return IActivityTaskManagerSingleton.get();
     }
 
+    @UnsupportedAppUsage(trackingBug = 129726065)
     private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
             new Singleton<IActivityTaskManager>() {
                 @Override
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 08239a1..38006dc 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2100,6 +2100,16 @@
     public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
             int flags, int userId) {
         final boolean differentUser = (UserHandle.myUserId() != userId);
+        ApplicationInfo ai;
+        try {
+            ai = getPackageManager().getApplicationInfo(packageName,
+                    PackageManager.GET_SHARED_LIBRARY_FILES
+                            | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
+                    (userId < 0) ? UserHandle.myUserId() : userId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
         synchronized (mResourcesManager) {
             WeakReference<LoadedApk> ref;
             if (differentUser) {
@@ -2112,11 +2122,7 @@
             }
 
             LoadedApk packageInfo = ref != null ? ref.get() : null;
-            //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
-            //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
-            //        + ": " + packageInfo.mResources.getAssets().isUpToDate());
-            if (packageInfo != null && (packageInfo.mResources == null
-                    || packageInfo.mResources.getAssets().isUpToDate())) {
+            if (ai != null && packageInfo != null && isLoadedApkUpToDate(packageInfo, ai)) {
                 if (packageInfo.isSecurityViolation()
                         && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
                     throw new SecurityException(
@@ -2129,16 +2135,6 @@
             }
         }
 
-        ApplicationInfo ai = null;
-        try {
-            ai = getPackageManager().getApplicationInfo(packageName,
-                    PackageManager.GET_SHARED_LIBRARY_FILES
-                            | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
-                    (userId < 0) ? UserHandle.myUserId() : userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
         if (ai != null) {
             return getPackageInfo(ai, compatInfo, flags);
         }
@@ -2209,37 +2205,59 @@
             }
 
             LoadedApk packageInfo = ref != null ? ref.get() : null;
-            if (packageInfo == null || (packageInfo.mResources != null
-                    && !packageInfo.mResources.getAssets().isUpToDate())) {
-                if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
+
+            boolean isUpToDate = packageInfo != null && isLoadedApkUpToDate(packageInfo, aInfo);
+
+            if (isUpToDate) {
+                return packageInfo;
+            }
+
+            if (localLOGV) {
+                Slog.v(TAG, (includeCode ? "Loading code package "
                         : "Loading resource-only package ") + aInfo.packageName
                         + " (in " + (mBoundApplication != null
-                                ? mBoundApplication.processName : null)
+                        ? mBoundApplication.processName : null)
                         + ")");
-                packageInfo =
-                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
-                            securityViolation, includeCode &&
-                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
-
-                if (mSystemThread && "android".equals(aInfo.packageName)) {
-                    packageInfo.installSystemApplicationInfo(aInfo,
-                            getSystemContext().mPackageInfo.getClassLoader());
-                }
-
-                if (differentUser) {
-                    // Caching not supported across users
-                } else if (includeCode) {
-                    mPackages.put(aInfo.packageName,
-                            new WeakReference<LoadedApk>(packageInfo));
-                } else {
-                    mResourcePackages.put(aInfo.packageName,
-                            new WeakReference<LoadedApk>(packageInfo));
-                }
             }
+
+            packageInfo =
+                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
+                            securityViolation, includeCode
+                            && (aInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
+
+            if (mSystemThread && "android".equals(aInfo.packageName)) {
+                packageInfo.installSystemApplicationInfo(aInfo,
+                        getSystemContext().mPackageInfo.getClassLoader());
+            }
+
+            if (differentUser) {
+                // Caching not supported across users
+            } else if (includeCode) {
+                mPackages.put(aInfo.packageName,
+                        new WeakReference<LoadedApk>(packageInfo));
+            } else {
+                mResourcePackages.put(aInfo.packageName,
+                        new WeakReference<LoadedApk>(packageInfo));
+            }
+
             return packageInfo;
         }
     }
 
+    /**
+     * Compares overlay/resource directories for a LoadedApk to determine if it's up to date
+     * with the given ApplicationInfo.
+     */
+    private boolean isLoadedApkUpToDate(LoadedApk loadedApk, ApplicationInfo appInfo) {
+        Resources packageResources = loadedApk.mResources;
+        String[] overlayDirs = ArrayUtils.defeatNullable(loadedApk.getOverlayDirs());
+        String[] resourceDirs = ArrayUtils.defeatNullable(appInfo.resourceDirs);
+
+        return (packageResources == null || packageResources.getAssets().isUpToDate())
+                && overlayDirs.length == resourceDirs.length
+                && ArrayUtils.containsAll(overlayDirs, resourceDirs);
+    }
+
     @UnsupportedAppUsage
     ActivityThread() {
         mResourcesManager = ResourcesManager.getInstance();
@@ -5434,19 +5452,25 @@
             ref = mResourcePackages.get(ai.packageName);
             resApk = ref != null ? ref.get() : null;
         }
+
+        final String[] oldResDirs = new String[2];
+
         if (apk != null) {
+            oldResDirs[0] = apk.getResDir();
             final ArrayList<String> oldPaths = new ArrayList<>();
             LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
             apk.updateApplicationInfo(ai, oldPaths);
         }
         if (resApk != null) {
+            oldResDirs[1] = resApk.getResDir();
             final ArrayList<String> oldPaths = new ArrayList<>();
             LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths);
             resApk.updateApplicationInfo(ai, oldPaths);
         }
+
         synchronized (mResourcesManager) {
             // Update all affected Resources objects to use new ResourcesImpl
-            mResourcesManager.applyNewResourceDirsLocked(ai.sourceDir, ai.resourceDirs);
+            mResourcesManager.applyNewResourceDirsLocked(ai, oldResDirs);
         }
 
         ApplicationPackageManager.configurationChanged();
@@ -5699,9 +5723,17 @@
                                         }
                                     }
                                 }
+
+                                final String[] oldResDirs = { pkgInfo.getResDir() };
+
                                 final ArrayList<String> oldPaths = new ArrayList<>();
                                 LoadedApk.makePaths(this, pkgInfo.getApplicationInfo(), oldPaths);
                                 pkgInfo.updateApplicationInfo(aInfo, oldPaths);
+
+                                synchronized (mResourcesManager) {
+                                    // Update affected Resources objects to use new ResourcesImpl
+                                    mResourcesManager.applyNewResourceDirsLocked(aInfo, oldResDirs);
+                                }
                             } catch (RemoteException e) {
                             }
                         }
@@ -5853,6 +5885,11 @@
     private void handleBindApplication(AppBindData data) {
         // Register the UI Thread as a sensitive thread to the runtime.
         VMRuntime.registerSensitiveThread();
+        // In the case the stack depth property exists, pass it down to the runtime.
+        String property = SystemProperties.get("debug.allocTracker.stackDepth");
+        if (property.length() != 0) {
+            VMDebug.setAllocTrackerStackDepth(Integer.parseInt(property));
+        }
         if (data.trackAllocation) {
             DdmVmInternal.enableRecentAllocations(true);
         }
@@ -5883,6 +5920,10 @@
                                                 UserHandle.myUserId());
         VMRuntime.setProcessPackageName(data.appInfo.packageName);
 
+        // Pass data directory path to ART. This is used for caching information and
+        // should be set before any application code is loaded.
+        VMRuntime.setProcessDataDirectory(data.appInfo.dataDir);
+
         if (mProfiler.profileFd != null) {
             mProfiler.startProfiling();
         }
@@ -6905,9 +6946,6 @@
             // If feature is disabled, we don't need to install
             if (!DEPRECATE_DATA_COLUMNS) return;
 
-            // If app is modern enough, we don't need to install
-            if (VMRuntime.getRuntime().getTargetSdkVersion() >= Build.VERSION_CODES.Q) return;
-
             // Install interception and make sure it sticks!
             Os def = null;
             do {
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 2ef0856..8ec5e3a 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Insets;
+import android.graphics.Region;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.VirtualDisplay;
 import android.hardware.input.InputManager;
@@ -46,6 +47,7 @@
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewParent;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 
@@ -81,6 +83,9 @@
     // Temp container to store view coordinates in window.
     private final int[] mLocationInWindow = new int[2];
 
+    // The latest tap exclude region that we've sent to WM.
+    private final Region mTapExcludeRegion = new Region();
+
     private TaskStackListener mTaskStackListener;
 
     private final CloseGuard mGuard = CloseGuard.get();
@@ -279,11 +284,11 @@
     }
 
     /**
-     * Triggers an update of {@link ActivityView}'s location in window to properly set touch exclude
+     * Triggers an update of {@link ActivityView}'s location in window to properly set tap exclude
      * regions and avoid focus switches by touches on this view.
      */
     public void onLocationChanged() {
-        updateLocation();
+        updateTapExcludeRegion();
     }
 
     @Override
@@ -291,15 +296,38 @@
         mSurfaceView.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */);
     }
 
-    /** Send current location and size to the WM to set tap exclude region for this view. */
-    private void updateLocation() {
+    @Override
+    public boolean gatherTransparentRegion(Region region) {
+        // The tap exclude region may be affected by any view on top of it, so we detect the
+        // possible change by monitoring this function.
+        updateTapExcludeRegion();
+        return super.gatherTransparentRegion(region);
+    }
+
+    /** Compute and send current tap exclude region to WM for this view. */
+    private void updateTapExcludeRegion() {
         if (!isAttachedToWindow()) {
             return;
         }
+        if (!canReceivePointerEvents()) {
+            cleanTapExcludeRegion();
+            return;
+        }
         try {
             getLocationInWindow(mLocationInWindow);
+            final int x = mLocationInWindow[0];
+            final int y = mLocationInWindow[1];
+            mTapExcludeRegion.set(x, y, x + getWidth(), y + getHeight());
+
+            // There might be views on top of us. We need to subtract those areas from the tap
+            // exclude region.
+            final ViewParent parent = getParent();
+            if (parent instanceof ViewGroup) {
+                ((ViewGroup) parent).subtractObscuredTouchableRegion(mTapExcludeRegion, this);
+            }
+
             WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(),
-                    mLocationInWindow[0], mLocationInWindow[1], getWidth(), getHeight());
+                    mTapExcludeRegion);
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
@@ -322,7 +350,7 @@
                 mVirtualDisplay.setDisplayState(true);
             }
 
-            updateLocation();
+            updateTapExcludeRegion();
         }
 
         @Override
@@ -330,7 +358,7 @@
             if (mVirtualDisplay != null) {
                 mVirtualDisplay.resize(width, height, getBaseDisplayDensity());
             }
-            updateLocation();
+            updateTapExcludeRegion();
         }
 
         @Override
@@ -460,13 +488,14 @@
 
     /** Report to server that tap exclude region on hosting display should be cleared. */
     private void cleanTapExcludeRegion() {
-        if (!isAttachedToWindow()) {
+        if (!isAttachedToWindow() || mTapExcludeRegion.isEmpty()) {
             return;
         }
-        // Update tap exclude region with an empty rect to clean the state on server.
+        // Update tap exclude region with a null region to clean the state on server.
         try {
             WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(),
-                    0 /* left */, 0 /* top */, 0 /* width */, 0 /* height */);
+                    null /* region */);
+            mTapExcludeRegion.setEmpty();
         } catch (RemoteException e) {
             e.rethrowAsRuntimeException();
         }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 5ed4428..4b0b8cb 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -1543,11 +1544,11 @@
             Manifest.permission.USE_BIOMETRIC,
             Manifest.permission.ACTIVITY_RECOGNITION,
             Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
-            Manifest.permission.READ_MEDIA_AUDIO,
+            null,
             null, // no permission for OP_WRITE_MEDIA_AUDIO
-            Manifest.permission.READ_MEDIA_VIDEO,
+            null,
             null, // no permission for OP_WRITE_MEDIA_VIDEO
-            Manifest.permission.READ_MEDIA_IMAGES,
+            null,
             null, // no permission for OP_WRITE_MEDIA_IMAGES
             null, // no permission for OP_LEGACY_STORAGE
             null, // no permission for OP_ACCESS_ACCESSIBILITY
@@ -3114,7 +3115,7 @@
          *
          * @see #getUidOpsAt(int)
          */
-        public int getUidCount() {
+        public @IntRange(from = 0) int getUidCount() {
             if (mHistoricalUidOps == null) {
                 return 0;
             }
@@ -3130,7 +3131,7 @@
          *
          * @see #getUidCount()
          */
-        public @NonNull HistoricalUidOps getUidOpsAt(int index) {
+        public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) {
             if (mHistoricalUidOps == null) {
                 throw new IndexOutOfBoundsException();
             }
@@ -3391,7 +3392,7 @@
          *
          * @see #getPackageOpsAt(int)
          */
-        public int getPackageCount() {
+        public @IntRange(from = 0) int getPackageCount() {
             if (mHistoricalPackageOps == null) {
                 return 0;
             }
@@ -3407,7 +3408,7 @@
          *
          * @see #getPackageCount()
          */
-        public @NonNull HistoricalPackageOps getPackageOpsAt(int index) {
+        public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) {
             if (mHistoricalPackageOps == null) {
                 throw new IndexOutOfBoundsException();
             }
@@ -3626,7 +3627,7 @@
          * @return The number historical app ops.
          * @see #getOpAt(int)
          */
-        public int getOpCount() {
+        public @IntRange(from = 0) int getOpCount() {
             if (mHistoricalOps == null) {
                 return 0;
             }
@@ -3640,7 +3641,7 @@
          * @return The op at the given index.
          * @see #getOpCount()
          */
-        public @NonNull HistoricalOp getOpAt(int index) {
+        public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) {
             if (mHistoricalOps == null) {
                 throw new IndexOutOfBoundsException();
             }
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 9ef24c6..faa30f3 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -17,20 +17,27 @@
 package android.app;
 
 import android.annotation.UnsupportedAppUsage;
+import android.content.pm.SharedLibraryInfo;
 import android.os.Build;
 import android.os.GraphicsEnvironment;
 import android.os.Trace;
 import android.util.ArrayMap;
+import android.util.Log;
 
 import com.android.internal.os.ClassLoaderFactory;
 
 import dalvik.system.PathClassLoader;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /** @hide */
 public class ApplicationLoaders {
+    private static final String TAG = "ApplicationLoaders";
+
     @UnsupportedAppUsage
     public static ApplicationLoaders getDefault() {
         return gApplicationLoaders;
@@ -54,6 +61,26 @@
                               libraryPermittedPath, parent, zip, classLoaderName, sharedLibraries);
     }
 
+    /**
+     * Gets a class loader for a shared library. Additional dependent shared libraries are allowed
+     * to be specified (sharedLibraries).
+     *
+     * Additionally, as an optimization, this will return a pre-created ClassLoader if one has
+     * been cached by createAndCacheNonBootclasspathSystemClassLoaders.
+     */
+    ClassLoader getSharedLibraryClassLoaderWithSharedLibraries(String zip, int targetSdkVersion,
+            boolean isBundled, String librarySearchPath, String libraryPermittedPath,
+            ClassLoader parent, String classLoaderName, List<ClassLoader> sharedLibraries) {
+        ClassLoader loader = getCachedNonBootclasspathSystemLib(zip, parent, classLoaderName,
+                sharedLibraries);
+        if (loader != null) {
+            return loader;
+        }
+
+        return getClassLoaderWithSharedLibraries(zip, targetSdkVersion, isBundled,
+              librarySearchPath, libraryPermittedPath, parent, classLoaderName, sharedLibraries);
+    }
+
     private ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
                                        String librarySearchPath, String libraryPermittedPath,
                                        ClassLoader parent, String cacheKey,
@@ -95,7 +122,9 @@
                         classloader, librarySearchPath, libraryPermittedPath);
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
-                mLoaders.put(cacheKey, classloader);
+                if (cacheKey != null) {
+                    mLoaders.put(cacheKey, classloader);
+                }
                 return classloader;
             }
 
@@ -108,6 +137,112 @@
     }
 
     /**
+     * Caches system library class loaders which are not on the bootclasspath but are still used
+     * by many system apps.
+     *
+     * All libraries in the closure of libraries to be loaded must be in libs. A library can
+     * only depend on libraries that come before it in the list.
+     */
+    public void createAndCacheNonBootclasspathSystemClassLoaders(SharedLibraryInfo[] libs) {
+        if (mSystemLibsCacheMap != null) {
+            Log.wtf(TAG, "Already cached.");
+            return;
+        }
+
+        mSystemLibsCacheMap = new HashMap<String, CachedClassLoader>();
+
+        for (SharedLibraryInfo lib : libs) {
+            createAndCacheNonBootclasspathSystemClassLoader(lib);
+        }
+    }
+
+    /**
+     * Caches a single non-bootclasspath class loader.
+     *
+     * All of this library's dependencies must have previously been cached.
+     */
+    private void createAndCacheNonBootclasspathSystemClassLoader(SharedLibraryInfo lib) {
+        String path = lib.getPath();
+        List<SharedLibraryInfo> dependencies = lib.getDependencies();
+
+        // get cached classloaders for dependencies
+        ArrayList<ClassLoader> sharedLibraries = null;
+        if (dependencies != null) {
+            sharedLibraries = new ArrayList<ClassLoader>(dependencies.size());
+            for (SharedLibraryInfo dependency : dependencies) {
+                String dependencyPath = dependency.getPath();
+                CachedClassLoader cached = mSystemLibsCacheMap.get(dependencyPath);
+
+                if (cached == null) {
+                    Log.e(TAG, "Failed to find dependency " + dependencyPath
+                            + " of cached library " + path);
+                    return;
+                }
+
+                sharedLibraries.add(cached.loader);
+            }
+        }
+
+        // assume cached libraries work with current sdk since they are built-in
+        ClassLoader classLoader = getClassLoader(path, Build.VERSION.SDK_INT, true /*isBundled*/,
+                null /*librarySearchPath*/, null /*libraryPermittedPath*/, null /*parent*/,
+                null /*cacheKey*/, null /*classLoaderName*/, sharedLibraries /*sharedLibraries*/);
+
+        if (classLoader == null) {
+            Log.e(TAG, "Failed to cache " + path);
+            return;
+        }
+
+        CachedClassLoader cached = new CachedClassLoader();
+        cached.loader = classLoader;
+        cached.sharedLibraries = sharedLibraries;
+
+        Log.d(TAG, "Created zygote-cached class loader: " + path);
+        mSystemLibsCacheMap.put(path, cached);
+    }
+
+    private static boolean sharedLibrariesEquals(List<ClassLoader> lhs, List<ClassLoader> rhs) {
+        if (lhs == null) {
+            return rhs == null;
+        }
+
+        return lhs.equals(rhs);
+    }
+
+    /**
+     * Returns lib cached with createAndCacheNonBootclasspathSystemClassLoader. This is called by
+     * the zygote during caching.
+     *
+     * If there is an error or the cache is not available, this returns null.
+     */
+    private ClassLoader getCachedNonBootclasspathSystemLib(String zip, ClassLoader parent,
+            String classLoaderName, List<ClassLoader> sharedLibraries) {
+        if (mSystemLibsCacheMap == null) {
+            return null;
+        }
+
+        // we only cache top-level libs with the default class loader
+        if (parent != null || classLoaderName != null) {
+            return null;
+        }
+
+        CachedClassLoader cached = mSystemLibsCacheMap.get(zip);
+        if (cached == null) {
+            return null;
+        }
+
+        // cached must be built and loaded in the same environment
+        if (!sharedLibrariesEquals(sharedLibraries, cached.sharedLibraries)) {
+            Log.w(TAG, "Unexpected environment for cached library: (" + sharedLibraries + "|"
+                    + cached.sharedLibraries + ")");
+            return null;
+        }
+
+        Log.d(TAG, "Returning zygote-cached class loader: " + zip);
+        return cached.loader;
+    }
+
+    /**
      * Creates a classloader for the WebView APK and places it in the cache of loaders maintained
      * by this class. This is used in the WebView zygote, where its presence in the cache speeds up
      * startup and enables memory sharing.
@@ -151,4 +286,18 @@
     private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<>();
 
     private static final ApplicationLoaders gApplicationLoaders = new ApplicationLoaders();
+
+    private static class CachedClassLoader {
+        ClassLoader loader;
+
+        /**
+         * The shared libraries used when constructing loader for verification.
+         */
+        List<ClassLoader> sharedLibraries;
+    }
+
+    /**
+     * This is a map of zip to associated class loader.
+     */
+    private Map<String, CachedClassLoader> mSystemLibsCacheMap = null;
 }
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 404e520..a906790 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3049,6 +3049,15 @@
     }
 
     @Override
+    public String getAttentionServicePackageName() {
+        try {
+            return mPM.getAttentionServicePackageName();
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    @Override
     public String getWellbeingPackageName() {
         try {
             return mPM.getWellbeingPackageName();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 11000df..41a4fba 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2122,8 +2122,7 @@
     }
 
     private static Resources createResources(IBinder activityToken, LoadedApk pi, String splitName,
-            int displayId, Configuration overrideConfig, CompatibilityInfo compatInfo,
-            String[] overlayDirs) {
+            int displayId, Configuration overrideConfig, CompatibilityInfo compatInfo) {
         final String[] splitResDirs;
         final ClassLoader classLoader;
         try {
@@ -2135,7 +2134,7 @@
         return ResourcesManager.getInstance().getResources(activityToken,
                 pi.getResDir(),
                 splitResDirs,
-                overlayDirs,
+                pi.getOverlayDirs(),
                 pi.getApplicationInfo().sharedLibraryFiles,
                 displayId,
                 overrideConfig,
@@ -2153,11 +2152,9 @@
                     new UserHandle(UserHandle.getUserId(application.uid)), flags, null, null);
 
             final int displayId = getDisplayId();
-            // overlayDirs is retrieved directly from ApplicationInfo since ActivityThread may have
-            // a LoadedApk containing Resources with stale overlays for a remote application.
-            final String[] overlayDirs = application.resourceDirs;
+
             c.setResources(createResources(mActivityToken, pi, null, displayId, null,
-                    getDisplayAdjustments(displayId).getCompatibilityInfo(), overlayDirs));
+                    getDisplayAdjustments(displayId).getCompatibilityInfo()));
             if (c.mResources != null) {
                 return c;
             }
@@ -2192,7 +2189,7 @@
             final int displayId = getDisplayId();
 
             c.setResources(createResources(mActivityToken, pi, null, displayId, null,
-                    getDisplayAdjustments(displayId).getCompatibilityInfo(), pi.getOverlayDirs()));
+                    getDisplayAdjustments(displayId).getCompatibilityInfo()));
             if (c.mResources != null) {
                 return c;
             }
@@ -2242,8 +2239,7 @@
 
         final int displayId = getDisplayId();
         context.setResources(createResources(mActivityToken, mPackageInfo, mSplitName, displayId,
-                overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo(),
-                mPackageInfo.getOverlayDirs()));
+                overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo()));
         return context;
     }
 
@@ -2258,8 +2254,7 @@
 
         final int displayId = display.getDisplayId();
         context.setResources(createResources(mActivityToken, mPackageInfo, mSplitName, displayId,
-                null, getDisplayAdjustments(displayId).getCompatibilityInfo(),
-                mPackageInfo.getOverlayDirs()));
+                null, getDisplayAdjustments(displayId).getCompatibilityInfo()));
         context.mDisplay = display;
         return context;
     }
@@ -2441,7 +2436,7 @@
         ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo, null,
                 null, null, 0, null, null);
         context.setResources(createResources(null, packageInfo, null, displayId, null,
-                packageInfo.getCompatibilityInfo(), packageInfo.getOverlayDirs()));
+                packageInfo.getCompatibilityInfo()));
         context.updateDisplay(displayId);
         return context;
     }
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 16fe7db..65f1080 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -346,6 +346,9 @@
     void unregisterUserSwitchObserver(in IUserSwitchObserver observer);
     int[] getRunningUserIds();
 
+    // Request a heap dump for the system server.
+    void requestSystemServerHeapDump();
+
     // Deprecated - This method is only used by a few internal components and it will soon be
     // replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
     // No new code should be calling it.
diff --git a/core/java/android/app/InstantAppResolverService.java b/core/java/android/app/InstantAppResolverService.java
index b1541c6..a7be542 100644
--- a/core/java/android/app/InstantAppResolverService.java
+++ b/core/java/android/app/InstantAppResolverService.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.Intent;
@@ -61,8 +63,8 @@
      *             String, InstantAppResolutionCallback)}.
      */
     @Deprecated
-    public void onGetInstantAppResolveInfo(
-            int digestPrefix[], String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppResolveInfo(@Nullable int[] digestPrefix, @NonNull String token,
+            @NonNull InstantAppResolutionCallback callback) {
         throw new IllegalStateException("Must define onGetInstantAppResolveInfo");
     }
 
@@ -75,8 +77,8 @@
      *             String, InstantAppResolutionCallback)}.
      */
     @Deprecated
-    public void onGetInstantAppIntentFilter(
-            int digestPrefix[], String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppIntentFilter(@Nullable int[] digestPrefix, @NonNull String token,
+            @NonNull InstantAppResolutionCallback callback) {
         throw new IllegalStateException("Must define onGetInstantAppIntentFilter");
     }
 
@@ -105,8 +107,9 @@
      *             String, InstantAppResolutionCallback)}.
      */
     @Deprecated
-    public void onGetInstantAppResolveInfo(Intent sanitizedIntent, int[] hostDigestPrefix,
-            String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppResolveInfo(@NonNull Intent sanitizedIntent,
+            @Nullable int[] hostDigestPrefix, @NonNull String token,
+            @NonNull InstantAppResolutionCallback callback) {
         // if not overridden, forward to old methods and filter out non-web intents
         if (sanitizedIntent.isWebIntent()) {
             onGetInstantAppResolveInfo(hostDigestPrefix, token, callback);
@@ -135,8 +138,9 @@
      *             String, InstantAppResolutionCallback)}.
      */
     @Deprecated
-    public void onGetInstantAppIntentFilter(Intent sanitizedIntent, int[] hostDigestPrefix,
-            String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppIntentFilter(@NonNull Intent sanitizedIntent,
+            @Nullable int[] hostDigestPrefix,
+            @NonNull String token, @NonNull InstantAppResolutionCallback callback) {
         Log.e(TAG, "New onGetInstantAppIntentFilter is not overridden");
         // if not overridden, forward to old methods and filter out non-web intents
         if (sanitizedIntent.isWebIntent()) {
@@ -167,8 +171,9 @@
      *
      * @see InstantAppResolveInfo
      */
-    public void onGetInstantAppResolveInfo(Intent sanitizedIntent, int[] hostDigestPrefix,
-            UserHandle userHandle, String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppResolveInfo(@NonNull Intent sanitizedIntent,
+            @Nullable int[] hostDigestPrefix, @NonNull UserHandle userHandle,
+            @NonNull String token, @NonNull InstantAppResolutionCallback callback) {
         // If not overridden, forward to the old method.
         onGetInstantAppResolveInfo(sanitizedIntent, hostDigestPrefix, token, callback);
     }
@@ -189,8 +194,9 @@
      *              to the currently visible installer via {@link Intent#EXTRA_INSTANT_APP_TOKEN}.
      * @param callback The {@link InstantAppResolutionCallback} to provide results to.
      */
-    public void onGetInstantAppIntentFilter(Intent sanitizedIntent, int[] hostDigestPrefix,
-            UserHandle userHandle, String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppIntentFilter(@NonNull Intent sanitizedIntent,
+            @Nullable int[] hostDigestPrefix, @NonNull UserHandle userHandle,
+            @NonNull String token, @NonNull InstantAppResolutionCallback callback) {
         // If not overridden, forward to the old method.
         onGetInstantAppIntentFilter(sanitizedIntent, hostDigestPrefix, token, callback);
     }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 41a9921..25e3573 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -676,7 +676,7 @@
 
         // Shared libraries get a null parent: this has the side effect of having canonicalized
         // shared libraries using ApplicationLoaders cache, which is the behavior we want.
-        return ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(jars,
+        return ApplicationLoaders.getDefault().getSharedLibraryClassLoaderWithSharedLibraries(jars,
                     mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
                     libraryPermittedPath, /* parent */ null,
                     /* classLoaderName */ null, sharedLibraries);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index d634aa5..0ab1a85 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -16,12 +16,14 @@
 
 package android.app;
 
+import static android.annotation.Dimension.DP;
 import static android.graphics.drawable.Icon.TYPE_BITMAP;
 
 import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast;
 
 import android.annotation.ColorInt;
 import android.annotation.DimenRes;
+import android.annotation.Dimension;
 import android.annotation.DrawableRes;
 import android.annotation.IdRes;
 import android.annotation.IntDef;
@@ -615,6 +617,13 @@
      */
     public static final int FLAG_CAN_COLORIZE = 0x00000800;
 
+    /**
+     * Bit to be bitswised-ored into the {@link #flags} field that should be
+     * set if this notification can be shown as a bubble.
+     * @hide
+     */
+    public static final int FLAG_BUBBLE = 0x00001000;
+
     public int flags;
 
     /** @hide */
@@ -5562,7 +5571,7 @@
                     button.setTextColor(R.id.action0, textColor);
                     rippleColor = textColor;
                 } else if (getRawColor(p) != COLOR_DEFAULT && !isColorized(p)
-                        && mTintActionButtons) {
+                        && mTintActionButtons && !mInNightMode) {
                     rippleColor = resolveContrastColor(p);
                     button.setTextColor(R.id.action0, rippleColor);
                 } else {
@@ -6241,6 +6250,15 @@
         return false;
     }
 
+    /**
+     * @return true if this is a notification that can show as a bubble.
+     *
+     * @hide
+     */
+    public boolean isBubbleNotification() {
+        return (flags & Notification.FLAG_BUBBLE) != 0;
+    }
+
     private boolean hasLargeIcon() {
         return mLargeIcon != null || largeIcon != null;
     }
@@ -8594,15 +8612,18 @@
 
         /**
          * @return the ideal height, in DPs, for the floating window that app content defined by
-         * {@link #getIntent()} for this bubble.
+         * {@link #getIntent()} for this bubble. A value of 0 indicates a desired height has not
+         * been set.
          */
+        @Dimension(unit = DP)
         public int getDesiredHeight() {
             return mDesiredHeight;
         }
 
         /**
          * @return the resId of ideal height for the floating window that app content defined by
-         * {@link #getIntent()} for this bubble.
+         * {@link #getIntent()} for this bubble. A value of 0 indicates a res value has not
+         * been provided for the desired height.
          */
         @DimenRes
         public int getDesiredHeightResId() {
@@ -8733,7 +8754,7 @@
              * be used instead.
              */
             @NonNull
-            public BubbleMetadata.Builder setDesiredHeight(int height) {
+            public BubbleMetadata.Builder setDesiredHeight(@Dimension(unit = DP) int height) {
                 mDesiredHeight = Math.max(height, 0);
                 mDesiredHeightResId = 0;
                 return this;
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 5cdf85a..69ec831 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -170,6 +170,7 @@
     private boolean mBlockableSystem = false;
     private boolean mAllowBubbles = DEFAULT_ALLOW_BUBBLE;
     private boolean mImportanceLockedByOEM;
+    private boolean mImportanceLockedDefaultApp;
 
     /**
      * Creates a notification channel.
@@ -656,11 +657,27 @@
      * @hide
      */
     @TestApi
+    public void setImportanceLockedByCriticalDeviceFunction(boolean locked) {
+        mImportanceLockedDefaultApp = locked;
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
     public boolean isImportanceLockedByOEM() {
         return mImportanceLockedByOEM;
     }
 
     /**
+     * @hide
+     */
+    @TestApi
+    public boolean isImportanceLockedByCriticalDeviceFunction() {
+        return mImportanceLockedDefaultApp;
+    }
+
+    /**
      * Returns whether the user has chosen the importance of this channel, either to affirm the
      * initial selection from the app, or changed it to be higher or lower.
      * @see #getImportance()
@@ -834,6 +851,9 @@
             out.attribute(null, ATT_ALLOW_BUBBLE, Boolean.toString(canBubble()));
         }
 
+        // mImportanceLockedDefaultApp and mImportanceLockedByOEM have a different source of
+        // truth and so aren't written to this xml file
+
         out.endTag(null, TAG_CHANNEL);
     }
 
@@ -942,7 +962,8 @@
         return sb.toString();
     }
 
-    public static final @android.annotation.NonNull Creator<NotificationChannel> CREATOR = new Creator<NotificationChannel>() {
+    public static final @android.annotation.NonNull Creator<NotificationChannel> CREATOR =
+            new Creator<NotificationChannel>() {
         @Override
         public NotificationChannel createFromParcel(Parcel in) {
             return new NotificationChannel(in);
@@ -983,7 +1004,8 @@
                 && Arrays.equals(mVibration, that.mVibration)
                 && Objects.equals(getGroup(), that.getGroup())
                 && Objects.equals(getAudioAttributes(), that.getAudioAttributes())
-                && mImportanceLockedByOEM == that.mImportanceLockedByOEM;
+                && mImportanceLockedByOEM == that.mImportanceLockedByOEM
+                && mImportanceLockedDefaultApp == that.mImportanceLockedDefaultApp;
     }
 
     @Override
@@ -993,7 +1015,7 @@
                 getUserLockedFields(),
                 isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(),
                 getAudioAttributes(), isBlockableSystem(), mAllowBubbles,
-                mImportanceLockedByOEM);
+                mImportanceLockedByOEM, mImportanceLockedDefaultApp);
         result = 31 * result + Arrays.hashCode(mVibration);
         return result;
     }
@@ -1022,6 +1044,7 @@
                 + ", mBlockableSystem=" + mBlockableSystem
                 + ", mAllowBubbles=" + mAllowBubbles
                 + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
+                + ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp
                 + '}';
         pw.println(prefix + output);
     }
@@ -1049,6 +1072,7 @@
                 + ", mBlockableSystem=" + mBlockableSystem
                 + ", mAllowBubbles=" + mAllowBubbles
                 + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
+                + ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp
                 + '}';
     }
 
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 35658fb..b93aaa2 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.res.ApkAssets;
 import android.content.res.AssetManager;
 import android.content.res.CompatResources;
@@ -32,6 +33,7 @@
 import android.content.res.ResourcesKey;
 import android.hardware.display.DisplayManagerGlobal;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.Trace;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
@@ -1136,27 +1138,46 @@
     }
 
     // TODO(adamlesinski): Make this accept more than just overlay directories.
-    final void applyNewResourceDirsLocked(@NonNull final String baseCodePath,
-            @Nullable final String[] newResourceDirs) {
+    final void applyNewResourceDirsLocked(@NonNull final ApplicationInfo appInfo,
+            @Nullable final String[] oldPaths) {
         try {
             Trace.traceBegin(Trace.TRACE_TAG_RESOURCES,
                     "ResourcesManager#applyNewResourceDirsLocked");
 
+            String baseCodePath = appInfo.getBaseCodePath();
+
+            final int myUid = Process.myUid();
+            String[] newSplitDirs = appInfo.uid == myUid
+                    ? appInfo.splitSourceDirs
+                    : appInfo.splitPublicSourceDirs;
+
+            // ApplicationInfo is mutable, so clone the arrays to prevent outside modification
+            String[] copiedSplitDirs = ArrayUtils.cloneOrNull(newSplitDirs);
+            String[] copiedResourceDirs = ArrayUtils.cloneOrNull(appInfo.resourceDirs);
+
             final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
             final int implCount = mResourceImpls.size();
             for (int i = 0; i < implCount; i++) {
                 final ResourcesKey key = mResourceImpls.keyAt(i);
                 final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
                 final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
-                if (impl != null && (key.mResDir == null || key.mResDir.equals(baseCodePath))) {
+
+                if (impl == null) {
+                    continue;
+                }
+
+                if (key.mResDir == null
+                        || key.mResDir.equals(baseCodePath)
+                        || ArrayUtils.contains(oldPaths, key.mResDir)) {
                     updatedResourceKeys.put(impl, new ResourcesKey(
-                            key.mResDir,
-                            key.mSplitResDirs,
-                            newResourceDirs,
+                            baseCodePath,
+                            copiedSplitDirs,
+                            copiedResourceDirs,
                             key.mLibDirs,
                             key.mDisplayId,
                             key.mOverrideConfiguration,
-                            key.mCompatInfo));
+                            key.mCompatInfo
+                    ));
                 }
             }
 
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 7746148..2e14d03 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -18,6 +18,7 @@
 import static android.Manifest.permission.DUMP;
 import static android.Manifest.permission.PACKAGE_USAGE_STATS;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
@@ -295,7 +296,7 @@
      * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
      */
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
-    public long[] setActiveConfigsChangedOperation(@Nullable PendingIntent pendingIntent)
+    public @NonNull long[] setActiveConfigsChangedOperation(@Nullable PendingIntent pendingIntent)
             throws StatsUnavailableException {
         synchronized (this) {
             try {
@@ -410,6 +411,36 @@
     }
 
     /**
+     * Returns the experiments IDs registered with statsd, or an empty array if there aren't any.
+     *
+     * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
+     * @hide
+     */
+    @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
+    public long[] getRegisteredExperimentIds()
+            throws StatsUnavailableException {
+        synchronized (this) {
+            try {
+                IStatsManager service = getIStatsManagerLocked();
+                if (service == null) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "Failed to find statsd when getting experiment IDs");
+                    }
+                    return new long[0];
+                }
+                return service.getRegisteredExperimentIds();
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.d(TAG,
+                            "Failed to connect to StatsCompanionService when getting "
+                                    + "registered experiment IDs");
+                }
+                return new long[0];
+            }
+        }
+    }
+
+    /**
      * Registers a callback for an atom when that atom is to be pulled. The stats service will
      * invoke pullData in the callback when the stats service determines that this atom needs to be
      * pulled. Currently, this only works for atoms with tags above 100,000 that do not have a uid.
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index a021e3c..4944673 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -22,6 +22,7 @@
 import android.accessibilityservice.IAccessibilityServiceClient;
 import android.accessibilityservice.IAccessibilityServiceConnection;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
@@ -390,10 +391,12 @@
      * <strong>Note:<strong/> Calling this method adopts only the specified shell permissions
      * and overrides all adopted permissions via {@link #adoptShellPermissionIdentity()}.
      *
+     * @param permissions The permissions to adopt or <code>null</code> to adopt all.
+     *
      * @see #adoptShellPermissionIdentity()
      * @see #dropShellPermissionIdentity()
      */
-    public void adoptShellPermissionIdentity(String... permissions) {
+    public void adoptShellPermissionIdentity(@Nullable String... permissions) {
         synchronized (mLock) {
             throwIfNotConnectedLocked();
         }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 4c05497..83c5e20 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -54,7 +54,6 @@
 import android.net.PrivateDnsConnectivityChecker;
 import android.net.ProxyInfo;
 import android.net.Uri;
-import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
@@ -2148,8 +2147,8 @@
         public static final int UPDATE_ERROR_INCORRECT_OS_VERSION = 2;
 
         /**
-         * Represents the update file being wrong, i.e. payloads are mismatched, wrong compressions
-         * method.
+         * Represents the update file being wrong; e.g. payloads are mismatched, or the wrong
+         * compression method is used.
          */
         public static final int UPDATE_ERROR_UPDATE_FILE_INVALID = 3;
 
@@ -2166,7 +2165,7 @@
          * reported back to the IT admin to be read.
          */
         public void onInstallUpdateError(
-                @InstallUpdateCallbackErrorConstants int errorCode, String errorMessage) {
+                @InstallUpdateCallbackErrorConstants int errorCode, @NonNull String errorMessage) {
         }
     }
 
@@ -5440,13 +5439,14 @@
     }
 
     /**
-     * Called by a device or profile owner to set whether auto time is required. If auto time is
-     * required, no user will be able set the date and time and network date and time will be used.
+     * Called by a device owner, or alternatively a profile owner from Android 8.0 (API level 26) or
+     * higher, to set whether auto time is required. If auto time is required, no user will be able
+     * set the date and time and network date and time will be used.
      * <p>
      * Note: if auto time is required the user can still manually set the time zone.
      * <p>
-     * The calling device admin must be a device or profile owner. If it is not, a security
-     * exception will be thrown.
+     * The calling device admin must be a device owner, or alternatively a profile owner from
+     * Android 8.0 (API level 26) or higher. If it is not, a security exception will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param required Whether auto time is set required or not.
@@ -6409,27 +6409,20 @@
      * Returns whether the specified package can read the device identifiers.
      *
      * @param packageName The package name of the app to check for device identifier access.
+     * @param pid The process id of the package to be checked.
+     * @param uid The uid of the package to be checked.
      * @return whether the package can read the device identifiers.
      *
      * @hide
      */
-    public boolean checkDeviceIdentifierAccess(String packageName) {
-        return checkDeviceIdentifierAccessAsUser(packageName, myUserId());
-    }
-
-    /**
-     * @hide
-     */
-    @RequiresPermission(value = android.Manifest.permission.MANAGE_USERS, conditional = true)
-    public boolean checkDeviceIdentifierAccessAsUser(String packageName, int userId) {
-        throwIfParentInstance("checkDeviceIdentifierAccessAsUser");
+    public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) {
+        throwIfParentInstance("checkDeviceIdentifierAccess");
         if (packageName == null) {
             return false;
         }
         if (mService != null) {
             try {
-                return mService.checkDeviceIdentifierAccess(packageName, userId,
-                        Binder.getCallingPid(), Binder.getCallingUid());
+                return mService.checkDeviceIdentifierAccess(packageName, pid, uid);
             } catch (RemoteException re) {
                 throw re.rethrowFromSystemServer();
             }
@@ -10789,8 +10782,8 @@
     }
 
     /**
-     * Returns whether the device is being used as a managed kiosk, as defined in the CDD. As of
-     * this release, these requirements are as follows:
+     * Returns whether the device is being used as a managed kiosk. These requirements are as
+     * follows:
      * <ul>
      *     <li>The device is in Lock Task (therefore there is also a Device Owner app on the
      *     device)</li>
@@ -10829,11 +10822,11 @@
     }
 
     /**
-     * Returns whether the device is being used as an unattended managed kiosk, as defined in the
-     * CDD. As of this release, these requirements are as follows:
+     * Returns whether the device is being used as an unattended managed kiosk. These requirements
+     * are as follows:
      * <ul>
-     *     <li>The device is being used as a managed kiosk, as defined in the CDD and verified at
-     *     {@link #isManagedKiosk()}</li>
+     *     <li>The device is being used as a managed kiosk, as defined at {@link
+     *     #isManagedKiosk()}</li>
      *     <li>The device has not received user input for at least 30 minutes</li>
      * </ul>
      *
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 3c389e4..2b96419 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -156,7 +156,7 @@
     void clearProfileOwner(in ComponentName who);
     boolean hasUserSetupCompleted();
 
-    boolean checkDeviceIdentifierAccess(in String packageName, int userHandle, int pid, int uid);
+    boolean checkDeviceIdentifierAccess(in String packageName, int pid, int uid);
 
     void setDeviceOwnerLockScreenInfo(in ComponentName who, CharSequence deviceOwnerInfo);
     CharSequence getDeviceOwnerLockScreenInfo();
diff --git a/core/java/android/app/prediction/AppTarget.java b/core/java/android/app/prediction/AppTarget.java
index 826c149..ed45b2f 100644
--- a/core/java/android/app/prediction/AppTarget.java
+++ b/core/java/android/app/prediction/AppTarget.java
@@ -223,7 +223,7 @@
          */
         @NonNull
         public Builder setTarget(@NonNull String packageName, @NonNull UserHandle user) {
-            if (mPackageName == null) {
+            if (mPackageName != null) {
                 throw new IllegalArgumentException("Target is already set");
             }
             mPackageName = Preconditions.checkNotNull(packageName);
diff --git a/core/java/android/app/role/RoleControllerManager.java b/core/java/android/app/role/RoleControllerManager.java
index e96c9a5..bd98117 100644
--- a/core/java/android/app/role/RoleControllerManager.java
+++ b/core/java/android/app/role/RoleControllerManager.java
@@ -167,7 +167,7 @@
         RemoteService(@NonNull Context context, @NonNull ComponentName componentName,
                 @NonNull Handler handler, @UserIdInt int userId) {
             super(context, RoleControllerService.SERVICE_INTERFACE, componentName, userId,
-                    service -> Log.e(LOG_TAG, "RemoteService " + service + " died"), handler, false,
+                    service -> Log.e(LOG_TAG, "RemoteService " + service + " died"), handler, 0,
                     false, 1);
         }
 
diff --git a/core/java/android/app/usage/EventList.java b/core/java/android/app/usage/EventList.java
index aaae57e5..8c03405 100644
--- a/core/java/android/app/usage/EventList.java
+++ b/core/java/android/app/usage/EventList.java
@@ -103,4 +103,18 @@
         }
         return result;
     }
+
+    /**
+     * Merge the {@link UsageEvents.Event events} in the given {@link EventList list} into this
+     * list while keeping the list sorted based on the event {@link
+     * UsageEvents.Event#mTimeStamp timestamps}.
+     *
+     * @param events The event list to merge
+     */
+    public void merge(EventList events) {
+        final int size = events.size();
+        for (int i = 0; i < size; i++) {
+            insert(events.get(i));
+        }
+    }
 }
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 26c8218..eb1ea90 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -298,7 +298,10 @@
      *
      * @param intervalType The time interval by which the stats are aggregated.
      * @param beginTime The inclusive beginning of the range of stats to include in the results.
-     * @param endTime The exclusive end of the range of stats to include in the results.
+     *                  Defined in terms of "Unix time", see
+     *                  {@link java.lang.System#currentTimeMillis}.
+     * @param endTime The exclusive end of the range of stats to include in the results. Defined
+     *                in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
      * @return A list of {@link UsageStats}
      *
      * @see #INTERVAL_DAILY
@@ -329,7 +332,10 @@
      *
      * @param intervalType The time interval by which the stats are aggregated.
      * @param beginTime The inclusive beginning of the range of stats to include in the results.
-     * @param endTime The exclusive end of the range of stats to include in the results.
+     *                  Defined in terms of "Unix time", see
+     *                  {@link java.lang.System#currentTimeMillis}.
+     * @param endTime The exclusive end of the range of stats to include in the results. Defined
+     *                in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
      * @return A list of {@link ConfigurationStats}
      */
     public List<ConfigurationStats> queryConfigurations(int intervalType, long beginTime,
@@ -364,7 +370,10 @@
      *
      * @param intervalType The time interval by which the stats are aggregated.
      * @param beginTime The inclusive beginning of the range of stats to include in the results.
-     * @param endTime The exclusive end of the range of stats to include in the results.
+     *                  Defined in terms of "Unix time", see
+     *                  {@link java.lang.System#currentTimeMillis}.
+     * @param endTime The exclusive end of the range of stats to include in the results. Defined
+     *                in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
      * @return A list of {@link EventStats}
      *
      * @see #INTERVAL_DAILY
@@ -393,7 +402,10 @@
      * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
      *
      * @param beginTime The inclusive beginning of the range of events to include in the results.
-     * @param endTime The exclusive end of the range of events to include in the results.
+     *                 Defined in terms of "Unix time", see
+     *                 {@link java.lang.System#currentTimeMillis}.
+     * @param endTime The exclusive end of the range of events to include in the results. Defined
+     *               in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
      * @return A {@link UsageEvents}.
      */
     public UsageEvents queryEvents(long beginTime, long endTime) {
@@ -413,7 +425,10 @@
      * Like {@link #queryEvents(long, long)}, but only returns events for the calling package.
      *
      * @param beginTime The inclusive beginning of the range of events to include in the results.
-     * @param endTime The exclusive end of the range of events to include in the results.
+     *                 Defined in terms of "Unix time", see
+     *                 {@link java.lang.System#currentTimeMillis}.
+     * @param endTime The exclusive end of the range of events to include in the results. Defined
+     *               in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
      * @return A {@link UsageEvents} object.
      *
      * @see #queryEvents(long, long)
@@ -438,7 +453,10 @@
      * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
      *
      * @param beginTime The inclusive beginning of the range of stats to include in the results.
-     * @param endTime The exclusive end of the range of stats to include in the results.
+     *                  Defined in terms of "Unix time", see
+     *                  {@link java.lang.System#currentTimeMillis}.
+     * @param endTime The exclusive end of the range of stats to include in the results. Defined
+     *                in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
      * @return A {@link java.util.Map} keyed by package name
      */
     public Map<String, UsageStats> queryAndAggregateUsageStats(long beginTime, long endTime) {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index fa2c9f8..204d7e3 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -535,7 +535,6 @@
     /**
      * Intent to broadcast silence mode changed.
      * Alway contains the extra field {@link #EXTRA_DEVICE}
-     * Alway contains the extra field {@link #EXTRA_SILENCE_ENABLED}
      *
      * @hide
      */
@@ -545,16 +544,6 @@
             "android.bluetooth.device.action.SILENCE_MODE_CHANGED";
 
     /**
-     * Used as an extra field in {@link #ACTION_SILENCE_MODE_CHANGED} intent,
-     * contains whether device is in silence mode as boolean.
-     *
-     * @hide
-     */
-    @SystemApi
-    public static final String EXTRA_SILENCE_ENABLED =
-            "android.bluetooth.device.extra.SILENCE_ENABLED";
-
-    /**
      * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent.
      *
      * @hide
@@ -1615,7 +1604,8 @@
     }
 
     /**
-     * Set the Bluetooth device silence mode.
+     * Sets whether the {@link BluetoothDevice} enters silence mode. Audio will not
+     * be routed to the {@link BluetoothDevice} if set to {@code true}.
      *
      * When the {@link BluetoothDevice} enters silence mode, and the {@link BluetoothDevice}
      * is an active device (for A2DP or HFP), the active device for that profile
@@ -1635,6 +1625,7 @@
      *
      * @param silence true to enter silence mode, false to exit
      * @return true on success, false on error.
+     * @throws IllegalStateException if Bluetooth is not turned ON.
      * @hide
      */
     @SystemApi
@@ -1642,12 +1633,9 @@
     public boolean setSilenceMode(boolean silence) {
         final IBluetooth service = sService;
         if (service == null) {
-            return false;
+            throw new IllegalStateException("Bluetooth is not turned ON");
         }
         try {
-            if (getSilenceMode() == silence) {
-                return true;
-            }
             return service.setSilenceMode(this, silence);
         } catch (RemoteException e) {
             Log.e(TAG, "setSilenceMode fail", e);
@@ -1656,24 +1644,25 @@
     }
 
     /**
-     * Get the device silence mode status
+     * Check whether the {@link BluetoothDevice} is in silence mode
      *
      * <p> Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
      *
      * @return true on device in silence mode, otherwise false.
+     * @throws IllegalStateException if Bluetooth is not turned ON.
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public boolean getSilenceMode() {
+    public boolean isInSilenceMode() {
         final IBluetooth service = sService;
         if (service == null) {
-            return false;
+            throw new IllegalStateException("Bluetooth is not turned ON");
         }
         try {
             return service.getSilenceMode(this);
         } catch (RemoteException e) {
-            Log.e(TAG, "getSilenceMode fail", e);
+            Log.e(TAG, "isInSilenceMode fail", e);
             return false;
         }
     }
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index e2e56fd..5fd60e0 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -99,6 +99,11 @@
     @Deprecated
     public static final int CHANNEL_TYPE_STREAMING = 11;
 
+    /**
+     * Hide auto-created default constructor
+     * @hide
+     */
+    BluetoothHealth() {}
 
     /**
      * Register an application configuration that acts as a Health SINK.
diff --git a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
index 88e06e5..2f66df2 100644
--- a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
+++ b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java
@@ -33,6 +33,13 @@
  */
 @Deprecated
 public final class BluetoothHealthAppConfiguration implements Parcelable {
+
+    /**
+     * Hide auto-created default constructor
+     * @hide
+     */
+    BluetoothHealthAppConfiguration() {}
+
     @Override
     public int describeContents() {
         return 0;
diff --git a/core/java/android/content/ComponentName.java b/core/java/android/content/ComponentName.java
index a5460e9..18147b5 100644
--- a/core/java/android/content/ComponentName.java
+++ b/core/java/android/content/ComponentName.java
@@ -339,6 +339,8 @@
     }
 
     public void writeToParcel(Parcel out, int flags) {
+        // WARNING: If you modify this function, also update
+        // frameworks/base/libs/services/src/content/ComponentName.cpp.
         out.writeString(mPackage);
         out.writeString(mClass);
     }
diff --git a/core/java/android/content/ContentCaptureOptions.java b/core/java/android/content/ContentCaptureOptions.java
index 1727d34..76c4fb8 100644
--- a/core/java/android/content/ContentCaptureOptions.java
+++ b/core/java/android/content/ContentCaptureOptions.java
@@ -136,13 +136,18 @@
     @Override
     public String toString() {
         if (lite) {
-            return "ContentCaptureOptions [(lite) loggingLevel=" + loggingLevel + "]";
+            return "ContentCaptureOptions [loggingLevel=" + loggingLevel + " (lite)]";
         }
-        return "ContentCaptureOptions [loggingLevel=" + loggingLevel + ", maxBufferSize="
-                + maxBufferSize + ", idleFlushingFrequencyMs=" + idleFlushingFrequencyMs
-                + ", textChangeFlushingFrequencyMs=" + textChangeFlushingFrequencyMs
-                + ", logHistorySize=" + logHistorySize + ", whitelistedComponents="
-                + whitelistedComponents + "]";
+        final StringBuilder string = new StringBuilder("ContentCaptureOptions [");
+        string.append("loggingLevel=").append(loggingLevel)
+            .append(", maxBufferSize=").append(maxBufferSize)
+            .append(", idleFlushingFrequencyMs=").append(idleFlushingFrequencyMs)
+            .append(", textChangeFlushingFrequencyMs=").append(textChangeFlushingFrequencyMs)
+            .append(", logHistorySize=").append(logHistorySize);
+        if (whitelistedComponents != null) {
+            string.append(", whitelisted=").append(whitelistedComponents);
+        }
+        return string.append(']').toString();
     }
 
     /** @hide */
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index fa85f0a..791c551 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1313,6 +1313,12 @@
     public final @Nullable ParcelFileDescriptor openFileDescriptor(@NonNull Uri uri,
             @NonNull String mode, @Nullable CancellationSignal cancellationSignal)
                     throws FileNotFoundException {
+        try {
+            if (mWrapped != null) return mWrapped.openFile(uri, mode, cancellationSignal);
+        } catch (RemoteException e) {
+            return null;
+        }
+
         AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode, cancellationSignal);
         if (afd == null) {
             return null;
@@ -1455,6 +1461,12 @@
         Preconditions.checkNotNull(uri, "uri");
         Preconditions.checkNotNull(mode, "mode");
 
+        try {
+            if (mWrapped != null) return mWrapped.openAssetFile(uri, mode, cancellationSignal);
+        } catch (RemoteException e) {
+            return null;
+        }
+
         String scheme = uri.getScheme();
         if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
             if (!"r".equals(mode)) {
@@ -1634,6 +1646,12 @@
         Preconditions.checkNotNull(uri, "uri");
         Preconditions.checkNotNull(mimeType, "mimeType");
 
+        try {
+            if (mWrapped != null) return mWrapped.openTypedAssetFile(uri, mimeType, opts, cancellationSignal);
+        } catch (RemoteException e) {
+            return null;
+        }
+
         IContentProvider unstableProvider = acquireUnstableProvider(uri);
         if (unstableProvider == null) {
             throw new FileNotFoundException("No content provider: " + uri);
@@ -3525,12 +3543,7 @@
      */
     public @NonNull Bitmap loadThumbnail(@NonNull Uri uri, @NonNull Size size,
             @Nullable CancellationSignal signal) throws IOException {
-        Objects.requireNonNull(uri);
-        Objects.requireNonNull(size);
-
-        try (ContentProviderClient client = acquireContentProviderClient(uri)) {
-            return loadThumbnail(client, uri, size, signal, ImageDecoder.ALLOCATOR_SOFTWARE);
-        }
+        return loadThumbnail(this, uri, size, signal, ImageDecoder.ALLOCATOR_SOFTWARE);
     }
 
     /** {@hide} */
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index d7a2e1b..af738da 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -427,7 +427,7 @@
      * invisible background activities.  This will impact the number of
      * recent activities the user can switch between without having them
      * restart.  There is no guarantee this will be respected, as the system
-     * tries to balance such requests from one app vs. the importantance of
+     * tries to balance such requests from one app vs. the importance of
      * keeping other apps around.
      */
     public static final int BIND_VISIBLE = 0x10000000;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 032e5ac..d87171e 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3115,21 +3115,14 @@
      * <p>
      * The path to the file is contained in {@link Intent#getData()}.
      *
-     * @deprecated Starting in the {@link android.os.Build.VERSION_CODES#Q}
-     *             release, shared storage paths are sandboxed per application,
-     *             and this broadcast cannot correctly translate those sandboxed
-     *             paths. Callers will need to instead migrate to using
-     *             {@link MediaScannerConnection}.
+     * @deprecated Callers should migrate to inserting items directly into
+     *             {@link MediaStore}, where they will be automatically scanned
+     *             after each mutation.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @Deprecated
     public static final String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE";
 
-    /** @hide */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @Deprecated
-    public static final String ACTION_MEDIA_SCANNER_SCAN_VOLUME = "android.intent.action.MEDIA_SCANNER_SCAN_VOLUME";
-
    /**
      * Broadcast Action:  The "Media Button" was pressed.  Includes a single
      * extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that
diff --git a/core/java/android/content/LocusId.java b/core/java/android/content/LocusId.java
index c67ff7c..283cea0 100644
--- a/core/java/android/content/LocusId.java
+++ b/core/java/android/content/LocusId.java
@@ -18,19 +18,50 @@
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.view.contentcapture.ContentCaptureManager;
 
 import com.android.internal.util.Preconditions;
 
 import java.io.PrintWriter;
 
 /**
- * Identifier for an unique state in the application.
+ * An identifier for an unique state (locus) in the application. Should be stable across reboots and
+ * backup / restore.
  *
- * <p>Should be stable across reboots and backup / restore.
+ * <p>Locus is a new concept introduced on
+ * {@link android.os.Build.VERSION_CODES#Q Android Q} and it lets the intelligence service provided
+ * by the Android System to correlate state between different subsystems such as content capture,
+ * shortcuts, and notifications.
  *
- * <p>For example, a chat app could use the context to resume a conversation between 2 users.
+ * <p>For example, if your app provides an activiy representing a chat between 2 users
+ * (say {@code A} and {@code B}, this chat state could be represented by:
+ *
+ * <pre><code>
+ * LocusId chatId = new LocusId("Chat_A_B");
+ * </code></pre>
+ *
+ * <p>And then you should use that {@code chatId} by:
+ *
+ * <ul>
+ *   <li>Setting it in the chat notification (through
+ *   {@link android.app.Notification.Builder#setLocusId(LocusId)
+ *   Notification.Builder.setLocusId(chatId)}).
+ *   <li>Setting it into the {@link android.content.pm.ShortcutInfo} (through
+ *   {@link android.content.pm.ShortcutInfo.Builder#setLocusId(LocusId)
+ *   ShortcutInfo.Builder.setLocusId(chatId)}), if you provide a launcher shortcut for that chat
+ *   conversation.
+ *   <li>Associating it with the {@link android.view.contentcapture.ContentCaptureContext} of the
+ *   root view of the chat conversation activity (through
+ *   {@link android.view.View#getContentCaptureSession()}, then
+ *   {@link android.view.contentcapture.ContentCaptureContext.Builder
+ *   new ContentCaptureContext.Builder(chatId).build()} and
+ *   {@link android.view.contentcapture.ContentCaptureSession#setContentCaptureContext(
+ *   android.view.contentcapture.ContentCaptureContext)} - see {@link ContentCaptureManager}
+ *   for more info about content capture).
+ *   <li>Configuring your app to launch the chat conversation through the
+ *   {@link Intent#ACTION_VIEW_LOCUS} intent.
+ * </ul>
  */
-// TODO(b/123577059): make sure this is well documented and understandable
 public final class LocusId implements Parcelable {
 
     private final String mId;
@@ -45,7 +76,7 @@
     }
 
     /**
-     * Gets the {@code id} associated with the locus.
+     * Gets the canonical {@code id} associated with the locus.
      */
     @NonNull
     public String getId() {
@@ -100,7 +131,7 @@
         parcel.writeString(mId);
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<LocusId> CREATOR =
+    public static final @NonNull Parcelable.Creator<LocusId> CREATOR =
             new Parcelable.Creator<LocusId>() {
 
         @NonNull
diff --git a/core/java/android/content/LoggingContentInterface.java b/core/java/android/content/LoggingContentInterface.java
index 6e12a57..83c0c91 100644
--- a/core/java/android/content/LoggingContentInterface.java
+++ b/core/java/android/content/LoggingContentInterface.java
@@ -48,191 +48,197 @@
         this.delegate = delegate;
     }
 
-    private void log(String method, Object res, Object... args) {
-        // First, force-unparcel any bundles so we can log them
-        for (Object arg : args) {
-            if (arg instanceof Bundle) {
-                ((Bundle) arg).size();
+    private class Logger implements AutoCloseable {
+        private final StringBuilder sb = new StringBuilder();
+
+        public Logger(String method, Object... args) {
+            // First, force-unparcel any bundles so we can log them
+            for (Object arg : args) {
+                if (arg instanceof Bundle) {
+                    ((Bundle) arg).size();
+                }
+            }
+
+            sb.append("callingUid=").append(Binder.getCallingUid()).append(' ');
+            sb.append(method);
+            sb.append('(').append(deepToString(args)).append(')');
+        }
+
+        private String deepToString(Object value) {
+            if (value != null && value.getClass().isArray()) {
+                return Arrays.deepToString((Object[]) value);
+            } else {
+                return String.valueOf(value);
             }
         }
 
-        final StringBuilder sb = new StringBuilder();
-        sb.append("callingUid=").append(Binder.getCallingUid()).append(' ');
-        sb.append(method);
-        sb.append('(').append(deepToString(args)).append(')');
-        if (res instanceof Cursor) {
-            sb.append('\n');
-            DatabaseUtils.dumpCursor((Cursor) res, sb);
-        } else {
-            sb.append(" = ").append(deepToString(res));
+        public <T> T setResult(T res) {
+            if (res instanceof Cursor) {
+                sb.append('\n');
+                DatabaseUtils.dumpCursor((Cursor) res, sb);
+            } else {
+                sb.append(" = ").append(deepToString(res));
+            }
+            return res;
         }
 
-        if (res instanceof Exception) {
-            Log.e(tag, sb.toString());
-        } else {
+        @Override
+        public void close() {
             Log.v(tag, sb.toString());
         }
     }
 
-    private String deepToString(Object value) {
-        if (value != null && value.getClass().isArray()) {
-            return Arrays.deepToString((Object[]) value);
-        } else {
-            return String.valueOf(value);
-        }
-    }
-
     @Override
     public @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection,
             @Nullable Bundle queryArgs, @Nullable CancellationSignal cancellationSignal)
             throws RemoteException {
-        try {
-            final Cursor res = delegate.query(uri, projection, queryArgs, cancellationSignal);
-            log("query", res, uri, projection, queryArgs, cancellationSignal);
-            return res;
-        } catch (Exception res) {
-            log("query", res, uri, projection, queryArgs, cancellationSignal);
-            throw res;
+        try (Logger l = new Logger("query", uri, projection, queryArgs, cancellationSignal)) {
+            try {
+                return l.setResult(delegate.query(uri, projection, queryArgs, cancellationSignal));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public @Nullable String getType(@NonNull Uri uri) throws RemoteException {
-        try {
-            final String res = delegate.getType(uri);
-            log("getType", res, uri);
-            return res;
-        } catch (Exception res) {
-            log("getType", res, uri);
-            throw res;
+        try (Logger l = new Logger("getType", uri)) {
+            try {
+                return l.setResult(delegate.getType(uri));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public @Nullable String[] getStreamTypes(@NonNull Uri uri, @NonNull String mimeTypeFilter)
             throws RemoteException {
-        try {
-            final String[] res = delegate.getStreamTypes(uri, mimeTypeFilter);
-            log("getStreamTypes", res, uri, mimeTypeFilter);
-            return res;
-        } catch (Exception res) {
-            log("getStreamTypes", res, uri, mimeTypeFilter);
-            throw res;
+        try (Logger l = new Logger("getStreamTypes", uri, mimeTypeFilter)) {
+            try {
+                return l.setResult(delegate.getStreamTypes(uri, mimeTypeFilter));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public @Nullable Uri canonicalize(@NonNull Uri uri) throws RemoteException {
-        try {
-            final Uri res = delegate.canonicalize(uri);
-            log("canonicalize", res, uri);
-            return res;
-        } catch (Exception res) {
-            log("canonicalize", res, uri);
-            throw res;
+        try (Logger l = new Logger("canonicalize", uri)) {
+            try {
+                return l.setResult(delegate.canonicalize(uri));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public @Nullable Uri uncanonicalize(@NonNull Uri uri) throws RemoteException {
-        try {
-            final Uri res = delegate.uncanonicalize(uri);
-            log("uncanonicalize", res, uri);
-            return res;
-        } catch (Exception res) {
-            log("uncanonicalize", res, uri);
-            throw res;
+        try (Logger l = new Logger("uncanonicalize", uri)) {
+            try {
+                return l.setResult(delegate.uncanonicalize(uri));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public boolean refresh(@NonNull Uri uri, @Nullable Bundle args,
             @Nullable CancellationSignal cancellationSignal) throws RemoteException {
-        try {
-            final boolean res = delegate.refresh(uri, args, cancellationSignal);
-            log("refresh", res, uri, args, cancellationSignal);
-            return res;
-        } catch (Exception res) {
-            log("refresh", res, uri, args, cancellationSignal);
-            throw res;
+        try (Logger l = new Logger("refresh", uri, args, cancellationSignal)) {
+            try {
+                return l.setResult(delegate.refresh(uri, args, cancellationSignal));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
             throws RemoteException {
-        try {
-            final Uri res = delegate.insert(uri, initialValues);
-            log("insert", res, uri, initialValues);
-            return res;
-        } catch (Exception res) {
-            log("insert", res, uri, initialValues);
-            throw res;
+        try (Logger l = new Logger("insert", uri, initialValues)) {
+            try {
+                return l.setResult(delegate.insert(uri, initialValues));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] initialValues)
             throws RemoteException {
-        try {
-            final int res = delegate.bulkInsert(uri, initialValues);
-            log("bulkInsert", res, uri, initialValues);
-            return res;
-        } catch (Exception res) {
-            log("bulkInsert", res, uri, initialValues);
-            throw res;
+        try (Logger l = new Logger("bulkInsert", uri, initialValues)) {
+            try {
+                return l.setResult(delegate.bulkInsert(uri, initialValues));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public int delete(@NonNull Uri uri, @Nullable String selection,
             @Nullable String[] selectionArgs) throws RemoteException {
-        try {
-            final int res = delegate.delete(uri, selection, selectionArgs);
-            log("delete", res, uri, selection, selectionArgs);
-            return res;
-        } catch (Exception res) {
-            log("delete", res, uri, selection, selectionArgs);
-            throw res;
+        try (Logger l = new Logger("delete", uri, selection, selectionArgs)) {
+            try {
+                return l.setResult(delegate.delete(uri, selection, selectionArgs));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
             @Nullable String[] selectionArgs) throws RemoteException {
-        try {
-            final int res = delegate.update(uri, values, selection, selectionArgs);
-            log("update", res, uri, values, selection, selectionArgs);
-            return res;
-        } catch (Exception res) {
-            log("update", res, uri, values, selection, selectionArgs);
-            throw res;
+        try (Logger l = new Logger("update", uri, values, selection, selectionArgs)) {
+            try {
+                return l.setResult(delegate.update(uri, values, selection, selectionArgs));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public @Nullable ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode,
             @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
-        try {
-            final ParcelFileDescriptor res = delegate.openFile(uri, mode, signal);
-            log("openFile", res, uri, mode, signal);
-            return res;
-        } catch (Exception res) {
-            log("openFile", res, uri, mode, signal);
-            throw res;
+        try (Logger l = new Logger("openFile", uri, mode, signal)) {
+            try {
+                return l.setResult(delegate.openFile(uri, mode, signal));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public @Nullable AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode,
             @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
-        try {
-            final AssetFileDescriptor res = delegate.openAssetFile(uri, mode, signal);
-            log("openAssetFile", res, uri, mode, signal);
-            return res;
-        } catch (Exception res) {
-            log("openAssetFile", res, uri, mode, signal);
-            throw res;
+        try (Logger l = new Logger("openAssetFile", uri, mode, signal)) {
+            try {
+                return l.setResult(delegate.openAssetFile(uri, mode, signal));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
@@ -240,13 +246,13 @@
     public @Nullable AssetFileDescriptor openTypedAssetFile(@NonNull Uri uri,
             @NonNull String mimeTypeFilter, @Nullable Bundle opts,
             @Nullable CancellationSignal signal) throws RemoteException, FileNotFoundException {
-        try {
-            final AssetFileDescriptor res = delegate.openTypedAssetFile(uri, mimeTypeFilter, opts, signal);
-            log("openTypedAssetFile", res, uri, mimeTypeFilter, opts, signal);
-            return res;
-        } catch (Exception res) {
-            log("openTypedAssetFile", res, uri, mimeTypeFilter, opts, signal);
-            throw res;
+        try (Logger l = new Logger("openTypedAssetFile", uri, mimeTypeFilter, opts, signal)) {
+            try {
+                return l.setResult(delegate.openTypedAssetFile(uri, mimeTypeFilter, opts, signal));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
@@ -254,26 +260,26 @@
     public @NonNull ContentProviderResult[] applyBatch(@NonNull String authority,
             @NonNull ArrayList<ContentProviderOperation> operations)
             throws RemoteException, OperationApplicationException {
-        try {
-            final ContentProviderResult[] res = delegate.applyBatch(authority, operations);
-            log("applyBatch", res, authority, operations);
-            return res;
-        } catch (Exception res) {
-            log("applyBatch", res, authority, operations);
-            throw res;
+        try (Logger l = new Logger("applyBatch", authority, operations)) {
+            try {
+                return l.setResult(delegate.applyBatch(authority, operations));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 
     @Override
     public @Nullable Bundle call(@NonNull String authority, @NonNull String method,
             @Nullable String arg, @Nullable Bundle extras) throws RemoteException {
-        try {
-            final Bundle res = delegate.call(authority, method, arg, extras);
-            log("call", res, authority, method, arg, extras);
-            return res;
-        } catch (Exception res) {
-            log("call", res, authority, method, arg, extras);
-            throw res;
+        try (Logger l = new Logger("call", authority, method, arg, extras)) {
+            try {
+                return l.setResult(delegate.call(authority, method, arg, extras));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
         }
     }
 }
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
index aabe59d..fc79a42 100644
--- a/core/java/android/content/om/OverlayInfo.java
+++ b/core/java/android/content/om/OverlayInfo.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.UserIdInt;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -44,8 +45,9 @@
             STATE_DISABLED,
             STATE_ENABLED,
             STATE_ENABLED_STATIC,
-            STATE_TARGET_UPGRADING,
-            STATE_OVERLAY_UPGRADING,
+            // @Deprecated STATE_TARGET_UPGRADING,
+            STATE_TARGET_IS_BEING_REPLACED,
+            STATE_OVERLAY_IS_BEING_REPLACED,
     })
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -93,18 +95,25 @@
     public static final int STATE_ENABLED = 3;
 
     /**
-     * The target package is currently being upgraded; the state will change
-     * once the package installation has finished.
+     * The target package is currently being upgraded or downgraded; the state
+     * will change once the package installation has finished.
      * @hide
+     *
+     * @deprecated No longer used. Caused invalid transitions from enabled -> upgrading -> enabled,
+     * where an update is propagated when nothing has changed. Can occur during --dont-kill
+     * installs when code and resources are hot swapped and the Activity should not be relaunched.
+     * In all other cases, the process and therefore Activity is killed, so the state loop is
+     * irrelevant.
      */
-    public static final int STATE_TARGET_UPGRADING = 4;
+    @Deprecated
+    public static final int STATE_TARGET_IS_BEING_REPLACED = 4;
 
     /**
-     * The overlay package is currently being upgraded; the state will change
-     * once the package installation has finished.
+     * The overlay package is currently being upgraded or downgraded; the state
+     * will change once the package installation has finished.
      * @hide
      */
-    public static final int STATE_OVERLAY_UPGRADING = 5;
+    public static final int STATE_OVERLAY_IS_BEING_REPLACED = 5;
 
     /**
      * The overlay package is currently enabled because it is marked as
@@ -128,7 +137,6 @@
      *
      * @hide
      */
-    @SystemApi
     public final String packageName;
 
     /**
@@ -136,7 +144,6 @@
      *
      * @hide
      */
-    @SystemApi
     public final String targetPackageName;
 
     /**
@@ -144,7 +151,6 @@
      *
      * @hide
      */
-    @SystemApi
     public final String targetOverlayableName;
 
     /**
@@ -152,7 +158,6 @@
      *
      * @hide
      */
-    @SystemApi
     public final String category;
 
     /**
@@ -171,7 +176,6 @@
      * User handle for which this overlay applies
      * @hide
      */
-    @SystemApi
     public final int userId;
 
     /**
@@ -236,6 +240,56 @@
         ensureValidState();
     }
 
+    /**
+     * Returns package name of the current overlay.
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    public String getPackageName() {
+        return packageName;
+    }
+
+    /**
+     * Returns the target package name of the current overlay.
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    public String getTargetPackageName() {
+        return targetPackageName;
+    }
+
+    /**
+     * Returns the category of the current overlay.
+     * @hide\
+     */
+    @SystemApi
+    @Nullable
+    public String getCategory() {
+        return category;
+    }
+
+    /**
+     * Returns user handle for which this overlay applies to.
+     * @hide
+     */
+    @SystemApi
+    @UserIdInt
+    public int getUserId() {
+        return userId;
+    }
+
+    /**
+     * Returns name of the target overlayable declaration.
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getTargetOverlayableName() {
+        return targetOverlayableName;
+    }
+
     private void ensureValidState() {
         if (packageName == null) {
             throw new IllegalArgumentException("packageName must not be null");
@@ -253,8 +307,8 @@
             case STATE_DISABLED:
             case STATE_ENABLED:
             case STATE_ENABLED_STATIC:
-            case STATE_TARGET_UPGRADING:
-            case STATE_OVERLAY_UPGRADING:
+            case STATE_TARGET_IS_BEING_REPLACED:
+            case STATE_OVERLAY_IS_BEING_REPLACED:
                 break;
             default:
                 throw new IllegalArgumentException("State " + state + " is not a valid state");
@@ -333,10 +387,10 @@
                 return "STATE_ENABLED";
             case STATE_ENABLED_STATIC:
                 return "STATE_ENABLED_STATIC";
-            case STATE_TARGET_UPGRADING:
-                return "STATE_TARGET_UPGRADING";
-            case STATE_OVERLAY_UPGRADING:
-                return "STATE_OVERLAY_UPGRADING";
+            case STATE_TARGET_IS_BEING_REPLACED:
+                return "STATE_TARGET_IS_BEING_REPLACED";
+            case STATE_OVERLAY_IS_BEING_REPLACED:
+                return "STATE_OVERLAY_IS_BEING_REPLACED";
             default:
                 return "<unknown state>";
         }
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 068a93a..1c2afd2 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -678,6 +678,21 @@
      */
     public static final int PRIVATE_FLAG_IS_RESOURCE_OVERLAY = 1 << 28;
 
+    /**
+     * Value for {@link #privateFlags}: If {@code true} this app allows
+     * shared/external storage media to be a sandboxed view that only contains
+     * files owned by the app.
+     *
+     * @hide
+     */
+    public static final int PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX = 1 << 29;
+
+    /**
+     * Value for {@link #privateFlags}: whether this app is pre-installed on the
+     * ODM partition of the system image.
+     * @hide
+     */
+    public static final int PRIVATE_FLAG_ODM = 1 << 30;
 
     /** @hide */
     @IntDef(flag = true, prefix = { "PRIVATE_FLAG_" }, value = {
@@ -707,7 +722,9 @@
             PRIVATE_FLAG_VIRTUAL_PRELOAD,
             PRIVATE_FLAG_HAS_FRAGILE_USER_DATA,
             PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE,
-            PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE
+            PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE,
+            PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX,
+            PRIVATE_FLAG_ODM,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ApplicationInfoPrivateFlags {}
@@ -1822,6 +1839,16 @@
         return (privateFlags & PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE) != 0;
     }
 
+    /**
+     * If {@code true} this app allows shared/external storage media to be a
+     * sandboxed view that only contains files owned by the app.
+     *
+     * @hide
+     */
+    public boolean isExternalStorageSandboxAllowed() {
+        return (privateFlags & PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX) != 0;
+    }
+
     private boolean isAllowedToUseHiddenApis() {
         if (isSignedWithPlatformKey()) {
             return true;
@@ -1951,6 +1978,11 @@
     }
 
     /** @hide */
+    public boolean isOdm() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0;
+    }
+
+    /** @hide */
     public boolean isPartiallyDirectBootAware() {
         return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE) != 0;
     }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c798270..fb22187 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -740,6 +740,8 @@
 
     String getSystemTextClassifierPackageName();
 
+    String getAttentionServicePackageName();
+
     String getWellbeingPackageName();
 
     String getAppPredictionServicePackageName();
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 954deac..037a149 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
@@ -782,8 +783,10 @@
      * @return an {@link AppUsageLimit} object describing the app time limit containing
      * the given package with the smallest time remaining, or {@code null} if none exist.
      * @throws SecurityException when the caller is not the recents app.
+     * @hide
      */
     @Nullable
+    @SystemApi
     public LauncherApps.AppUsageLimit getAppUsageLimit(@NonNull String packageName,
             @NonNull UserHandle user) {
         try {
@@ -1739,7 +1742,9 @@
      * in this class.
      *
      * @see #getAppUsageLimit(String, UserHandle)
+     * @hide
      */
+    @SystemApi
     public static final class AppUsageLimit implements Parcelable {
         private final long mTotalUsageLimit;
         private final long mUsageRemaining;
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3edd17a..a96316b 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -497,6 +497,36 @@
     }
 
     /**
+     * Returns an active staged session, or {@code null} if there is none.
+     *
+     * <p>Staged session is active iff:
+     * <ul>
+     *     <li>It is committed.
+     *     <li>It is not applied.
+     *     <li>It is not failed.
+     * </ul>
+     *
+     * <p>In case of a multi-apk session, parent session will be returned.
+     */
+    public @Nullable SessionInfo getActiveStagedSession() {
+        final List<SessionInfo> stagedSessions = getStagedSessions();
+        for (SessionInfo s : stagedSessions) {
+            if (s.isStagedSessionApplied() || s.isStagedSessionFailed()) {
+                // Finalized session.
+                continue;
+            }
+            if (s.getParentSessionId() != SessionInfo.INVALID_ID) {
+                // Child session.
+                continue;
+            }
+            if (s.isCommitted()) {
+                return s;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Uninstall the given package, removing it completely from the device. This
      * method is available to:
      * <ul>
@@ -1181,6 +1211,9 @@
          * Adds a session ID to the set of sessions that will be committed atomically
          * when this session is committed.
          *
+         * <p>If the parent is staged or has rollback enabled, all children must have
+         * the same properties.
+         *
          * @param sessionId the session ID to add to this multi-package session.
          */
         public void addChildSessionId(int sessionId) {
@@ -1450,6 +1483,9 @@
         /**
          * Request that rollbacks be enabled or disabled for the given upgrade.
          *
+         * <p>If the parent session is staged or has rollback enabled, all children sessions
+         * must have the same properties.
+         *
          * @param enable set to {@code true} to enable, {@code false} to disable
          * @hide
          */
@@ -1577,6 +1613,9 @@
          * multi-package. In that case, if any of the children sessions fail to install at reboot,
          * all the other children sessions are aborted as well.
          *
+         * <p>If the parent session is staged or has rollback enabled, all children sessions
+         * must have the same properties.
+         *
          * {@hide}
          */
         @SystemApi @TestApi
@@ -1596,6 +1635,11 @@
             installFlags |= PackageManager.INSTALL_APEX;
         }
 
+        /** @hide */
+        public boolean getEnableRollback() {
+            return (installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0;
+        }
+
         /** {@hide} */
         public void dump(IndentingPrintWriter pw) {
             pw.printPair("mode", mode);
@@ -1770,6 +1814,9 @@
         private String mStagedSessionErrorMessage;
 
         /** {@hide} */
+        public boolean isCommitted;
+
+        /** {@hide} */
         @UnsupportedAppUsage
         public SessionInfo() {
         }
@@ -1809,6 +1856,7 @@
             isStagedSessionFailed = source.readBoolean();
             mStagedSessionErrorCode = source.readInt();
             mStagedSessionErrorMessage = source.readString();
+            isCommitted = source.readBoolean();
         }
 
         /**
@@ -2118,6 +2166,7 @@
          * Returns the set of session IDs that will be committed when this session is commited if
          * this session is a multi-package session.
          */
+        @NonNull
         public int[] getChildSessionIds() {
             return childSessionIds;
         }
@@ -2181,6 +2230,13 @@
             mStagedSessionErrorMessage = errorMessage;
         }
 
+        /**
+         * Whenever this session was committed.
+         */
+        public boolean isCommitted() {
+            return isCommitted;
+        }
+
         @Override
         public int describeContents() {
             return 0;
@@ -2218,6 +2274,7 @@
             dest.writeBoolean(isStagedSessionFailed);
             dest.writeInt(mStagedSessionErrorCode);
             dest.writeString(mStagedSessionErrorMessage);
+            dest.writeBoolean(isCommitted);
         }
 
         public static final Parcelable.Creator<SessionInfo>
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 961faa0c..f0539c49 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1397,6 +1397,14 @@
      */
     public static final int INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS = -119;
 
+    /**
+     * Installation failed return code: one of the child sessions does not match the parent session
+     * in respect to staged or rollback enabled parameters.
+     *
+     * @hide
+     */
+    public static final int INSTALL_FAILED_MULTIPACKAGE_INCONSISTENCY = -120;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "DELETE_" }, value = {
             DELETE_KEEP_DATA,
@@ -2990,6 +2998,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public static final int FLAG_PERMISSION_POLICY_FIXED =  1 << 2;
 
     /**
@@ -3013,6 +3022,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public static final int FLAG_PERMISSION_SYSTEM_FIXED =  1 << 4;
 
     /**
@@ -3065,15 +3075,6 @@
     public static final int FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED =  1 << 9;
 
     /**
-     * Permission flag: The permission should not be shown in the UI.
-     *
-     * @hide
-     */
-    @SystemApi
-    @TestApi
-    public static final int FLAG_PERMISSION_HIDDEN =  1 << 10;
-
-    /**
      * Mask for all permission flags present in Android P
      *
      * @deprecated This constant does not contain useful information and should never have been
@@ -3091,7 +3092,7 @@
      *
      * @hide
      */
-    public static final int MASK_PERMISSION_FLAGS_ALL = 0x7FF;
+    public static final int MASK_PERMISSION_FLAGS_ALL = 0x3FF;
 
     /**
      * Injected activity in app that forwards user to setting activity of that app.
@@ -3214,7 +3215,8 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract PackageInfo getPackageInfo(String packageName, @PackageInfoFlags int flags)
+    public abstract PackageInfo getPackageInfo(@NonNull String packageName,
+            @PackageInfoFlags int flags)
             throws NameNotFoundException;
 
     /**
@@ -3239,7 +3241,7 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract PackageInfo getPackageInfo(VersionedPackage versionedPackage,
+    public abstract PackageInfo getPackageInfo(@NonNull VersionedPackage versionedPackage,
             @PackageInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3263,25 +3265,25 @@
      */
     @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
     @UnsupportedAppUsage
-    public abstract PackageInfo getPackageInfoAsUser(String packageName,
+    public abstract PackageInfo getPackageInfoAsUser(@NonNull String packageName,
             @PackageInfoFlags int flags, @UserIdInt int userId) throws NameNotFoundException;
 
     /**
      * Map from the current package names in use on the device to whatever
      * the current canonical name of that package is.
-     * @param names Array of current names to be mapped.
+     * @param packageNames Array of current names to be mapped.
      * @return Returns an array of the same size as the original, containing
      * the canonical name for each package.
      */
-    public abstract String[] currentToCanonicalPackageNames(String[] names);
+    public abstract String[] currentToCanonicalPackageNames(@NonNull String[] packageNames);
 
     /**
      * Map from a packages canonical name to the current name in use on the device.
-     * @param names Array of new names to be mapped.
+     * @param packageNames Array of new names to be mapped.
      * @return Returns an array of the same size as the original, containing
      * the current name for each package.
      */
-    public abstract String[] canonicalToCurrentPackageNames(String[] names);
+    public abstract String[] canonicalToCurrentPackageNames(@NonNull String[] packageNames);
 
     /**
      * Returns a "good" intent to launch a front-door activity in a package.
@@ -3360,7 +3362,7 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract int[] getPackageGids(String packageName, @PackageInfoFlags int flags)
+    public abstract int[] getPackageGids(@NonNull String packageName, @PackageInfoFlags int flags)
             throws NameNotFoundException;
 
     /**
@@ -3375,7 +3377,7 @@
      * @throws NameNotFoundException if a package with the given name can not be
      *             found on the system.
      */
-    public abstract int getPackageUid(String packageName, @PackageInfoFlags int flags)
+    public abstract int getPackageUid(@NonNull String packageName, @PackageInfoFlags int flags)
             throws NameNotFoundException;
 
     /**
@@ -3393,7 +3395,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract int getPackageUidAsUser(String packageName, @UserIdInt int userId)
+    public abstract int getPackageUidAsUser(@NonNull String packageName, @UserIdInt int userId)
             throws NameNotFoundException;
 
     /**
@@ -3411,13 +3413,13 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract int getPackageUidAsUser(String packageName, @PackageInfoFlags int flags,
-            @UserIdInt int userId) throws NameNotFoundException;
+    public abstract int getPackageUidAsUser(@NonNull String packageName,
+            @PackageInfoFlags int flags, @UserIdInt int userId) throws NameNotFoundException;
 
     /**
      * Retrieve all of the information we know about a particular permission.
      *
-     * @param name The fully qualified name (i.e. com.google.permission.LOGIN)
+     * @param permissionName The fully qualified name (i.e. com.google.permission.LOGIN)
      *            of the permission you are interested in.
      * @param flags Additional option flags to modify the data returned.
      * @return Returns a {@link PermissionInfo} containing information about the
@@ -3425,13 +3427,13 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract PermissionInfo getPermissionInfo(String name, @PermissionInfoFlags int flags)
-            throws NameNotFoundException;
+    public abstract PermissionInfo getPermissionInfo(@NonNull String permissionName,
+            @PermissionInfoFlags int flags) throws NameNotFoundException;
 
     /**
      * Query for all of the permissions associated with a particular group.
      *
-     * @param group The fully qualified name (i.e. com.google.permission.LOGIN)
+     * @param permissionGroup The fully qualified name (i.e. com.google.permission.LOGIN)
      *            of the permission group you are interested in. Use null to
      *            find all of the permissions not associated with a group.
      * @param flags Additional option flags to modify the data returned.
@@ -3440,7 +3442,8 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract List<PermissionInfo> queryPermissionsByGroup(String group,
+    @NonNull
+    public abstract List<PermissionInfo> queryPermissionsByGroup(@NonNull String permissionGroup,
             @PermissionInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3465,7 +3468,7 @@
      * Retrieve all of the information we know about a particular group of
      * permissions.
      *
-     * @param name The fully qualified name (i.e.
+     * @param permissionName The fully qualified name (i.e.
      *            com.google.permission_group.APPS) of the permission you are
      *            interested in.
      * @param flags Additional option flags to modify the data returned.
@@ -3474,7 +3477,8 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract PermissionGroupInfo getPermissionGroupInfo(String name,
+    @NonNull
+    public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String permissionName,
             @PermissionGroupInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3484,6 +3488,7 @@
      * @return Returns a list of {@link PermissionGroupInfo} containing
      *         information about all of the known permission groups.
      */
+    @NonNull
     public abstract List<PermissionGroupInfo> getAllPermissionGroups(
             @PermissionGroupInfoFlags int flags);
 
@@ -3504,12 +3509,14 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract ApplicationInfo getApplicationInfo(String packageName,
+    @NonNull
+    public abstract ApplicationInfo getApplicationInfo(@NonNull String packageName,
             @ApplicationInfoFlags int flags) throws NameNotFoundException;
 
     /** {@hide} */
+    @NonNull
     @UnsupportedAppUsage
-    public abstract ApplicationInfo getApplicationInfoAsUser(String packageName,
+    public abstract ApplicationInfo getApplicationInfoAsUser(@NonNull String packageName,
             @ApplicationInfoFlags int flags, @UserIdInt int userId) throws NameNotFoundException;
 
     /**
@@ -3552,7 +3559,8 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract ActivityInfo getActivityInfo(ComponentName component,
+    @NonNull
+    public abstract ActivityInfo getActivityInfo(@NonNull ComponentName component,
             @ComponentInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3568,7 +3576,8 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract ActivityInfo getReceiverInfo(ComponentName component,
+    @NonNull
+    public abstract ActivityInfo getReceiverInfo(@NonNull ComponentName component,
             @ComponentInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3583,7 +3592,8 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract ServiceInfo getServiceInfo(ComponentName component,
+    @NonNull
+    public abstract ServiceInfo getServiceInfo(@NonNull ComponentName component,
             @ComponentInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3599,7 +3609,8 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract ProviderInfo getProviderInfo(ComponentName component,
+    @NonNull
+    public abstract ProviderInfo getProviderInfo(@NonNull ComponentName component,
             @ComponentInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3612,7 +3623,8 @@
      * @throws NameNotFoundException if a module with the given name cannot be
      *             found on the system.
      */
-    public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags)
+    @NonNull
+    public ModuleInfo getModuleInfo(@NonNull String packageName, @ModuleInfoFlags int flags)
             throws NameNotFoundException {
         throw new UnsupportedOperationException(
                 "getModuleInfo not implemented in subclass");
@@ -3626,7 +3638,8 @@
      *         module, containing information about the module. In the unlikely case
      *         there are no installed modules, an empty list is returned.
      */
-    public @NonNull List<ModuleInfo> getInstalledModules(@ModuleInfoFlags int flags) {
+    @NonNull
+    public List<ModuleInfo> getInstalledModules(@ModuleInfoFlags int flags) {
         throw new UnsupportedOperationException(
                 "getInstalledModules not implemented in subclass");
     }
@@ -3644,6 +3657,7 @@
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
      */
+    @NonNull
     public abstract List<PackageInfo> getInstalledPackages(@PackageInfoFlags int flags);
 
     /**
@@ -3661,8 +3675,9 @@
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
      */
+    @NonNull
     public abstract List<PackageInfo> getPackagesHoldingPermissions(
-            String[] permissions, @PackageInfoFlags int flags);
+            @NonNull String[] permissions, @PackageInfoFlags int flags);
 
     /**
      * Return a List of all packages that are installed on the device, for a
@@ -3680,6 +3695,7 @@
      *         deleted with {@code DONT_DELETE_DATA} flag set).
      * @hide
      */
+    @NonNull
     @TestApi
     @SystemApi
     @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
@@ -3690,8 +3706,8 @@
      * Check whether a particular package has been granted a particular
      * permission.
      *
-     * @param permName The name of the permission you are checking for.
-     * @param pkgName The name of the package you are checking against.
+     * @param permissionName The name of the permission you are checking for.
+     * @param packageName The name of the package you are checking against.
      *
      * @return If the package has the permission, PERMISSION_GRANTED is
      * returned.  If it does not have the permission, PERMISSION_DENIED
@@ -3701,7 +3717,9 @@
      * @see #PERMISSION_DENIED
      */
     @CheckResult
-    public abstract @PermissionResult int checkPermission(String permName, String pkgName);
+    @PermissionResult
+    public abstract int checkPermission(@NonNull String permissionName,
+            @NonNull String packageName);
 
     /**
      * Checks whether a particular permissions has been revoked for a
@@ -3710,14 +3728,14 @@
      * permissions, hence the only way for an app to get such a permission
      * is by a policy change.
      *
-     * @param permName The name of the permission you are checking for.
-     * @param pkgName The name of the package you are checking against.
+     * @param permissionName The name of the permission you are checking for.
+     * @param packageName The name of the package you are checking against.
      *
      * @return Whether the permission is restricted by policy.
      */
     @CheckResult
-    public abstract boolean isPermissionRevokedByPolicy(@NonNull String permName,
-            @NonNull String pkgName);
+    public abstract boolean isPermissionRevokedByPolicy(@NonNull String permissionName,
+            @NonNull String packageName);
 
     /**
      * Gets the package name of the component controlling runtime permissions.
@@ -3726,6 +3744,7 @@
      *
      * @hide
      */
+    @NonNull
     @TestApi
     public abstract String getPermissionControllerPackageName();
 
@@ -3761,7 +3780,7 @@
      *
      * @see #removePermission(String)
      */
-    public abstract boolean addPermission(PermissionInfo info);
+    public abstract boolean addPermission(@NonNull PermissionInfo info);
 
     /**
      * Like {@link #addPermission(PermissionInfo)} but asynchronously
@@ -3770,7 +3789,7 @@
      * expense of no guarantee the added permission will be retained if
      * the device is rebooted before it is written.
      */
-    public abstract boolean addPermissionAsync(PermissionInfo info);
+    public abstract boolean addPermissionAsync(@NonNull PermissionInfo info);
 
     /**
      * Removes a permission that was previously added with
@@ -3778,14 +3797,14 @@
      * -- you are only allowed to remove permissions that you are allowed
      * to add.
      *
-     * @param name The name of the permission to remove.
+     * @param permissionName The name of the permission to remove.
      *
      * @throws SecurityException if you are not allowed to remove the
      * given permission name.
      *
      * @see #addPermission(PermissionInfo)
      */
-    public abstract void removePermission(String name);
+    public abstract void removePermission(@NonNull String permissionName);
 
     /**
      * Permission flags set when granting or revoking a permission.
@@ -3802,7 +3821,6 @@
             FLAG_PERMISSION_GRANTED_BY_DEFAULT,
             FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED,
             FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED,
-            FLAG_PERMISSION_HIDDEN,
             /*
             FLAG_PERMISSION_REVOKE_WHEN_REQUESED
             */
@@ -3880,8 +3898,9 @@
             android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
             android.Manifest.permission.GET_RUNTIME_PERMISSIONS
     })
-    public abstract @PermissionFlags int getPermissionFlags(String permissionName,
-            String packageName, @NonNull UserHandle user);
+    @PermissionFlags
+    public abstract int getPermissionFlags(@NonNull String permissionName,
+            @NonNull String packageName, @NonNull UserHandle user);
 
     /**
      * Updates the flags associated with a permission by replacing the flags in
@@ -3901,9 +3920,9 @@
             android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
             android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
     })
-    public abstract void updatePermissionFlags(String permissionName,
-            String packageName, @PermissionFlags int flagMask, @PermissionFlags int flagValues,
-            @NonNull UserHandle user);
+    public abstract void updatePermissionFlags(@NonNull String permissionName,
+            @NonNull String packageName, @PermissionFlags int flagMask,
+            @PermissionFlags int flagValues, @NonNull UserHandle user);
 
     /**
      * Gets whether you should show UI with rationale for requesting a permission.
@@ -3911,13 +3930,13 @@
      * which the permission is requested does not clearly communicate to the user
      * what would be the benefit from grating this permission.
      *
-     * @param permission A permission your app wants to request.
+     * @param permissionName A permission your app wants to request.
      * @return Whether you can show permission rationale UI.
      *
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract boolean shouldShowRequestPermissionRationale(String permission);
+    public abstract boolean shouldShowRequestPermissionRationale(@NonNull String permissionName);
 
     /**
      * Returns an {@link android.content.Intent} suitable for passing to
@@ -3928,6 +3947,7 @@
      *
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
     public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) {
         if (ArrayUtils.isEmpty(permissions)) {
@@ -3946,8 +3966,8 @@
      * with each other: they can share the same user-id, run instrumentation
      * against each other, etc.
      *
-     * @param pkg1 First package name whose signature will be compared.
-     * @param pkg2 Second package name whose signature will be compared.
+     * @param packageName1 First package name whose signature will be compared.
+     * @param packageName2 Second package name whose signature will be compared.
      *
      * @return Returns an integer indicating whether all signatures on the
      * two packages match. The value is >= 0 ({@link #SIGNATURE_MATCH}) if
@@ -3957,7 +3977,9 @@
      * @see #checkSignatures(int, int)
      */
     @CheckResult
-    public abstract @SignatureResult int checkSignatures(String pkg1, String pkg2);
+    @SignatureResult
+    public abstract int checkSignatures(@NonNull String packageName1,
+            @NonNull String packageName2);
 
     /**
      * Like {@link #checkSignatures(String, String)}, but takes UIDs of
@@ -4030,7 +4052,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract int getUidForSharedUser(String sharedUserName)
+    public abstract int getUidForSharedUser(@NonNull String sharedUserName)
             throws NameNotFoundException;
 
     /**
@@ -4049,6 +4071,7 @@
      *         applications with data directory i.e. applications which had been
      *         deleted with {@code DONT_DELETE_DATA} flag set).
      */
+    @NonNull
     public abstract List<ApplicationInfo> getInstalledApplications(@ApplicationInfoFlags int flags);
 
     /**
@@ -4071,6 +4094,7 @@
      *         deleted with {@code DONT_DELETE_DATA} flag set).
      * @hide
      */
+    @NonNull
     @TestApi
     public abstract List<ApplicationInfo> getInstalledApplicationsAsUser(
             @ApplicationInfoFlags int flags, @UserIdInt int userId);
@@ -4121,7 +4145,7 @@
      * @see #getInstantAppCookieMaxBytes()
      * @see #clearInstantAppCookie()
      */
-    public abstract boolean isInstantApp(String packageName);
+    public abstract boolean isInstantApp(@NonNull String packageName);
 
     /**
      * Gets the maximum size in bytes of the cookie data an instant app
@@ -4208,6 +4232,7 @@
      * available on the system, or null if none are installed.
      *
      */
+    @Nullable
     public abstract String[] getSystemSharedLibraryNames();
 
     /**
@@ -4296,6 +4321,7 @@
      * @return An array of FeatureInfo classes describing the features
      * that are available on the system, or null if there are none(!!).
      */
+    @NonNull
     public abstract FeatureInfo[] getSystemAvailableFeatures();
 
     /**
@@ -4306,7 +4332,7 @@
      *
      * @return Returns true if the devices supports the feature, else false.
      */
-    public abstract boolean hasSystemFeature(String name);
+    public abstract boolean hasSystemFeature(@NonNull String featureName);
 
     /**
      * Check whether the given feature name and version is one of the available
@@ -4317,7 +4343,7 @@
      *
      * @return Returns true if the devices supports the feature, else false.
      */
-    public abstract boolean hasSystemFeature(String name, int version);
+    public abstract boolean hasSystemFeature(@NonNull String featureName, int version);
 
     /**
      * Determine the best action to perform for a given Intent. This is how
@@ -4345,7 +4371,9 @@
      *         found and there is no default set, returns a ResolveInfo object
      *         containing something else, such as the activity resolver.
      */
-    public abstract ResolveInfo resolveActivity(Intent intent, @ResolveInfoFlags int flags);
+    @Nullable
+    public abstract ResolveInfo resolveActivity(@NonNull Intent intent,
+            @ResolveInfoFlags int flags);
 
     /**
      * Determine the best action to perform for a given Intent for a given user.
@@ -4375,9 +4403,10 @@
      *         containing something else, such as the activity resolver.
      * @hide
      */
+    @Nullable
     @UnsupportedAppUsage
-    public abstract ResolveInfo resolveActivityAsUser(Intent intent, @ResolveInfoFlags int flags,
-            @UserIdInt int userId);
+    public abstract ResolveInfo resolveActivityAsUser(@NonNull Intent intent,
+            @ResolveInfoFlags int flags, @UserIdInt int userId);
 
     /**
      * Retrieve all activities that can be performed for the given intent.
@@ -4394,7 +4423,8 @@
      *         {@link #resolveActivity}. If there are no matching activities, an
      *         empty list is returned.
      */
-    public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
+    @Nullable
+    public abstract List<ResolveInfo> queryIntentActivities(@NonNull Intent intent,
             @ResolveInfoFlags int flags);
 
     /**
@@ -4414,8 +4444,9 @@
      *         empty list is returned.
      * @hide
      */
+    @Nullable
     @UnsupportedAppUsage
-    public abstract List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
+    public abstract List<ResolveInfo> queryIntentActivitiesAsUser(@NonNull Intent intent,
             @ResolveInfoFlags int flags, @UserIdInt int userId);
 
     /**
@@ -4469,8 +4500,9 @@
      *         included by one of the <var>specifics</var> intents. If there are
      *         no matching activities, an empty list is returned.
      */
+    @NonNull
     public abstract List<ResolveInfo> queryIntentActivityOptions(@Nullable ComponentName caller,
-            @Nullable Intent[] specifics, Intent intent, @ResolveInfoFlags int flags);
+            @Nullable Intent[] specifics, @NonNull Intent intent, @ResolveInfoFlags int flags);
 
     /**
      * Retrieve all receivers that can handle a broadcast of the given intent.
@@ -4481,7 +4513,8 @@
      *         each matching receiver, ordered from best to worst. If there are
      *         no matching receivers, an empty list or null is returned.
      */
-    public abstract List<ResolveInfo> queryBroadcastReceivers(Intent intent,
+    @NonNull
+    public abstract List<ResolveInfo> queryBroadcastReceivers(@NonNull Intent intent,
             @ResolveInfoFlags int flags);
 
     /**
@@ -4496,9 +4529,10 @@
      *         no matching receivers, an empty list or null is returned.
      * @hide
      */
+    @NonNull
     @SystemApi
     @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS)
-    public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent,
+    public List<ResolveInfo> queryBroadcastReceiversAsUser(@NonNull Intent intent,
             @ResolveInfoFlags int flags, UserHandle userHandle) {
         return queryBroadcastReceiversAsUser(intent, flags, userHandle.getIdentifier());
     }
@@ -4506,15 +4540,17 @@
     /**
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
-    public abstract List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent,
+    public abstract List<ResolveInfo> queryBroadcastReceiversAsUser(@NonNull Intent intent,
             @ResolveInfoFlags int flags, @UserIdInt int userId);
 
 
-    /** {@hide} */
+    /** @deprecated @hide */
+    @NonNull
     @Deprecated
     @UnsupportedAppUsage
-    public List<ResolveInfo> queryBroadcastReceivers(Intent intent,
+    public List<ResolveInfo> queryBroadcastReceivers(@NonNull Intent intent,
             @ResolveInfoFlags int flags, @UserIdInt int userId) {
         final String msg = "Shame on you for calling the hidden API "
                 + "queryBroadcastReceivers(). Shame!";
@@ -4536,13 +4572,15 @@
      *         that was determined to be the best action. Returns null if no
      *         matching service was found.
      */
-    public abstract ResolveInfo resolveService(Intent intent, @ResolveInfoFlags int flags);
+    @Nullable
+    public abstract ResolveInfo resolveService(@NonNull Intent intent, @ResolveInfoFlags int flags);
 
     /**
      * @hide
      */
-    public abstract ResolveInfo resolveServiceAsUser(Intent intent, @ResolveInfoFlags int flags,
-            @UserIdInt int userId);
+    @Nullable
+    public abstract ResolveInfo resolveServiceAsUser(@NonNull Intent intent,
+            @ResolveInfoFlags int flags, @UserIdInt int userId);
 
     /**
      * Retrieve all services that can match the given intent.
@@ -4555,7 +4593,8 @@
      *         {@link #resolveService}. If there are no matching services, an
      *         empty list or null is returned.
      */
-    public abstract List<ResolveInfo> queryIntentServices(Intent intent,
+    @NonNull
+    public abstract List<ResolveInfo> queryIntentServices(@NonNull Intent intent,
             @ResolveInfoFlags int flags);
 
     /**
@@ -4571,8 +4610,9 @@
      *         empty list or null is returned.
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
-    public abstract List<ResolveInfo> queryIntentServicesAsUser(Intent intent,
+    public abstract List<ResolveInfo> queryIntentServicesAsUser(@NonNull Intent intent,
             @ResolveInfoFlags int flags, @UserIdInt int userId);
 
     /**
@@ -4608,9 +4648,10 @@
      *         no matching services, an empty list or null is returned.
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
     public abstract List<ResolveInfo> queryIntentContentProvidersAsUser(
-            Intent intent, @ResolveInfoFlags int flags, @UserIdInt int userId);
+            @NonNull Intent intent, @ResolveInfoFlags int flags, @UserIdInt int userId);
 
     /**
      * Retrieve all providers that can match the given intent.
@@ -4642,7 +4683,8 @@
      *         each matching provider, ordered from best to worst. If there are
      *         no matching services, an empty list or null is returned.
      */
-    public abstract List<ResolveInfo> queryIntentContentProviders(Intent intent,
+    @NonNull
+    public abstract List<ResolveInfo> queryIntentContentProviders(@NonNull Intent intent,
             @ResolveInfoFlags int flags);
 
     /**
@@ -4659,21 +4701,23 @@
      * @return A {@link ProviderInfo} object containing information about the
      *         provider. If a provider was not found, returns null.
      */
-    public abstract ProviderInfo resolveContentProvider(String authority,
+    @Nullable
+    public abstract ProviderInfo resolveContentProvider(@NonNull String authority,
             @ComponentInfoFlags int flags);
 
     /**
      * Find a single content provider by its base path name.
      *
-     * @param name The name of the provider to find.
+     * @param providerName The name of the provider to find.
      * @param flags Additional option flags to modify the data returned.
      * @param userId The user id.
      * @return A {@link ProviderInfo} object containing information about the
      *         provider. If a provider was not found, returns null.
      * @hide
      */
+    @Nullable
     @UnsupportedAppUsage
-    public abstract ProviderInfo resolveContentProviderAsUser(String name,
+    public abstract ProviderInfo resolveContentProviderAsUser(@NonNull String providerName,
             @ComponentInfoFlags int flags, @UserIdInt int userId);
 
     /**
@@ -4693,8 +4737,9 @@
      *         <var>processName</var> is null, all known content providers.
      *         <em>If there are no matching providers, null is returned.</em>
      */
+    @NonNull
     public abstract List<ProviderInfo> queryContentProviders(
-            String processName, int uid, @ComponentInfoFlags int flags);
+            @Nullable String processName, int uid, @ComponentInfoFlags int flags);
 
     /**
      * Same as {@link #queryContentProviders}, except when {@code metaDataKey} is not null,
@@ -4711,8 +4756,9 @@
      *
      * @hide
      */
-    public List<ProviderInfo> queryContentProviders(
-            String processName, int uid, @ComponentInfoFlags int flags, String metaDataKey) {
+    @NonNull
+    public List<ProviderInfo> queryContentProviders(@Nullable String processName,
+            int uid, @ComponentInfoFlags int flags, String metaDataKey) {
         // Provide the default implementation for mocks.
         return queryContentProviders(processName, uid, flags);
     }
@@ -4730,7 +4776,8 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract InstrumentationInfo getInstrumentationInfo(ComponentName className,
+    @NonNull
+    public abstract InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName className,
             @InstrumentationInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -4745,7 +4792,8 @@
      *         entry for each matching instrumentation. If there are no
      *         instrumentation available, returns an empty list.
      */
-    public abstract List<InstrumentationInfo> queryInstrumentation(String targetPackage,
+    @NonNull
+    public abstract List<InstrumentationInfo> queryInstrumentation(@NonNull String targetPackage,
             @InstrumentationInfoFlags int flags);
 
     /**
@@ -4765,8 +4813,9 @@
      * @return Returns a Drawable holding the requested image.  Returns null if
      * an image could not be found for any reason.
      */
-    public abstract Drawable getDrawable(String packageName, @DrawableRes int resid,
-            ApplicationInfo appInfo);
+    @Nullable
+    public abstract Drawable getDrawable(@NonNull String packageName, @DrawableRes int resid,
+            @Nullable ApplicationInfo appInfo);
 
     /**
      * Retrieve the icon associated with an activity.  Given the full name of
@@ -4783,7 +4832,8 @@
      *
      * @see #getActivityIcon(Intent)
      */
-    public abstract Drawable getActivityIcon(ComponentName activityName)
+    @NonNull
+    public abstract Drawable getActivityIcon(@NonNull ComponentName activityName)
             throws NameNotFoundException;
 
     /**
@@ -4803,7 +4853,8 @@
      *
      * @see #getActivityIcon(ComponentName)
      */
-    public abstract Drawable getActivityIcon(Intent intent)
+    @NonNull
+    public abstract Drawable getActivityIcon(@NonNull Intent intent)
             throws NameNotFoundException;
 
     /**
@@ -4819,7 +4870,8 @@
      *             activity could not be loaded.
      * @see #getActivityBanner(Intent)
      */
-    public abstract Drawable getActivityBanner(ComponentName activityName)
+    @Nullable
+    public abstract Drawable getActivityBanner(@NonNull ComponentName activityName)
             throws NameNotFoundException;
 
     /**
@@ -4837,7 +4889,8 @@
      *             matching the given intent could not be loaded.
      * @see #getActivityBanner(ComponentName)
      */
-    public abstract Drawable getActivityBanner(Intent intent)
+    @Nullable
+    public abstract Drawable getActivityBanner(@NonNull Intent intent)
             throws NameNotFoundException;
 
     /**
@@ -4846,6 +4899,7 @@
      *
      * @return Drawable Image of the icon.
      */
+    @NonNull
     public abstract Drawable getDefaultActivityIcon();
 
     /**
@@ -4859,7 +4913,8 @@
      *
      * @see #getApplicationIcon(String)
      */
-    public abstract Drawable getApplicationIcon(ApplicationInfo info);
+    @NonNull
+    public abstract Drawable getApplicationIcon(@NonNull ApplicationInfo info);
 
     /**
      * Retrieve the icon associated with an application.  Given the name of the
@@ -4877,7 +4932,8 @@
      *
      * @see #getApplicationIcon(ApplicationInfo)
      */
-    public abstract Drawable getApplicationIcon(String packageName)
+    @NonNull
+    public abstract Drawable getApplicationIcon(@NonNull String packageName)
             throws NameNotFoundException;
 
     /**
@@ -4888,7 +4944,8 @@
      *         banner specified.
      * @see #getApplicationBanner(String)
      */
-    public abstract Drawable getApplicationBanner(ApplicationInfo info);
+    @Nullable
+    public abstract Drawable getApplicationBanner(@NonNull ApplicationInfo info);
 
     /**
      * Retrieve the banner associated with an application. Given the name of the
@@ -4904,7 +4961,8 @@
      *             application could not be loaded.
      * @see #getApplicationBanner(ApplicationInfo)
      */
-    public abstract Drawable getApplicationBanner(String packageName)
+    @Nullable
+    public abstract Drawable getApplicationBanner(@NonNull String packageName)
             throws NameNotFoundException;
 
     /**
@@ -4920,7 +4978,8 @@
      *             activity could not be loaded.
      * @see #getActivityLogo(Intent)
      */
-    public abstract Drawable getActivityLogo(ComponentName activityName)
+    @Nullable
+    public abstract Drawable getActivityLogo(@NonNull ComponentName activityName)
             throws NameNotFoundException;
 
     /**
@@ -4941,7 +5000,8 @@
      *
      * @see #getActivityLogo(ComponentName)
      */
-    public abstract Drawable getActivityLogo(Intent intent)
+    @Nullable
+    public abstract Drawable getActivityLogo(@NonNull Intent intent)
             throws NameNotFoundException;
 
     /**
@@ -4955,7 +5015,8 @@
      *
      * @see #getApplicationLogo(String)
      */
-    public abstract Drawable getApplicationLogo(ApplicationInfo info);
+    @Nullable
+    public abstract Drawable getApplicationLogo(@NonNull ApplicationInfo info);
 
     /**
      * Retrieve the logo associated with an application.  Given the name of the
@@ -4974,7 +5035,8 @@
      *
      * @see #getApplicationLogo(ApplicationInfo)
      */
-    public abstract Drawable getApplicationLogo(String packageName)
+    @Nullable
+    public abstract Drawable getApplicationLogo(@NonNull String packageName)
             throws NameNotFoundException;
 
     /**
@@ -4988,12 +5050,14 @@
      * is performed in place and the original drawable is returned.
      * </p>
      *
-     * @param icon The icon to badge.
+     * @param drawable The drawable to badge.
      * @param user The target user.
      * @return A drawable that combines the original icon and a badge as
      *         determined by the system.
      */
-    public abstract Drawable getUserBadgedIcon(Drawable icon, UserHandle user);
+    @NonNull
+    public abstract Drawable getUserBadgedIcon(@NonNull Drawable drawable,
+            @NonNull UserHandle user);
 
     /**
      * If the target user is a managed profile of the calling user or the caller
@@ -5019,8 +5083,9 @@
      * @return A drawable that combines the original drawable and a badge as
      *         determined by the system.
      */
-    public abstract Drawable getUserBadgedDrawableForDensity(Drawable drawable,
-            UserHandle user, Rect badgeLocation, int badgeDensity);
+    @NonNull
+    public abstract Drawable getUserBadgedDrawableForDensity(@NonNull Drawable drawable,
+            @NonNull UserHandle user, @Nullable Rect badgeLocation, int badgeDensity);
 
     /**
      * If the target user is a managed profile of the calling user or the caller
@@ -5034,8 +5099,9 @@
      * @return the drawable or null if no drawable is required.
      * @hide
      */
+    @Nullable
     @UnsupportedAppUsage
-    public abstract Drawable getUserBadgeForDensity(UserHandle user, int density);
+    public abstract Drawable getUserBadgeForDensity(@NonNull UserHandle user, int density);
 
     /**
      * If the target user is a managed profile of the calling user or the caller
@@ -5051,8 +5117,10 @@
      * @return the drawable or null if no drawable is required.
      * @hide
      */
+    @Nullable
     @UnsupportedAppUsage
-    public abstract Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density);
+    public abstract Drawable getUserBadgeForDensityNoBackground(@NonNull UserHandle user,
+            int density);
 
     /**
      * If the target user is a managed profile of the calling user or the caller
@@ -5065,7 +5133,9 @@
      * @return A label that combines the original label and a badge as
      *         determined by the system.
      */
-    public abstract CharSequence getUserBadgedLabel(CharSequence label, UserHandle user);
+    @NonNull
+    public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence label,
+            @NonNull UserHandle user);
 
     /**
      * Retrieve text from a package.  This is a low-level API used by
@@ -5084,8 +5154,9 @@
      * @return Returns a CharSequence holding the requested text.  Returns null
      * if the text could not be found for any reason.
      */
-    public abstract CharSequence getText(String packageName, @StringRes int resid,
-            ApplicationInfo appInfo);
+    @Nullable
+    public abstract CharSequence getText(@NonNull String packageName, @StringRes int resid,
+            @Nullable ApplicationInfo appInfo);
 
     /**
      * Retrieve an XML file from a package.  This is a low-level API used to
@@ -5103,8 +5174,9 @@
      * data.  Returns null if the xml resource could not be found for any
      * reason.
      */
-    public abstract XmlResourceParser getXml(String packageName, @XmlRes int resid,
-            ApplicationInfo appInfo);
+    @Nullable
+    public abstract XmlResourceParser getXml(@NonNull String packageName, @XmlRes int resid,
+            @Nullable ApplicationInfo appInfo);
 
     /**
      * Return the label to use for this application.
@@ -5113,7 +5185,8 @@
      * it could not be found for any reason.
      * @param info The application to get the label of.
      */
-    public abstract CharSequence getApplicationLabel(ApplicationInfo info);
+    @NonNull
+    public abstract CharSequence getApplicationLabel(@NonNull ApplicationInfo info);
 
     /**
      * Retrieve the resources associated with an activity.  Given the full
@@ -5130,7 +5203,8 @@
      *
      * @see #getResourcesForApplication(ApplicationInfo)
      */
-    public abstract Resources getResourcesForActivity(ComponentName activityName)
+    @NonNull
+    public abstract Resources getResourcesForActivity(@NonNull ComponentName activityName)
             throws NameNotFoundException;
 
     /**
@@ -5143,7 +5217,8 @@
      * @throws NameNotFoundException Thrown if the resources for the given
      * application could not be loaded (most likely because it was uninstalled).
      */
-    public abstract Resources getResourcesForApplication(ApplicationInfo app)
+    @NonNull
+    public abstract Resources getResourcesForApplication(@NonNull ApplicationInfo app)
             throws NameNotFoundException;
 
     /**
@@ -5152,7 +5227,7 @@
      * calls getResources() to return its application's resources.  If the
      * appPackageName cannot be found, NameNotFoundException is thrown.
      *
-     * @param appPackageName Package name of the application whose resources
+     * @param packageName Package name of the application whose resources
      *                       are to be retrieved.
      *
      * @return Returns the application's Resources.
@@ -5161,12 +5236,14 @@
      *
      * @see #getResourcesForApplication(ApplicationInfo)
      */
-    public abstract Resources getResourcesForApplication(String appPackageName)
+    @NonNull
+    public abstract Resources getResourcesForApplication(@NonNull String packageName)
             throws NameNotFoundException;
 
     /** @hide */
+    @NonNull
     @UnsupportedAppUsage
-    public abstract Resources getResourcesForApplicationAsUser(String appPackageName,
+    public abstract Resources getResourcesForApplicationAsUser(@NonNull String packageName,
             @UserIdInt int userId) throws NameNotFoundException;
 
     /**
@@ -5178,7 +5255,9 @@
      * @return A PackageInfo object containing information about the package
      *         archive. If the package could not be parsed, returns null.
      */
-    public PackageInfo getPackageArchiveInfo(String archiveFilePath, @PackageInfoFlags int flags) {
+    @Nullable
+    public PackageInfo getPackageArchiveInfo(@NonNull String archiveFilePath,
+            @PackageInfoFlags int flags) {
         final PackageParser parser = new PackageParser();
         parser.setCallback(new PackageParser.CallbackImpl(this));
         final File apkFile = new File(archiveFilePath);
@@ -5212,7 +5291,8 @@
      */
     @Deprecated
     @SystemApi
-    public abstract int installExistingPackage(String packageName) throws NameNotFoundException;
+    public abstract int installExistingPackage(@NonNull String packageName)
+            throws NameNotFoundException;
 
     /**
      * If there is already an application with the given package name installed
@@ -5223,8 +5303,8 @@
      */
     @Deprecated
     @SystemApi
-    public abstract int installExistingPackage(String packageName, @InstallReason int installReason)
-            throws NameNotFoundException;
+    public abstract int installExistingPackage(@NonNull String packageName,
+            @InstallReason int installReason) throws NameNotFoundException;
 
     /**
      * If there is already an application with the given package name installed
@@ -5239,8 +5319,8 @@
             Manifest.permission.INSTALL_PACKAGES,
             Manifest.permission.INTERACT_ACROSS_USERS_FULL})
     @UnsupportedAppUsage
-    public abstract int installExistingPackageAsUser(String packageName, @UserIdInt int userId)
-            throws NameNotFoundException;
+    public abstract int installExistingPackageAsUser(@NonNull String packageName,
+            @UserIdInt int userId) throws NameNotFoundException;
 
     /**
      * Allows a package listening to the
@@ -5316,7 +5396,7 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT)
     public abstract void verifyIntentFilter(int verificationId, int verificationCode,
-            List<String> failedDomains);
+            @NonNull List<String> failedDomains);
 
     /**
      * Get the status of a Domain Verification Result for an IntentFilter. This is
@@ -5340,7 +5420,8 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
-    public abstract int getIntentVerificationStatusAsUser(String packageName, @UserIdInt int userId);
+    public abstract int getIntentVerificationStatusAsUser(@NonNull String packageName,
+            @UserIdInt int userId);
 
     /**
      * Allow to change the status of a Intent Verification status for all IntentFilter of an App.
@@ -5364,8 +5445,8 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
-    public abstract boolean updateIntentVerificationStatusAsUser(String packageName, int status,
-            @UserIdInt int userId);
+    public abstract boolean updateIntentVerificationStatusAsUser(@NonNull String packageName,
+            int status, @UserIdInt int userId);
 
     /**
      * Get the list of IntentFilterVerificationInfo for a specific package and User.
@@ -5379,9 +5460,10 @@
      *
      * @hide
      */
+    @NonNull
     @SystemApi
     public abstract List<IntentFilterVerificationInfo> getIntentFilterVerifications(
-            String packageName);
+            @NonNull String packageName);
 
     /**
      * Get the list of IntentFilter for a specific package.
@@ -5394,8 +5476,9 @@
      *
      * @hide
      */
+    @NonNull
     @SystemApi
-    public abstract List<IntentFilter> getAllIntentFilters(String packageName);
+    public abstract List<IntentFilter> getAllIntentFilters(@NonNull String packageName);
 
     /**
      * Get the default Browser package name for a specific user.
@@ -5407,6 +5490,7 @@
      *
      * @hide
      */
+    @Nullable
     @TestApi
     @SystemApi
     @RequiresPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
@@ -5428,7 +5512,7 @@
     @RequiresPermission(allOf = {
             Manifest.permission.SET_PREFERRED_APPLICATIONS,
             Manifest.permission.INTERACT_ACROSS_USERS_FULL})
-    public abstract boolean setDefaultBrowserPackageNameAsUser(String packageName,
+    public abstract boolean setDefaultBrowserPackageNameAsUser(@Nullable String packageName,
             @UserIdInt int userId);
 
     /**
@@ -5446,13 +5530,13 @@
      * @param installerPackageName The package name of the new installer.  May be
      * null to clear the association.
      */
-    public abstract void setInstallerPackageName(String targetPackage,
-            String installerPackageName);
+    public abstract void setInstallerPackageName(@NonNull String targetPackage,
+            @Nullable String installerPackageName);
 
     /** @hide */
     @SystemApi
     @RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
-    public abstract void setUpdateAvailable(String packageName, boolean updateAvaialble);
+    public abstract void setUpdateAvailable(@NonNull String packageName, boolean updateAvaialble);
 
     /**
      * Attempts to delete a package. Since this may take a little while, the
@@ -5472,8 +5556,8 @@
      */
     @RequiresPermission(Manifest.permission.DELETE_PACKAGES)
     @UnsupportedAppUsage
-    public abstract void deletePackage(String packageName, IPackageDeleteObserver observer,
-            @DeleteFlags int flags);
+    public abstract void deletePackage(@NonNull String packageName,
+            @Nullable IPackageDeleteObserver observer, @DeleteFlags int flags);
 
     /**
      * Attempts to delete a package. Since this may take a little while, the
@@ -5495,7 +5579,8 @@
             Manifest.permission.INTERACT_ACROSS_USERS_FULL})
     @UnsupportedAppUsage
     public abstract void deletePackageAsUser(@NonNull String packageName,
-            IPackageDeleteObserver observer, @DeleteFlags int flags, @UserIdInt int userId);
+            @Nullable IPackageDeleteObserver observer, @DeleteFlags int flags,
+            @UserIdInt int userId);
 
     /**
      * Retrieve the package name of the application that installed a package. This identifies
@@ -5505,7 +5590,7 @@
      * @throws IllegalArgumentException if the given package name is not installed
      */
     @Nullable
-    public abstract String getInstallerPackageName(String packageName);
+    public abstract String getInstallerPackageName(@NonNull String packageName);
 
     /**
      * Attempts to clear the user data directory of an application.
@@ -5522,8 +5607,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract void clearApplicationUserData(String packageName,
-            IPackageDataObserver observer);
+    public abstract void clearApplicationUserData(@NonNull String packageName,
+            @Nullable IPackageDataObserver observer);
     /**
      * Attempts to delete the cache files associated with an application.
      * Since this may take a little while, the result will
@@ -5541,8 +5626,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract void deleteApplicationCacheFiles(String packageName,
-            IPackageDataObserver observer);
+    public abstract void deleteApplicationCacheFiles(@NonNull String packageName,
+            @Nullable IPackageDataObserver observer);
 
     /**
      * Attempts to delete the cache files associated with an application for a given user. Since
@@ -5563,8 +5648,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract void deleteApplicationCacheFilesAsUser(String packageName, int userId,
-            IPackageDataObserver observer);
+    public abstract void deleteApplicationCacheFilesAsUser(@NonNull String packageName,
+            @UserIdInt int userId, @Nullable IPackageDataObserver observer);
 
     /**
      * Free storage by deleting LRU sorted list of cache files across
@@ -5589,14 +5674,15 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer) {
+    public void freeStorageAndNotify(long freeStorageSize,
+            @Nullable IPackageDataObserver observer) {
         freeStorageAndNotify(null, freeStorageSize, observer);
     }
 
     /** {@hide} */
     @UnsupportedAppUsage
-    public abstract void freeStorageAndNotify(String volumeUuid, long freeStorageSize,
-            IPackageDataObserver observer);
+    public abstract void freeStorageAndNotify(@Nullable String volumeUuid, long freeStorageSize,
+            @Nullable IPackageDataObserver observer);
 
     /**
      * Free storage by deleting LRU sorted list of cache files across
@@ -5622,13 +5708,14 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public void freeStorage(long freeStorageSize, IntentSender pi) {
+    public void freeStorage(long freeStorageSize, @Nullable IntentSender pi) {
         freeStorage(null, freeStorageSize, pi);
     }
 
     /** {@hide} */
     @UnsupportedAppUsage
-    public abstract void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi);
+    public abstract void freeStorage(@Nullable String volumeUuid, long freeStorageSize,
+            @Nullable IntentSender pi);
 
     /**
      * Retrieve the size information for a package.
@@ -5651,8 +5738,8 @@
      */
     @Deprecated
     @UnsupportedAppUsage
-    public abstract void getPackageSizeInfoAsUser(String packageName, @UserIdInt int userId,
-            IPackageStatsObserver observer);
+    public abstract void getPackageSizeInfoAsUser(@NonNull String packageName,
+            @UserIdInt int userId, @Nullable IPackageStatsObserver observer);
 
     /**
      * Like {@link #getPackageSizeInfoAsUser(String, int, IPackageStatsObserver)}, but
@@ -5663,7 +5750,7 @@
      */
     @Deprecated
     @UnsupportedAppUsage
-    public void getPackageSizeInfo(String packageName, IPackageStatsObserver observer) {
+    public void getPackageSizeInfo(@NonNull String packageName, IPackageStatsObserver observer) {
         getPackageSizeInfoAsUser(packageName, getUserId(), observer);
     }
 
@@ -5676,7 +5763,7 @@
      * holders, see {@link android.app.role.RoleManager}.
      */
     @Deprecated
-    public abstract void addPackageToPreferred(String packageName);
+    public abstract void addPackageToPreferred(@NonNull String packageName);
 
     /**
      * @deprecated This function no longer does anything. It is the platform's
@@ -5687,7 +5774,7 @@
      * holders, see {@link android.app.role.RoleManager}.
      */
     @Deprecated
-    public abstract void removePackageFromPreferred(String packageName);
+    public abstract void removePackageFromPreferred(@NonNull String packageName);
 
     /**
      * Retrieve the list of all currently configured preferred packages. The
@@ -5705,6 +5792,7 @@
      * an app to be responsible for a particular role and to check current role
      * holders, see {@link android.app.role.RoleManager}.
      */
+    @NonNull
     @Deprecated
     public abstract List<PackageInfo> getPreferredPackages(@PackageInfoFlags int flags);
 
@@ -5731,8 +5819,8 @@
      * holders, see {@link android.app.role.RoleManager}.
      */
     @Deprecated
-    public abstract void addPreferredActivity(IntentFilter filter, int match,
-            ComponentName[] set, ComponentName activity);
+    public abstract void addPreferredActivity(@NonNull IntentFilter filter, int match,
+            @Nullable ComponentName[] set, @NonNull ComponentName activity);
 
     /**
      * Same as {@link #addPreferredActivity(IntentFilter, int,
@@ -5749,8 +5837,8 @@
      */
     @Deprecated
     @UnsupportedAppUsage
-    public void addPreferredActivityAsUser(IntentFilter filter, int match,
-            ComponentName[] set, ComponentName activity, @UserIdInt int userId) {
+    public void addPreferredActivityAsUser(@NonNull IntentFilter filter, int match,
+            @Nullable ComponentName[] set, @NonNull ComponentName activity, @UserIdInt int userId) {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
 
@@ -5781,8 +5869,8 @@
      */
     @Deprecated
     @UnsupportedAppUsage
-    public abstract void replacePreferredActivity(IntentFilter filter, int match,
-            ComponentName[] set, ComponentName activity);
+    public abstract void replacePreferredActivity(@NonNull IntentFilter filter, int match,
+            @Nullable ComponentName[] set, @NonNull ComponentName activity);
 
     /**
      * Replaces an existing preferred activity mapping to the system, and if that were not present
@@ -5826,8 +5914,8 @@
      */
     @Deprecated
     @UnsupportedAppUsage
-    public void replacePreferredActivityAsUser(IntentFilter filter, int match,
-           ComponentName[] set, ComponentName activity, @UserIdInt int userId) {
+    public void replacePreferredActivityAsUser(@NonNull IntentFilter filter, int match,
+            @Nullable ComponentName[] set, @NonNull ComponentName activity, @UserIdInt int userId) {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
 
@@ -5848,7 +5936,7 @@
      * holders, see {@link android.app.role.RoleManager}.
      */
     @Deprecated
-    public abstract void clearPackagePreferredActivities(String packageName);
+    public abstract void clearPackagePreferredActivities(@NonNull String packageName);
 
     /**
      * Retrieve all preferred activities, previously added with
@@ -5876,15 +5964,16 @@
      */
     @Deprecated
     public abstract int getPreferredActivities(@NonNull List<IntentFilter> outFilters,
-            @NonNull List<ComponentName> outActivities, String packageName);
+            @NonNull List<ComponentName> outActivities, @Nullable String packageName);
 
     /**
      * Ask for the set of available 'home' activities and the current explicit
      * default, if any.
      * @hide
      */
+    @Nullable
     @UnsupportedAppUsage
-    public abstract ComponentName getHomeActivities(List<ResolveInfo> outActivities);
+    public abstract ComponentName getHomeActivities(@NonNull List<ResolveInfo> outActivities);
 
     /**
      * Set the enabled setting for a package component (activity, receiver, service, provider).
@@ -5984,7 +6073,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract void flushPackageRestrictionsAsUser(int userId);
+    public abstract void flushPackageRestrictionsAsUser(@UserIdInt int userId);
 
     /**
      * Puts the package in a hidden state, which is almost like an uninstalled state,
@@ -5994,8 +6083,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
-            UserHandle userHandle);
+    public abstract boolean setApplicationHiddenSettingAsUser(@NonNull String packageName,
+            boolean hidden, @NonNull UserHandle userHandle);
 
     /**
      * Returns the hidden state of a package.
@@ -6003,8 +6092,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract boolean getApplicationHiddenSettingAsUser(String packageName,
-            UserHandle userHandle);
+    public abstract boolean getApplicationHiddenSettingAsUser(@NonNull String packageName,
+            @NonNull UserHandle userHandle);
 
     /**
      * Return whether the device has been booted into safe mode.
@@ -6020,7 +6109,8 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
-    public abstract void addOnPermissionsChangeListener(OnPermissionsChangedListener listener);
+    public abstract void addOnPermissionsChangeListener(
+            @NonNull OnPermissionsChangedListener listener);
 
     /**
      * Remvoes a listener for permission changes for installed packages.
@@ -6031,7 +6121,8 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
-    public abstract void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener);
+    public abstract void removeOnPermissionsChangeListener(
+            @NonNull OnPermissionsChangedListener listener);
 
     /**
      * Return the {@link KeySet} associated with the String alias for this
@@ -6041,14 +6132,16 @@
      *        application's AndroidManifest.xml.
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
-    public abstract KeySet getKeySetByAlias(String packageName, String alias);
+    public abstract KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias);
 
     /** Return the signing {@link KeySet} for this application.
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
-    public abstract KeySet getSigningKeySet(String packageName);
+    public abstract KeySet getSigningKeySet(@NonNull String packageName);
 
     /**
      * Return whether the package denoted by packageName has been signed by all
@@ -6058,7 +6151,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract boolean isSignedBy(String packageName, KeySet ks);
+    public abstract boolean isSignedBy(@NonNull String packageName, @NonNull KeySet ks);
 
     /**
      * Return whether the package denoted by packageName has been signed by all
@@ -6067,7 +6160,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract boolean isSignedByExactly(String packageName, KeySet ks);
+    public abstract boolean isSignedByExactly(@NonNull String packageName, @NonNull KeySet ks);
 
     /**
      * Flag to denote no restrictions. This should be used to clear any restrictions that may have
@@ -6284,7 +6377,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract boolean isPackageSuspendedForUser(String packageName, int userId);
+    public abstract boolean isPackageSuspendedForUser(@NonNull String packageName, int userId);
 
     /**
      * Query if an app is currently suspended.
@@ -6294,7 +6387,7 @@
      *
      * @see #isPackageSuspended()
      */
-    public boolean isPackageSuspended(String packageName) throws NameNotFoundException {
+    public boolean isPackageSuspended(@NonNull String packageName) throws NameNotFoundException {
         throw new UnsupportedOperationException("isPackageSuspended not implemented");
     }
 
@@ -6378,23 +6471,26 @@
 
     /** {@hide} */
     @UnsupportedAppUsage
-    public abstract void registerMoveCallback(MoveCallback callback, Handler handler);
+    public abstract void registerMoveCallback(@NonNull MoveCallback callback,
+            @NonNull Handler handler);
     /** {@hide} */
     @UnsupportedAppUsage
-    public abstract void unregisterMoveCallback(MoveCallback callback);
+    public abstract void unregisterMoveCallback(@NonNull MoveCallback callback);
 
     /** {@hide} */
     @UnsupportedAppUsage
-    public abstract int movePackage(String packageName, VolumeInfo vol);
+    public abstract int movePackage(@NonNull String packageName, @NonNull VolumeInfo vol);
     /** {@hide} */
     @UnsupportedAppUsage
-    public abstract @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app);
+    public abstract @Nullable VolumeInfo getPackageCurrentVolume(@NonNull ApplicationInfo app);
     /** {@hide} */
+    @NonNull
     @UnsupportedAppUsage
-    public abstract @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app);
+    public abstract List<VolumeInfo> getPackageCandidateVolumes(
+            @NonNull ApplicationInfo app);
 
     /** {@hide} */
-    public abstract int movePrimaryStorage(VolumeInfo vol);
+    public abstract int movePrimaryStorage(@NonNull VolumeInfo vol);
     /** {@hide} */
     public abstract @Nullable VolumeInfo getPrimaryStorageCurrentVolume();
     /** {@hide} */
@@ -6407,6 +6503,7 @@
      * @return identity that uniquely identifies current device
      * @hide
      */
+    @NonNull
     public abstract VerifierDeviceIdentity getVerifierDeviceIdentity();
 
     /**
@@ -6437,8 +6534,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId,
-            int targetUserId, int flags);
+    public abstract void addCrossProfileIntentFilter(@NonNull IntentFilter filter,
+            @UserIdInt int sourceUserId, @UserIdInt int targetUserId, int flags);
 
     /**
      * Clearing {@code CrossProfileIntentFilter}s which have the specified user
@@ -6448,27 +6545,32 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract void clearCrossProfileIntentFilters(int sourceUserId);
+    public abstract void clearCrossProfileIntentFilters(@UserIdInt int sourceUserId);
 
     /**
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
-    public abstract Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo);
+    public abstract Drawable loadItemIcon(@NonNull PackageItemInfo itemInfo,
+            @Nullable ApplicationInfo appInfo);
 
     /**
      * @hide
      */
+    @NonNull
     @UnsupportedAppUsage
-    public abstract Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo);
+    public abstract Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo,
+            @Nullable ApplicationInfo appInfo);
 
     /** {@hide} */
     @UnsupportedAppUsage
-    public abstract boolean isPackageAvailable(String packageName);
+    public abstract boolean isPackageAvailable(@NonNull String packageName);
 
     /** {@hide} */
+    @NonNull
     @UnsupportedAppUsage
-    public static String installStatusToString(int status, String msg) {
+    public static String installStatusToString(int status, @Nullable String msg) {
         final String str = installStatusToString(status);
         if (msg != null) {
             return str + ": " + msg;
@@ -6478,6 +6580,7 @@
     }
 
     /** {@hide} */
+    @NonNull
     @UnsupportedAppUsage
     public static String installStatusToString(int status) {
         switch (status) {
@@ -6582,7 +6685,8 @@
     }
 
     /** {@hide} */
-    public static String deleteStatusToString(int status, String msg) {
+    @NonNull
+    public static String deleteStatusToString(int status, @Nullable String msg) {
         final String str = deleteStatusToString(status);
         if (msg != null) {
             return str + ": " + msg;
@@ -6592,6 +6696,7 @@
     }
 
     /** {@hide} */
+    @NonNull
     @UnsupportedAppUsage
     public static String deleteStatusToString(int status) {
         switch (status) {
@@ -6621,6 +6726,7 @@
     }
 
     /** {@hide} */
+    @NonNull
     public static String permissionFlagToString(int flag) {
         switch (flag) {
             case FLAG_PERMISSION_GRANTED_BY_DEFAULT: return "GRANTED_BY_DEFAULT";
@@ -6633,7 +6739,6 @@
             case FLAG_PERMISSION_REVOKE_WHEN_REQUESTED: return "REVOKE_WHEN_REQUESTED";
             case FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED: return "USER_SENSITIVE_WHEN_GRANTED";
             case FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED: return "USER_SENSITIVE_WHEN_DENIED";
-            case FLAG_PERMISSION_HIDDEN: return "HIDDEN";
             default: return Integer.toString(flag);
         }
     }
@@ -6668,8 +6773,8 @@
      * @hide
      */
     @TestApi
-    public abstract @InstallReason int getInstallReason(String packageName,
-            @NonNull UserHandle user);
+    @InstallReason
+    public abstract int getInstallReason(@NonNull String packageName, @NonNull UserHandle user);
 
     /**
      * Checks whether the calling package is allowed to request package installs through package
@@ -6695,6 +6800,7 @@
      * @see {@link android.content.Intent#ACTION_INSTANT_APP_RESOLVER_SETTINGS}
      * @hide
      */
+    @Nullable
     @SystemApi
     public abstract ComponentName getInstantAppResolverSettingsComponent();
 
@@ -6705,6 +6811,7 @@
      * @see {@link android.content.Intent#ACTION_INSTALL_INSTANT_APP_PACKAGE}
      * @hide
      */
+    @Nullable
     @SystemApi
     public abstract ComponentName getInstantAppInstallerComponent();
 
@@ -6714,7 +6821,9 @@
      * @see {@link android.provider.Settings.Secure#ANDROID_ID}
      * @hide
      */
-    public abstract String getInstantAppAndroidId(String packageName, @NonNull UserHandle user);
+    @Nullable
+    public abstract String getInstantAppAndroidId(@NonNull String packageName,
+            @NonNull UserHandle user);
 
     /**
      * Callback use to notify the callers of module registration that the operation
@@ -6757,7 +6866,7 @@
      * @hide
      */
     @SystemApi
-    public abstract void registerDexModule(String dexModulePath,
+    public abstract void registerDexModule(@NonNull String dexModulePath,
             @Nullable DexModuleRegisterCallback callback);
 
     /**
@@ -6837,8 +6946,8 @@
      * @param type representation of the {@code certificate}
      * @return true if this package was or is signed by exactly the certificate {@code certificate}
      */
-    public boolean hasSigningCertificate(
-            String packageName, byte[] certificate, @CertificateInputType int type) {
+    public boolean hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
+            @CertificateInputType int type) {
         throw new UnsupportedOperationException(
                 "hasSigningCertificate not implemented in subclass");
     }
@@ -6862,7 +6971,7 @@
      * @return true if this package was or is signed by exactly the certificate {@code certificate}
      */
     public boolean hasSigningCertificate(
-            int uid, byte[] certificate, @CertificateInputType int type) {
+            int uid, @NonNull byte[] certificate, @CertificateInputType int type) {
         throw new UnsupportedOperationException(
                 "hasSigningCertificate not implemented in subclass");
     }
@@ -6872,16 +6981,28 @@
      *
      * @hide
      */
+    @Nullable
     public String getSystemTextClassifierPackageName() {
         throw new UnsupportedOperationException(
                 "getSystemTextClassifierPackageName not implemented in subclass");
     }
 
     /**
+     * @return  attention service package name, or null if there's none.
+     *
+     * @hide
+     */
+    public String getAttentionServicePackageName() {
+        throw new UnsupportedOperationException(
+                "getAttentionServicePackageName not implemented in subclass");
+    }
+
+    /**
      * @return the wellbeing app package name, or null if it's not defined by the OEM.
      *
      * @hide
      */
+    @Nullable
     @TestApi
     public String getWellbeingPackageName() {
         throw new UnsupportedOperationException(
@@ -6893,6 +7014,7 @@
      *
      * @hide
      */
+    @Nullable
     public String getAppPredictionServicePackageName() {
         throw new UnsupportedOperationException(
             "getAppPredictionServicePackageName not implemented in subclass");
@@ -6903,6 +7025,7 @@
      *
      * @hide
      */
+    @Nullable
     public String getSystemCaptionsServicePackageName() {
         throw new UnsupportedOperationException(
                 "getSystemCaptionsServicePackageName not implemented in subclass");
@@ -6916,6 +7039,7 @@
      */
     @SystemApi
     @TestApi
+    @Nullable
     public String getIncidentReportApproverPackageName() {
         throw new UnsupportedOperationException(
                 "getIncidentReportApproverPackageName not implemented in subclass");
@@ -6927,7 +7051,7 @@
      *
      * @hide
      */
-    public boolean isPackageStateProtected(String packageName, int userId) {
+    public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
         throw new UnsupportedOperationException(
             "isPackageStateProtected not implemented in subclass");
     }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index b480939..81788b9 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -166,6 +166,9 @@
     private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO = 1.333f;
     private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH = 1f;
 
+    private static final int DEFAULT_MIN_SDK_VERSION = 1;
+    private static final int DEFAULT_TARGET_SDK_VERSION = 0;
+
     // TODO: switch outError users to PackageParserException
     // TODO: refactor "codePath" to "apkPath"
 
@@ -466,6 +469,8 @@
         public final int versionCodeMajor;
         public final int revisionCode;
         public final int installLocation;
+        public final int minSdkVersion;
+        public final int targetSdkVersion;
         public final VerifierInfo[] verifiers;
         public final SigningDetails signingDetails;
         public final boolean coreApp;
@@ -484,7 +489,8 @@
                 int revisionCode, int installLocation, List<VerifierInfo> verifiers,
                 SigningDetails signingDetails, boolean coreApp,
                 boolean debuggable, boolean multiArch, boolean use32bitAbi,
-                boolean useEmbeddedDex, boolean extractNativeLibs, boolean isolatedSplits) {
+                boolean useEmbeddedDex, boolean extractNativeLibs, boolean isolatedSplits,
+                int minSdkVersion, int targetSdkVersion) {
             this.codePath = codePath;
             this.packageName = packageName;
             this.splitName = splitName;
@@ -505,6 +511,8 @@
             this.extractNativeLibs = extractNativeLibs;
             this.isolatedSplits = isolatedSplits;
             this.isSplitRequired = isSplitRequired;
+            this.minSdkVersion = minSdkVersion;
+            this.targetSdkVersion = targetSdkVersion;
         }
 
         public long getLongVersionCode() {
@@ -1712,6 +1720,8 @@
         int installLocation = PARSE_DEFAULT_INSTALL_LOCATION;
         int versionCode = 0;
         int versionCodeMajor = 0;
+        int targetSdkVersion = DEFAULT_TARGET_SDK_VERSION;
+        int minSdkVersion = DEFAULT_MIN_SDK_VERSION;
         int revisionCode = 0;
         boolean coreApp = false;
         boolean debuggable = false;
@@ -1749,7 +1759,7 @@
             }
         }
 
-        // Only search the tree when the tag is directly below <manifest>
+        // Only search the tree when the tag is the direct child of <manifest> tag
         int type;
         final int searchDepth = parser.getDepth() + 1;
 
@@ -1800,13 +1810,25 @@
                             PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                             "<uses-split> tag requires 'android:name' attribute");
                 }
+            } else if (TAG_USES_SDK.equals(parser.getName())) {
+                for (int i = 0; i < attrs.getAttributeCount(); ++i) {
+                    final String attr = attrs.getAttributeName(i);
+                    if ("targetSdkVersion".equals(attr)) {
+                        targetSdkVersion = attrs.getAttributeIntValue(i,
+                                DEFAULT_TARGET_SDK_VERSION);
+                    }
+                    if ("minSdkVersion".equals(attr)) {
+                        minSdkVersion = attrs.getAttributeIntValue(i, DEFAULT_MIN_SDK_VERSION);
+                    }
+                }
             }
         }
 
         return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
                 configForSplit, usesSplitName, isSplitRequired, versionCode, versionCodeMajor,
                 revisionCode, installLocation, verifiers, signingDetails, coreApp, debuggable,
-                multiArch, use32bitAbi, useEmbeddedDex, extractNativeLibs, isolatedSplits);
+                multiArch, use32bitAbi, useEmbeddedDex, extractNativeLibs, isolatedSplits,
+                minSdkVersion, targetSdkVersion);
     }
 
     /**
@@ -2525,46 +2547,26 @@
         // STOPSHIP(b/112545973): remove once feature enabled by default
         if (!StorageManager.hasIsolatedStorage()) {
             if ("android".equals(pkg.packageName)) {
-                final ArraySet<String> newGroups = new ArraySet<>();
-                newGroups.add(android.Manifest.permission_group.MEDIA_AURAL);
-                newGroups.add(android.Manifest.permission_group.MEDIA_VISUAL);
-
-                for (int i = pkg.permissionGroups.size() - 1; i >= 0; i--) {
-                    final PermissionGroup pg = pkg.permissionGroups.get(i);
-                    if (newGroups.contains(pg.info.name)) {
-                        pkg.permissionGroups.remove(i);
-                    }
-                }
-
                 final ArraySet<String> newPermissions = new ArraySet<>();
-                newPermissions.add(android.Manifest.permission.READ_MEDIA_AUDIO);
-                newPermissions.add(android.Manifest.permission.READ_MEDIA_VIDEO);
-                newPermissions.add(android.Manifest.permission.READ_MEDIA_IMAGES);
                 newPermissions.add(android.Manifest.permission.ACCESS_MEDIA_LOCATION);
                 newPermissions.add(android.Manifest.permission.WRITE_OBB);
 
-                final ArraySet<String> removedPermissions = new ArraySet<>();
-                removedPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE);
-                removedPermissions.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
-
                 for (int i = pkg.permissions.size() - 1; i >= 0; i--) {
                     final Permission p = pkg.permissions.get(i);
                     if (newPermissions.contains(p.info.name)) {
                         pkg.permissions.remove(i);
-                    } else if (removedPermissions.contains(p.info.name)) {
-                        p.info.flags &= ~PermissionInfo.FLAG_REMOVED;
                     }
                 }
             }
         } else {
             if (FORCE_AUDIO_PACKAGES.contains(pkg.packageName)) {
-                pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_AUDIO);
+                pkg.requestedPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE);
             }
             if (FORCE_VIDEO_PACKAGES.contains(pkg.packageName)) {
-                pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_VIDEO);
+                pkg.requestedPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE);
             }
             if (FORCE_IMAGES_PACKAGES.contains(pkg.packageName)) {
-                pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_IMAGES);
+                pkg.requestedPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE);
             }
         }
 
@@ -3667,6 +3669,12 @@
             ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE;
         }
 
+        if (sa.getBoolean(
+                R.styleable.AndroidManifestApplication_allowExternalStorageSandbox,
+                owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q)) {
+            ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX;
+        }
+
         ai.maxAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0);
         ai.minAspectRatio = sa.getFloat(R.styleable.AndroidManifestApplication_minAspectRatio, 0);
 
@@ -4774,7 +4782,7 @@
             // except for watches which always supported 1:1.
             minAspectRatio = owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q
                     ? 0
-                    : mCallback.hasFeature(FEATURE_WATCH)
+                    : (mCallback != null && mCallback.hasFeature(FEATURE_WATCH))
                             ? DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH
                             : DEFAULT_PRE_Q_MIN_ASPECT_RATIO;
         }
@@ -6912,6 +6920,11 @@
         }
 
         /** @hide */
+        public boolean isOdm() {
+            return applicationInfo.isOdm();
+        }
+
+        /** @hide */
         public boolean isPrivileged() {
             return applicationInfo.isPrivilegedApp();
         }
@@ -8350,69 +8363,37 @@
         }
     }
 
-    public static PackageInfo generatePackageInfoFromApex(File apexFile, boolean collectCerts)
+    // TODO(b/129261524): Clean up API
+    /**
+     * PackageInfo parser specifically for apex files.
+     * NOTE: It will collect certificates
+     *
+     * @param apexFile
+     * @return PackageInfo
+     * @throws PackageParserException
+     */
+    public static PackageInfo generatePackageInfoFromApex(File apexFile, int flags)
             throws PackageParserException {
-        PackageInfo pi = new PackageInfo();
-        int parseFlags = 0;
-        if (collectCerts) {
-            parseFlags |= PARSE_COLLECT_CERTIFICATES;
-            try {
-                if (apexFile.getCanonicalPath().startsWith("/system")) {
-                    // Don't need verify the APK integrity of APEXes on /system, just like
-                    // we don't do that for APKs.
-                    // TODO(b/126514108): we may be able to do this for APEXes on /data as well.
-                    parseFlags |= PARSE_IS_SYSTEM_DIR;
-                }
-            } catch (IOException e) {
-                throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
-                        "Failed to get path for " + apexFile.getPath(), e);
-            }
-        }
+        PackageParser pp = new PackageParser();
+        final Package p = pp.parsePackage(apexFile, flags, false);
+        PackageUserState state = new PackageUserState();
+        PackageInfo pi = generatePackageInfo(p, EmptyArray.INT, flags, 0, 0,
+                Collections.emptySet(), state);
 
-        // TODO(b/123086053) properly fill in the ApplicationInfo with data from AndroidManifest
-        // Add ApplicationInfo to the PackageInfo.
-        ApplicationInfo ai = new ApplicationInfo();
-        ai.sourceDir = apexFile.getPath();
-        ai.flags = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
-        ai.enabled = true;
-        ai.targetSdkVersion = 28;
-        ai.targetSandboxVersion = 0;
-        pi.applicationInfo = ai;
+        pi.applicationInfo.sourceDir = apexFile.getPath();
+        pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
+        pi.isApex = true;
 
-
-        // TODO(b/123052859): We should avoid these repeated calls to parseApkLite each time
-        // we want to generate information for APEX modules.
-        PackageParser.ApkLite apk = PackageParser.parseApkLite(apexFile, parseFlags);
-
-        pi.packageName = apk.packageName;
-        ai.packageName = apk.packageName;
-        pi.setLongVersionCode(apk.getLongVersionCode());
-        ai.setVersionCode(apk.getLongVersionCode());
-
-        if (collectCerts) {
-            if (apk.signingDetails.hasPastSigningCertificates()) {
-                // Package has included signing certificate rotation information.  Return
-                // the oldest cert so that programmatic checks keep working even if unaware
-                // of key rotation.
-                pi.signatures = new Signature[1];
-                pi.signatures[0] = apk.signingDetails.pastSigningCertificates[0];
-            } else if (apk.signingDetails.hasSignatures()) {
-                // otherwise keep old behavior
-                int numberOfSigs = apk.signingDetails.signatures.length;
-                pi.signatures = new Signature[numberOfSigs];
-                System.arraycopy(apk.signingDetails.signatures, 0, pi.signatures, 0,
-                    numberOfSigs);
-            }
-
-            if (apk.signingDetails != SigningDetails.UNKNOWN) {
+        // Collect certificates
+        if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
+            collectCertificates(p, apexFile, false);
+            if (p.mSigningDetails != SigningDetails.UNKNOWN) {
                 // only return a valid SigningInfo if there is signing information to report
-                pi.signingInfo = new SigningInfo(apk.signingDetails);
+                pi.signingInfo = new SigningInfo(p.mSigningDetails);
             } else {
                 pi.signingInfo = null;
             }
         }
-
-        pi.isApex = true;
         return pi;
     }
 }
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index df67117..f851799 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -15,8 +15,10 @@
  */
 package android.content.pm;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
@@ -565,6 +567,7 @@
      */
     @NonNull
     @SystemApi
+    @RequiresPermission(Manifest.permission.MANAGE_APP_PREDICTIONS)
     public List<ShareShortcutInfo> getShareTargets(@NonNull IntentFilter filter) {
         try {
             return mService.getShareTargets(mContext.getPackageName(), filter,
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 49b4cb0..e5ef67b 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -23,6 +23,7 @@
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.annotation.StyleRes;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration.NativeConfig;
@@ -357,6 +358,22 @@
         return sEmptyApkAssets;
     }
 
+    /** @hide */
+    @TestApi
+    public @NonNull String[] getApkPaths() {
+        synchronized (this) {
+            if (mOpen) {
+                String[] paths = new String[mApkAssets.length];
+                final int count = mApkAssets.length;
+                for (int i = 0; i < count; i++) {
+                    paths[i] = mApkAssets[i].getAssetPath();
+                }
+                return paths;
+            }
+        }
+        return new String[0];
+    }
+
     /**
      * Returns a cookie for use with the other APIs of AssetManager.
      * @return 0 if the path was not found, otherwise a positive integer cookie representing
@@ -1263,12 +1280,19 @@
      */
     @UnsupportedAppUsage
     public boolean isUpToDate() {
-        for (ApkAssets apkAssets : getApkAssets()) {
-            if (!apkAssets.isUpToDate()) {
+        synchronized (this) {
+            if (!mOpen) {
                 return false;
             }
+
+            for (ApkAssets apkAssets : mApkAssets) {
+                if (!apkAssets.isUpToDate()) {
+                    return false;
+                }
+            }
+
+            return true;
         }
-        return true;
     }
 
     /**
@@ -1349,6 +1373,7 @@
     /**
      * @hide
      */
+    @TestApi
     @GuardedBy("this")
     public @Nullable Map<String, String> getOverlayableMap(String packageName) {
         synchronized (this) {
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index 44bd883..647448c 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -61,7 +61,10 @@
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
+    // May throw CursorWindowAllocationException
     private static native long nativeCreate(String name, int cursorWindowSize);
+
+    // May throw CursorWindowAllocationException
     private static native long nativeCreateFromParcel(Parcel parcel);
     private static native void nativeDispose(long windowPtr);
     private static native void nativeWriteToParcel(long windowPtr, Parcel parcel);
@@ -135,8 +138,7 @@
         mName = name != null && name.length() != 0 ? name : "<unnamed>";
         mWindowPtr = nativeCreate(mName, (int) windowSizeBytes);
         if (mWindowPtr == 0) {
-            throw new CursorWindowAllocationException("Cursor window allocation of " +
-                    windowSizeBytes + " bytes failed. " + printStats());
+            throw new IllegalStateException(); // Shouldn't happen.
         }
         mCloseGuard.open("close");
         recordNewWindow(Binder.getCallingPid(), mWindowPtr);
@@ -164,8 +166,7 @@
         mStartPos = source.readInt();
         mWindowPtr = nativeCreateFromParcel(source);
         if (mWindowPtr == 0) {
-            throw new CursorWindowAllocationException("Cursor window could not be "
-                    + "created from binder.");
+            throw new IllegalStateException(); // Shouldn't happen.
         }
         mName = nativeGetName(mWindowPtr);
         mCloseGuard.open("close");
diff --git a/core/java/android/database/TranslatingCursor.java b/core/java/android/database/TranslatingCursor.java
index d9165b4..35cbdc7 100644
--- a/core/java/android/database/TranslatingCursor.java
+++ b/core/java/android/database/TranslatingCursor.java
@@ -22,6 +22,7 @@
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
 import android.os.CancellationSignal;
+import android.util.ArraySet;
 
 import com.android.internal.util.ArrayUtils;
 
@@ -59,7 +60,7 @@
     private final boolean mDropLast;
 
     private final int mAuxiliaryColumnIndex;
-    private final int[] mTranslateColumnIndices;
+    private final ArraySet<Integer> mTranslateColumnIndices;
 
     public TranslatingCursor(@NonNull Cursor cursor, @NonNull Config config,
             @NonNull Translator translator, boolean dropLast) {
@@ -70,9 +71,12 @@
         mDropLast = dropLast;
 
         mAuxiliaryColumnIndex = cursor.getColumnIndexOrThrow(config.auxiliaryColumn);
-        mTranslateColumnIndices = new int[config.translateColumns.length];
-        for (int i = 0; i < mTranslateColumnIndices.length; ++i) {
-            mTranslateColumnIndices[i] = cursor.getColumnIndex(config.translateColumns[i]);
+        mTranslateColumnIndices = new ArraySet<>();
+        for (int i = 0; i < cursor.getColumnCount(); ++i) {
+            String columnName = cursor.getColumnName(i);
+            if (ArrayUtils.contains(config.translateColumns, columnName)) {
+                mTranslateColumnIndices.add(i);
+            }
         }
     }
 
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index a73a719..014bc24 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -39,6 +39,7 @@
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 /**
@@ -47,11 +48,15 @@
  */
 public class SQLiteQueryBuilder {
     private static final String TAG = "SQLiteQueryBuilder";
+
     private static final Pattern sLimitPattern =
             Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?");
+    private static final Pattern sAggregationPattern = Pattern.compile(
+            "(?i)(AVG|COUNT|MAX|MIN|SUM|TOTAL)\\((.+)\\)");
 
     private Map<String, String> mProjectionMap = null;
     private List<Pattern> mProjectionGreylist = null;
+    private boolean mProjectionAggregationAllowed = false;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private String mTables = "";
@@ -80,7 +85,7 @@
      * Get if the query is marked as {@code DISTINCT}, as last configured by
      * {@link #setDistinct(boolean)}.
      */
-    public boolean getDistinct() {
+    public boolean isDistinct() {
         return mDistinct;
     }
 
@@ -203,6 +208,16 @@
         return mProjectionGreylist;
     }
 
+    /** {@hide} */
+    public void setProjectionAggregationAllowed(boolean projectionAggregationAllowed) {
+        mProjectionAggregationAllowed = projectionAggregationAllowed;
+    }
+
+    /** {@hide} */
+    public boolean isProjectionAggregationAllowed() {
+        return mProjectionAggregationAllowed;
+    }
+
     /**
      * Sets the cursor factory to be used for the query.  You can use
      * one factory for all queries on a database but it is normally
@@ -215,7 +230,7 @@
     }
 
     /**
-     * Sets the cursor factory to be used for the query, as last configured by
+     * Gets the cursor factory to be used for the query, as last configured by
      * {@link #setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory)}.
      */
     public @Nullable SQLiteDatabase.CursorFactory getCursorFactory() {
@@ -251,7 +266,7 @@
      * Get if the query is marked as strict, as last configured by
      * {@link #setStrict(boolean)}.
      */
-    public boolean getStrict() {
+    public boolean isStrict() {
         return mStrict;
     }
 
@@ -842,26 +857,48 @@
         return query.toString();
     }
 
+    private static @NonNull String maybeWithOperator(@Nullable String operator,
+            @NonNull String column) {
+        if (operator != null) {
+            return operator + "(" + column + ")";
+        } else {
+            return column;
+        }
+    }
+
+    /** {@hide} */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    private String[] computeProjection(String[] projectionIn) {
+    public String[] computeProjection(String[] projectionIn) {
         if (projectionIn != null && projectionIn.length > 0) {
             if (mProjectionMap != null) {
                 String[] projection = new String[projectionIn.length];
                 int length = projectionIn.length;
 
                 for (int i = 0; i < length; i++) {
+                    String operator = null;
                     String userColumn = projectionIn[i];
                     String column = mProjectionMap.get(userColumn);
 
+                    // If aggregation is allowed, extract the underlying column
+                    // that may be aggregated
+                    if (mProjectionAggregationAllowed) {
+                        final Matcher matcher = sAggregationPattern.matcher(userColumn);
+                        if (matcher.matches()) {
+                            operator = matcher.group(1);
+                            userColumn = matcher.group(2);
+                            column = mProjectionMap.get(userColumn);
+                        }
+                    }
+
                     if (column != null) {
-                        projection[i] = column;
+                        projection[i] = maybeWithOperator(operator, column);
                         continue;
                     }
 
                     if (!mStrict &&
                             ( userColumn.contains(" AS ") || userColumn.contains(" as "))) {
                         /* A column alias already exist */
-                        projection[i] = userColumn;
+                        projection[i] = maybeWithOperator(operator, userColumn);
                         continue;
                     }
 
@@ -878,7 +915,7 @@
 
                         if (match) {
                             Log.w(TAG, "Allowing abusive custom column: " + userColumn);
-                            projection[i] = userColumn;
+                            projection[i] = maybeWithOperator(operator, userColumn);
                             continue;
                         }
                     }
@@ -911,7 +948,8 @@
         return null;
     }
 
-    private @Nullable String computeWhere(@Nullable String selection) {
+    /** {@hide} */
+    public @Nullable String computeWhere(@Nullable String selection) {
         final boolean hasInternal = !TextUtils.isEmpty(mWhereClause);
         final boolean hasExternal = !TextUtils.isEmpty(selection);
 
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index c39796b..6a2d8d8 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -2680,10 +2680,12 @@
      * MAXIMUM resolutions and anything smaller from the list given by
      * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } are
      * guaranteed to work.
-     * The mandatory stream combination array will be {@code null} in case the device is a
-     * physical camera not independently exposed in
-     * {@link android.hardware.camera2.CameraManager#getCameraIdList } or is not backward
-     * compatible.</p>
+     * For a physical camera not independently exposed in
+     * {@link android.hardware.camera2.CameraManager#getCameraIdList }, the mandatory stream
+     * combinations for that physical camera Id are also generated, so that the application can
+     * configure them as physical streams via the logical camera.
+     * The mandatory stream combination array will be {@code null} in case the device is not
+     * backward compatible.</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
      * <p><b>Limited capability</b> -
      * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
@@ -3894,6 +3896,8 @@
      * <p>In both cases, all images generated for a particular capture request still carry the same
      * timestamps, so that they can be used to look up the matching frame number and
      * onCaptureStarted callback.</p>
+     * <p>This tag is only applicable if the logical camera device supports concurrent physical
+     * streams from different physical cameras.</p>
      * <p><b>Possible values:</b>
      * <ul>
      *   <li>{@link #LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE APPROXIMATE}</li>
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index d5d25c5..b0142ea 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -314,12 +314,10 @@
                 } else {
                     // Normal path: Get the camera characteristics directly from the camera service
                     CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
-                    if (!isHiddenPhysicalCamera(cameraId)) {
-                        try {
-                            info.setCameraId(Integer.parseInt(cameraId));
-                        } catch (NumberFormatException e) {
-                            Log.e(TAG, "Failed to parse camera Id " + cameraId + " to integer");
-                        }
+                    try {
+                        info.setCameraId(Integer.parseInt(cameraId));
+                    } catch (NumberFormatException e) {
+                        Log.e(TAG, "Failed to parse camera Id " + cameraId + " to integer");
                     }
                     info.setDisplaySize(displaySize);
 
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index a3e561c..9e0ee58 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -825,14 +825,23 @@
     public static final int REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING = 10;
 
     /**
-     * <p>The camera device is a logical camera backed by two or more physical cameras. In
-     * API level 28, the physical cameras must also be exposed to the application via
-     * {@link android.hardware.camera2.CameraManager#getCameraIdList }. Starting from API
-     * level 29, some or all physical cameras may not be independently exposed to the
-     * application, in which case the physical camera IDs will not be available in
-     * {@link android.hardware.camera2.CameraManager#getCameraIdList }. But the application
-     * can still query the physical cameras' characteristics by calling
-     * {@link android.hardware.camera2.CameraManager#getCameraCharacteristics }.</p>
+     * <p>The camera device is a logical camera backed by two or more physical cameras.</p>
+     * <p>In API level 28, the physical cameras must also be exposed to the application via
+     * {@link android.hardware.camera2.CameraManager#getCameraIdList }.</p>
+     * <p>Starting from API level 29, some or all physical cameras may not be independently
+     * exposed to the application, in which case the physical camera IDs will not be
+     * available in {@link android.hardware.camera2.CameraManager#getCameraIdList }. But the
+     * application can still query the physical cameras' characteristics by calling
+     * {@link android.hardware.camera2.CameraManager#getCameraCharacteristics }. Additionally,
+     * if a physical camera is hidden from camera ID list, the mandatory stream combinations
+     * for that physical camera must be supported through the logical camera using physical
+     * streams.</p>
+     * <p>Combinations of logical and physical streams, or physical streams from different
+     * physical cameras are not guaranteed. However, if the camera device supports
+     * {@link CameraDevice#isSessionConfigurationSupported },
+     * application must be able to query whether a stream combination involving physical
+     * streams is supported by calling
+     * {@link CameraDevice#isSessionConfigurationSupported }.</p>
      * <p>Camera application shouldn't assume that there are at most 1 rear camera and 1 front
      * camera in the system. For an application that switches between front and back cameras,
      * the recommendation is to switch between the first rear camera and the first front
@@ -857,24 +866,6 @@
      *   the same.</li>
      * <li>The logical camera must be LIMITED or higher device.</li>
      * </ul>
-     * <p>Both the logical camera device and its underlying physical devices support the
-     * mandatory stream combinations required for their device levels.</p>
-     * <p>Additionally, for each guaranteed stream combination, the logical camera supports:</p>
-     * <ul>
-     * <li>For each guaranteed stream combination, the logical camera supports replacing one
-     *   logical {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}
-     *   or raw stream with two physical streams of the same size and format, each from a
-     *   separate physical camera, given that the size and format are supported by both
-     *   physical cameras.</li>
-     * <li>If the logical camera doesn't advertise RAW capability, but the underlying physical
-     *   cameras do, the logical camera will support guaranteed stream combinations for RAW
-     *   capability, except that the RAW streams will be physical streams, each from a separate
-     *   physical camera. This is usually the case when the physical cameras have different
-     *   sensor sizes.</li>
-     * </ul>
-     * <p>Using physical streams in place of a logical stream of the same size and format will
-     * not slow down the frame rate of the capture, as long as the minimum frame duration
-     * of the physical and logical streams are the same.</p>
      * <p>A logical camera device's dynamic metadata may contain
      * {@link CaptureResult#LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID android.logicalMultiCamera.activePhysicalId} to notify the application of the current
      * active physical camera Id. An active physical camera is the physical camera from which
diff --git a/core/java/android/hardware/camera2/CaptureFailure.java b/core/java/android/hardware/camera2/CaptureFailure.java
index cd2bc5f..20ca4a3 100644
--- a/core/java/android/hardware/camera2/CaptureFailure.java
+++ b/core/java/android/hardware/camera2/CaptureFailure.java
@@ -17,6 +17,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -61,17 +62,19 @@
     private final boolean mDropped;
     private final int mSequenceId;
     private final long mFrameNumber;
+    private final String mErrorPhysicalCameraId;
 
     /**
      * @hide
      */
     public CaptureFailure(CaptureRequest request, int reason,
-            boolean dropped, int sequenceId, long frameNumber) {
+            boolean dropped, int sequenceId, long frameNumber, String errorPhysicalCameraId) {
         mRequest = request;
         mReason = reason;
         mDropped = dropped;
         mSequenceId = sequenceId;
         mFrameNumber = frameNumber;
+        mErrorPhysicalCameraId = errorPhysicalCameraId;
     }
 
     /**
@@ -155,4 +158,17 @@
     public int getSequenceId() {
         return mSequenceId;
     }
+
+    /**
+     * The physical camera device ID in case the capture failure comes from a {@link CaptureRequest}
+     * with configured physical camera streams for a logical camera.
+     *
+     * @return String The physical camera device ID of the respective failing output.
+     *         {@code null} in case the capture request has no associated physical camera device.
+     * @see CaptureRequest.Builder#setPhysicalCameraKey
+     * @see android.hardware.camera2.params.OutputConfiguration#setPhysicalCameraId
+     */
+    public @Nullable String getPhysicalCameraId() {
+        return mErrorPhysicalCameraId;
+    }
 }
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 57b608f..fc12b09 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -2232,6 +2232,7 @@
             final int requestId = resultExtras.getRequestId();
             final int subsequenceId = resultExtras.getSubsequenceId();
             final long frameNumber = resultExtras.getFrameNumber();
+            final String errorPhysicalCameraId = resultExtras.getErrorPhysicalCameraId();
             final CaptureCallbackHolder holder =
                     CameraDeviceImpl.this.mCaptureCallbackMap.get(requestId);
 
@@ -2287,7 +2288,8 @@
                     reason,
                     /*dropped*/ mayHaveBuffers,
                     requestId,
-                    frameNumber);
+                    frameNumber,
+                    errorPhysicalCameraId);
 
                 failureDispatch = new Runnable() {
                     @Override
diff --git a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
index edc3d91..1ff5bd5 100644
--- a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
+++ b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java
@@ -29,6 +29,7 @@
     private long frameNumber;
     private int partialResultCount;
     private int errorStreamId;
+    private String errorPhysicalCameraId;
 
     public static final @android.annotation.NonNull Parcelable.Creator<CaptureResultExtras> CREATOR =
             new Parcelable.Creator<CaptureResultExtras>() {
@@ -49,7 +50,8 @@
 
     public CaptureResultExtras(int requestId, int subsequenceId, int afTriggerId,
                                int precaptureTriggerId, long frameNumber,
-                               int partialResultCount, int errorStreamId) {
+                               int partialResultCount, int errorStreamId,
+                               String errorPhysicalCameraId) {
         this.requestId = requestId;
         this.subsequenceId = subsequenceId;
         this.afTriggerId = afTriggerId;
@@ -57,6 +59,7 @@
         this.frameNumber = frameNumber;
         this.partialResultCount = partialResultCount;
         this.errorStreamId = errorStreamId;
+        this.errorPhysicalCameraId = errorPhysicalCameraId;
     }
 
     @Override
@@ -73,6 +76,12 @@
         dest.writeLong(frameNumber);
         dest.writeInt(partialResultCount);
         dest.writeInt(errorStreamId);
+        if ((errorPhysicalCameraId != null) && !errorPhysicalCameraId.isEmpty()) {
+            dest.writeBoolean(true);
+            dest.writeString(errorPhysicalCameraId);
+        } else {
+            dest.writeBoolean(false);
+        }
     }
 
     public void readFromParcel(Parcel in) {
@@ -83,6 +92,14 @@
         frameNumber = in.readLong();
         partialResultCount = in.readInt();
         errorStreamId = in.readInt();
+        boolean errorPhysicalCameraIdPresent = in.readBoolean();
+        if (errorPhysicalCameraIdPresent) {
+            errorPhysicalCameraId = in.readString();
+        }
+    }
+
+    public String getErrorPhysicalCameraId() {
+        return errorPhysicalCameraId;
     }
 
     public int getRequestId() {
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
index aff09f2..908ed09 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
@@ -109,11 +109,11 @@
         }
         if (holder == null) {
             return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE,
-                    ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE);
+                    ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, null);
         }
         return new CaptureResultExtras(holder.getRequestId(), holder.getSubsequeceId(),
                 /*afTriggerId*/0, /*precaptureTriggerId*/0, holder.getFrameNumber(),
-                /*partialResultCount*/1, errorStreamId);
+                /*partialResultCount*/1, errorStreamId, null);
     }
 
     /**
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index da0899b..690df1a 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -333,6 +333,16 @@
         startPreview();
     }
 
+    private void disconnectCallbackSurfaces() {
+        for (Surface s : mCallbackOutputs) {
+            try {
+                LegacyCameraDevice.disconnectSurface(s);
+            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
+                Log.d(TAG, "Surface abandoned, skipping...", e);
+            }
+        }
+    }
+
     private void configureOutputs(Collection<Pair<Surface, Size>> outputs) {
         if (DEBUG) {
             String outputsStr = outputs == null ? "null" : (outputs.size() + " surfaces");
@@ -370,14 +380,8 @@
             mGLThreadManager.waitUntilIdle();
         }
         resetJpegSurfaceFormats(mCallbackOutputs);
+        disconnectCallbackSurfaces();
 
-        for (Surface s : mCallbackOutputs) {
-            try {
-                LegacyCameraDevice.disconnectSurface(s);
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping...", e);
-            }
-        }
         mPreviewOutputs.clear();
         mCallbackOutputs.clear();
         mJpegSurfaceIds.clear();
@@ -972,11 +976,11 @@
                         mGLThreadManager.quit();
                         mGLThreadManager = null;
                     }
+                    disconnectCallbackSurfaces();
                     if (mCamera != null) {
                         mCamera.release();
                         mCamera = null;
                     }
-                    resetJpegSurfaceFormats(mCallbackOutputs);
                     break;
                 case RequestHandlerThread.MSG_POKE_IDLE_HANDLER:
                     // OK: Ignore message.
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index b122f19..c45b8ed 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -48,7 +48,10 @@
         return pulseOnNotificationEnabled(user)
                 || pulseOnLongPressEnabled(user)
                 || alwaysOnEnabled(user)
-                || wakeScreenGestureEnabled(user);
+                || wakeScreenGestureEnabled(user)
+                || pickupGestureEnabled(user)
+                || tapGestureEnabled(user)
+                || doubleTapGestureEnabled(user);
     }
 
     /** {@hide} */
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 2923bbf..0daf30f25 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.input;
 
+import android.graphics.Rect;
 import android.hardware.input.InputDeviceIdentifier;
 import android.hardware.input.KeyboardLayout;
 import android.hardware.input.IInputDevicesChangedListener;
@@ -24,6 +25,7 @@
 import android.os.IBinder;
 import android.view.InputDevice;
 import android.view.InputEvent;
+import android.view.InputMonitor;
 import android.view.PointerIcon;
 
 /** @hide */
@@ -82,4 +84,7 @@
     void setCustomPointerIcon(in PointerIcon icon);
 
     void requestPointerCapture(IBinder windowToken, boolean enabled);
+
+    /** Create an input monitor for gestures. */
+    InputMonitor monitorGestureInput(String name, int displayId);
 }
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index fec5c34..2a59be2 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -41,6 +41,7 @@
 import android.util.SparseArray;
 import android.view.InputDevice;
 import android.view.InputEvent;
+import android.view.InputMonitor;
 import android.view.MotionEvent;
 import android.view.PointerIcon;
 
@@ -933,6 +934,19 @@
         }
     }
 
+    /**
+     * Monitor input on the specified display for gestures.
+     *
+     * @hide
+     */
+    public InputMonitor monitorGestureInput(String name, int displayId) {
+        try {
+            return mIm.monitorGestureInput(name, displayId);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
     private void populateInputDevicesLocked() {
         if (mInputDevicesChangedListener == null) {
             final InputDevicesChangedListener listener = new InputDevicesChangedListener();
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index cf3395a..5b5bd76 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -25,6 +25,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
+import android.app.ActivityThread;
 import android.media.AudioFormat;
 import android.os.Handler;
 import android.os.Parcel;
@@ -1440,6 +1441,17 @@
     public static final int SERVICE_STATE_DISABLED = 1;
 
     /**
+     * @return returns current package name.
+     */
+    static String getCurrentOpPackageName() {
+        String packageName = ActivityThread.currentOpPackageName();
+        if (packageName == null) {
+            return "";
+        }
+        return packageName;
+    }
+
+    /**
      * Returns a list of descriptors for all hardware modules loaded.
      * @param modules A ModuleProperties array where the list will be returned.
      * @return - {@link #STATUS_OK} in case of success
@@ -1452,7 +1464,23 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public static native int listModules(ArrayList <ModuleProperties> modules);
+    public static int listModules(ArrayList<ModuleProperties> modules) {
+        return listModules(getCurrentOpPackageName(), modules);
+    }
+
+    /**
+     * Returns a list of descriptors for all hardware modules loaded.
+     * @param opPackageName
+     * @param modules A ModuleProperties array where the list will be returned.
+     * @return - {@link #STATUS_OK} in case of success
+     *         - {@link #STATUS_ERROR} in case of unspecified error
+     *         - {@link #STATUS_PERMISSION_DENIED} if the caller does not have system permission
+     *         - {@link #STATUS_NO_INIT} if the native service cannot be reached
+     *         - {@link #STATUS_BAD_VALUE} if modules is null
+     *         - {@link #STATUS_DEAD_OBJECT} if the binder transaction to the native service fails
+     */
+    private static native int listModules(String opPackageName,
+                                          ArrayList<ModuleProperties> modules);
 
     /**
      * Get an interface on a hardware module to control sound models and recognition on
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
index 402c228..9113548 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -46,9 +46,10 @@
     SoundTriggerModule(int moduleId, SoundTrigger.StatusListener listener, Handler handler) {
         mId = moduleId;
         mEventHandlerDelegate = new NativeEventHandlerDelegate(listener, handler);
-        native_setup(new WeakReference<SoundTriggerModule>(this));
+        native_setup(SoundTrigger.getCurrentOpPackageName(),
+                new WeakReference<SoundTriggerModule>(this));
     }
-    private native void native_setup(Object module_this);
+    private native void native_setup(String opPackageName, Object moduleThis);
 
     @Override
     protected void finalize() {
diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java
index 1339432..a66fcae 100644
--- a/core/java/android/net/CaptivePortal.java
+++ b/core/java/android/net/CaptivePortal.java
@@ -137,6 +137,8 @@
 
     /**
      * Log a captive portal login event.
+     * @param eventId one of the CAPTIVE_PORTAL_LOGIN_* constants in metrics_constants.proto.
+     * @param packageName captive portal application package name.
      * @hide
      */
     @SystemApi
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ae93cf0..2906710 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1934,6 +1934,8 @@
             @NonNull Callback callback) {
         ParcelFileDescriptor dup;
         try {
+            // Dup is needed here as the pfd inside the socket is owned by the IpSecService,
+            // which cannot be obtained by the app process.
             dup = ParcelFileDescriptor.dup(socket.getFileDescriptor());
         } catch (IOException ignored) {
             // Construct an invalid fd, so that if the user later calls start(), it will fail with
@@ -1975,6 +1977,7 @@
             @NonNull Callback callback) {
         ParcelFileDescriptor dup;
         try {
+            // TODO: Consider remove unnecessary dup.
             dup = pfd.dup();
         } catch (IOException ignored) {
             // Construct an invalid fd, so that if the user later calls start(), it will fail with
@@ -2614,7 +2617,7 @@
 
     /**
      * Start listening to tethering change events. Any new added callback will receive the last
-     * tethering status right away. If callback is registered when tethering loses its upstream or
+     * tethering status right away. If callback is registered when tethering has no upstream or
      * disabled, {@link OnTetheringEventCallback#onUpstreamChanged} will immediately be called
      * with a null argument. The same callback object cannot be registered twice.
      *
@@ -3231,7 +3234,7 @@
          *
          * @hide
          */
-        public void onPreCheck(Network network) {}
+        public void onPreCheck(@NonNull Network network) {}
 
         /**
          * Called when the framework connects and has declared a new network ready for use.
@@ -3244,8 +3247,9 @@
          * @param blocked Whether access to the {@link Network} is blocked due to system policy.
          * @hide
          */
-        public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
-                LinkProperties linkProperties, boolean blocked) {
+        public void onAvailable(@NonNull Network network,
+                @NonNull NetworkCapabilities networkCapabilities,
+                @NonNull LinkProperties linkProperties, boolean blocked) {
             // Internally only this method is called when a new network is available, and
             // it calls the callback in the same way and order that older versions used
             // to call so as not to change the behavior.
@@ -3269,7 +3273,7 @@
          *
          * @param network The {@link Network} of the satisfying network.
          */
-        public void onAvailable(Network network) {}
+        public void onAvailable(@NonNull Network network) {}
 
         /**
          * Called when the network is about to be disconnected.  Often paired with an
@@ -3285,7 +3289,7 @@
          *                     network connected.  Note that the network may suffer a
          *                     hard loss at any time.
          */
-        public void onLosing(Network network, int maxMsToLive) {}
+        public void onLosing(@NonNull Network network, int maxMsToLive) {}
 
         /**
          * Called when the framework has a hard loss of the network or when the
@@ -3293,7 +3297,7 @@
          *
          * @param network The {@link Network} lost.
          */
-        public void onLost(Network network) {}
+        public void onLost(@NonNull Network network) {}
 
         /**
          * Called if no network is found in the timeout time specified in
@@ -3313,8 +3317,8 @@
          * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this
          *                            network.
          */
-        public void onCapabilitiesChanged(Network network,
-                NetworkCapabilities networkCapabilities) {}
+        public void onCapabilitiesChanged(@NonNull Network network,
+                @NonNull NetworkCapabilities networkCapabilities) {}
 
         /**
          * Called when the network the framework connected to for this request
@@ -3323,7 +3327,8 @@
          * @param network The {@link Network} whose link properties have changed.
          * @param linkProperties The new {@link LinkProperties} for this network.
          */
-        public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
+        public void onLinkPropertiesChanged(@NonNull Network network,
+                @NonNull LinkProperties linkProperties) {}
 
         /**
          * Called when the network the framework connected to for this request
@@ -3334,7 +3339,7 @@
          * a tunnel, etc.
          * @hide
          */
-        public void onNetworkSuspended(Network network) {}
+        public void onNetworkSuspended(@NonNull Network network) {}
 
         /**
          * Called when the network the framework connected to for this request
@@ -3342,7 +3347,7 @@
          * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call.
          * @hide
          */
-        public void onNetworkResumed(Network network) {}
+        public void onNetworkResumed(@NonNull Network network) {}
 
         /**
          * Called when access to the specified network is blocked or unblocked.
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 1a3a6f8..2e52f72 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -72,15 +72,12 @@
      * Create a {@link StaticIpConfiguration} based on the DhcpResults.
      */
     public StaticIpConfiguration toStaticIpConfiguration() {
-        final StaticIpConfiguration s = new StaticIpConfiguration();
-        // All these except dnsServers are immutable, so no need to make copies.
-        s.setIpAddress(ipAddress);
-        s.setGateway(gateway);
-        for (InetAddress addr : dnsServers) {
-            s.addDnsServer(addr);
-        }
-        s.setDomains(domains);
-        return s;
+        return new StaticIpConfiguration.Builder()
+                .setIpAddress(ipAddress)
+                .setGateway(gateway)
+                .setDnsServers(dnsServers)
+                .setDomains(domains)
+                .build();
     }
 
     public DhcpResults(StaticIpConfiguration source) {
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index 5980251..06c32c6 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -22,6 +22,10 @@
 import static android.net.NetworkUtils.resNetworkSend;
 import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
 import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.SOCK_DGRAM;
 
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
@@ -30,12 +34,18 @@
 import android.os.CancellationSignal;
 import android.os.Looper;
 import android.system.ErrnoException;
+import android.system.Os;
 import android.util.Log;
 
+import libcore.io.IoUtils;
+
 import java.io.FileDescriptor;
+import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.List;
@@ -52,6 +62,7 @@
     private static final String TAG = "DnsResolver";
     private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
     private static final int MAXPACKET = 8 * 1024;
+    private static final int SLEEP_TIME_MS = 2;
 
     @IntDef(prefix = { "CLASS_" }, value = {
             CLASS_IN
@@ -188,9 +199,9 @@
      * Send a raw DNS query.
      * The answer will be provided asynchronously through the provided {@link AnswerCallback}.
      *
-     * @param network {@link Network} specifying which network for querying.
+     * @param network {@link Network} specifying which network to query on.
      *         {@code null} for query on default network.
-     * @param query blob message
+     * @param query blob message to query
      * @param flags flags as a combination of the FLAGS_* constants
      * @param executor The {@link Executor} that the callback should be executed on.
      * @param cancellationSignal used by the caller to signal if the query should be
@@ -205,26 +216,32 @@
         if (cancellationSignal != null && cancellationSignal.isCanceled()) {
             return;
         }
+        final Object lock = new Object();
         final FileDescriptor queryfd;
         try {
             queryfd = resNetworkSend((network != null
                 ? network.netId : NETID_UNSET), query, query.length, flags);
         } catch (ErrnoException e) {
-            callback.onQueryException(e);
+            executor.execute(() -> {
+                callback.onQueryException(e);
+            });
             return;
         }
 
-        maybeAddCancellationSignal(cancellationSignal, queryfd);
-        registerFDListener(executor, queryfd, callback);
+        synchronized (lock)  {
+            registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
+            if (cancellationSignal == null) return;
+            addCancellationSignal(cancellationSignal, queryfd, lock);
+        }
     }
 
     /**
      * Send a DNS query with the specified name, class and query type.
      * The answer will be provided asynchronously through the provided {@link AnswerCallback}.
      *
-     * @param network {@link Network} specifying which network for querying.
+     * @param network {@link Network} specifying which network to query on.
      *         {@code null} for query on default network.
-     * @param domain domain name for querying
+     * @param domain domain name to query
      * @param nsClass dns class as one of the CLASS_* constants
      * @param nsType dns resource record (RR) type as one of the TYPE_* constants
      * @param flags flags as a combination of the FLAGS_* constants
@@ -242,40 +259,187 @@
         if (cancellationSignal != null && cancellationSignal.isCanceled()) {
             return;
         }
+        final Object lock = new Object();
         final FileDescriptor queryfd;
         try {
             queryfd = resNetworkQuery((network != null
                     ? network.netId : NETID_UNSET), domain, nsClass, nsType, flags);
         } catch (ErrnoException e) {
-            callback.onQueryException(e);
+            executor.execute(() -> {
+                callback.onQueryException(e);
+            });
             return;
         }
+        synchronized (lock)  {
+            registerFDListener(executor, queryfd, callback, cancellationSignal, lock);
+            if (cancellationSignal == null) return;
+            addCancellationSignal(cancellationSignal, queryfd, lock);
+        }
+    }
 
-        maybeAddCancellationSignal(cancellationSignal, queryfd);
-        registerFDListener(executor, queryfd, callback);
+    private class InetAddressAnswerAccumulator extends InetAddressAnswerCallback {
+        private final List<InetAddress> mAllAnswers;
+        private ParseException mParseException;
+        private ErrnoException mErrnoException;
+        private final InetAddressAnswerCallback mUserCallback;
+        private final int mTargetAnswerCount;
+        private int mReceivedAnswerCount = 0;
+
+        InetAddressAnswerAccumulator(int size, @NonNull InetAddressAnswerCallback callback) {
+            mTargetAnswerCount = size;
+            mAllAnswers = new ArrayList<>();
+            mUserCallback = callback;
+        }
+
+        private boolean maybeReportException() {
+            if (mErrnoException != null) {
+                mUserCallback.onQueryException(mErrnoException);
+                return true;
+            }
+            if (mParseException != null) {
+                mUserCallback.onParseException(mParseException);
+                return true;
+            }
+            return false;
+        }
+
+        private void maybeReportAnswer() {
+            if (++mReceivedAnswerCount != mTargetAnswerCount) return;
+            if (mAllAnswers.isEmpty() && maybeReportException()) return;
+            // TODO: Do RFC6724 sort.
+            mUserCallback.onAnswer(mAllAnswers);
+        }
+
+        @Override
+        public void onAnswer(@NonNull List<InetAddress> answer) {
+            mAllAnswers.addAll(answer);
+            maybeReportAnswer();
+        }
+
+        @Override
+        public void onParseException(@NonNull ParseException e) {
+            mParseException = e;
+            maybeReportAnswer();
+        }
+
+        @Override
+        public void onQueryException(@NonNull ErrnoException e) {
+            mErrnoException = e;
+            maybeReportAnswer();
+        }
+    }
+
+    /**
+     * Send a DNS query with the specified name, get back a set of InetAddresses asynchronously.
+     * The answer will be provided asynchronously through the provided
+     * {@link InetAddressAnswerCallback}.
+     *
+     * @param network {@link Network} specifying which network to query on.
+     *         {@code null} for query on default network.
+     * @param domain domain name to query
+     * @param flags flags as a combination of the FLAGS_* constants
+     * @param executor The {@link Executor} that the callback should be executed on.
+     * @param cancellationSignal used by the caller to signal if the query should be
+     *    cancelled. May be {@code null}.
+     * @param callback an {@link InetAddressAnswerCallback} which will be called to notify the
+     *    caller of the result of dns query.
+     */
+    public void query(@Nullable Network network, @NonNull String domain, @QueryFlag int flags,
+            @NonNull @CallbackExecutor Executor executor,
+            @Nullable CancellationSignal cancellationSignal,
+            @NonNull InetAddressAnswerCallback callback) {
+        if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+            return;
+        }
+        final Object lock = new Object();
+        final boolean queryIpv6 = haveIpv6(network);
+        final boolean queryIpv4 = haveIpv4(network);
+
+        final FileDescriptor v4fd;
+        final FileDescriptor v6fd;
+
+        int queryCount = 0;
+
+        if (queryIpv6) {
+            try {
+                v6fd = resNetworkQuery((network != null
+                        ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_AAAA, flags);
+            } catch (ErrnoException e) {
+                executor.execute(() -> {
+                    callback.onQueryException(e);
+                });
+                return;
+            }
+            queryCount++;
+        } else v6fd = null;
+
+        // TODO: Use device flag to control the sleep time.
+        // Avoiding gateways drop packets if queries are sent too close together
+        try {
+            Thread.sleep(SLEEP_TIME_MS);
+        } catch (InterruptedException ex) { }
+
+        if (queryIpv4) {
+            try {
+                v4fd = resNetworkQuery((network != null
+                        ? network.netId : NETID_UNSET), domain, CLASS_IN, TYPE_A, flags);
+            } catch (ErrnoException e) {
+                if (queryIpv6) resNetworkCancel(v6fd);  // Closes fd, marks it invalid.
+                executor.execute(() -> {
+                    callback.onQueryException(e);
+                });
+                return;
+            }
+            queryCount++;
+        } else v4fd = null;
+
+        final InetAddressAnswerAccumulator accumulator =
+                new InetAddressAnswerAccumulator(queryCount, callback);
+
+        synchronized (lock)  {
+            if (queryIpv6) {
+                registerFDListener(executor, v6fd, accumulator, cancellationSignal, lock);
+            }
+            if (queryIpv4) {
+                registerFDListener(executor, v4fd, accumulator, cancellationSignal, lock);
+            }
+            if (cancellationSignal == null) return;
+            cancellationSignal.setOnCancelListener(() -> {
+                synchronized (lock)  {
+                    if (queryIpv4) cancelQuery(v4fd);
+                    if (queryIpv6) cancelQuery(v6fd);
+                }
+            });
+        }
     }
 
     private <T> void registerFDListener(@NonNull Executor executor,
-            @NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback) {
+            @NonNull FileDescriptor queryfd, @NonNull AnswerCallback<T> answerCallback,
+            @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) {
         Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener(
                 queryfd,
                 FD_EVENTS,
                 (fd, events) -> {
                     executor.execute(() -> {
-                        byte[] answerbuf = null;
-                        try {
-                            answerbuf = resNetworkResult(fd);
-                        } catch (ErrnoException e) {
-                            Log.e(TAG, "resNetworkResult:" + e.toString());
-                            answerCallback.onQueryException(e);
-                            return;
-                        }
+                        synchronized (lock) {
+                            if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+                                return;
+                            }
+                            byte[] answerbuf = null;
+                            try {
+                                answerbuf = resNetworkResult(fd);  // Closes fd, marks it invalid.
+                            } catch (ErrnoException e) {
+                                Log.e(TAG, "resNetworkResult:" + e.toString());
+                                answerCallback.onQueryException(e);
+                                return;
+                            }
 
-                        try {
-                            answerCallback.onAnswer(
-                                    answerCallback.parser.parse(answerbuf));
-                        } catch (ParseException e) {
-                            answerCallback.onParseException(e);
+                            try {
+                                answerCallback.onAnswer(
+                                        answerCallback.parser.parse(answerbuf));
+                            } catch (ParseException e) {
+                                answerCallback.onParseException(e);
+                            }
                         }
                     });
                     // Unregister this fd listener
@@ -283,15 +447,51 @@
                 });
     }
 
-    private void maybeAddCancellationSignal(@Nullable CancellationSignal cancellationSignal,
-            @NonNull FileDescriptor queryfd) {
-        if (cancellationSignal == null) return;
-        cancellationSignal.setOnCancelListener(
-                () -> {
-                    Looper.getMainLooper().getQueue()
-                            .removeOnFileDescriptorEventListener(queryfd);
-                    resNetworkCancel(queryfd);
-            });
+    private void cancelQuery(@NonNull FileDescriptor queryfd) {
+        if (!queryfd.valid()) return;
+        Looper.getMainLooper().getQueue().removeOnFileDescriptorEventListener(queryfd);
+        resNetworkCancel(queryfd);  // Closes fd, marks it invalid.
+    }
+
+    private void addCancellationSignal(@NonNull CancellationSignal cancellationSignal,
+            @NonNull FileDescriptor queryfd, @NonNull Object lock) {
+        cancellationSignal.setOnCancelListener(() -> {
+            synchronized (lock)  {
+                cancelQuery(queryfd);
+            }
+        });
+    }
+
+    // These two functions match the behaviour of have_ipv4 and have_ipv6 in the native resolver.
+    private boolean haveIpv4(@Nullable Network network) {
+        final SocketAddress addrIpv4 =
+                new InetSocketAddress(InetAddresses.parseNumericAddress("8.8.8.8"), 0);
+        return checkConnectivity(network, AF_INET, addrIpv4);
+    }
+
+    private boolean haveIpv6(@Nullable Network network) {
+        final SocketAddress addrIpv6 =
+                new InetSocketAddress(InetAddresses.parseNumericAddress("2000::"), 0);
+        return checkConnectivity(network, AF_INET6, addrIpv6);
+    }
+
+    private boolean checkConnectivity(@Nullable Network network,
+            int domain, @NonNull SocketAddress addr) {
+        final FileDescriptor socket;
+        try {
+            socket = Os.socket(domain, SOCK_DGRAM, IPPROTO_UDP);
+        } catch (ErrnoException e) {
+            return false;
+        }
+        try {
+            if (network != null) network.bindSocket(socket);
+            Os.connect(socket, addr);
+        } catch (IOException | ErrnoException e) {
+            return false;
+        } finally {
+            IoUtils.closeQuietly(socket);
+        }
+        return true;
     }
 
     private static class DnsAddressAnswer extends DnsPacket {
diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java
index 402bffd..8cfe6df 100644
--- a/core/java/android/net/IpPrefix.java
+++ b/core/java/android/net/IpPrefix.java
@@ -16,6 +16,7 @@
 
 package android.net;
 
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -71,7 +72,7 @@
      *
      * @hide
      */
-    public IpPrefix(@NonNull byte[] address, int prefixLength) {
+    public IpPrefix(@NonNull byte[] address, @IntRange(from = 0, to = 128) int prefixLength) {
         this.address = address.clone();
         this.prefixLength = prefixLength;
         checkAndMaskAddressAndPrefixLength();
@@ -88,7 +89,7 @@
      */
     @SystemApi
     @TestApi
-    public IpPrefix(@NonNull InetAddress address, int prefixLength) {
+    public IpPrefix(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength) {
         // We don't reuse the (byte[], int) constructor because it calls clone() on the byte array,
         // which is unnecessary because getAddress() already returns a clone.
         this.address = address.getAddress();
@@ -150,13 +151,13 @@
      *
      * @return the address in the form of a byte array.
      */
-    public InetAddress getAddress() {
+    public @NonNull InetAddress getAddress() {
         try {
             return InetAddress.getByAddress(address);
         } catch (UnknownHostException e) {
             // Cannot happen. InetAddress.getByAddress can only throw an exception if the byte
             // array is the wrong length, but we check that in the constructor.
-            return null;
+            throw new IllegalArgumentException("Address is invalid");
         }
     }
 
@@ -166,7 +167,7 @@
      *
      * @return the address in the form of a byte array.
      */
-    public byte[] getRawAddress() {
+    public @NonNull byte[] getRawAddress() {
         return address.clone();
     }
 
@@ -175,6 +176,7 @@
      *
      * @return the prefix length.
      */
+    @IntRange(from = 0, to = 128)
     public int getPrefixLength() {
         return prefixLength;
     }
@@ -183,10 +185,10 @@
      * Determines whether the prefix contains the specified address.
      *
      * @param address An {@link InetAddress} to test.
-     * @return {@code true} if the prefix covers the given address.
+     * @return {@code true} if the prefix covers the given address. {@code false} otherwise.
      */
-    public boolean contains(InetAddress address) {
-        byte[] addrBytes = (address == null) ? null : address.getAddress();
+    public boolean contains(@NonNull InetAddress address) {
+        byte[] addrBytes = address.getAddress();
         if (addrBytes == null || addrBytes.length != this.address.length) {
             return false;
         }
@@ -201,7 +203,7 @@
      * @param otherPrefix the prefix to test
      * @hide
      */
-    public boolean containsPrefix(IpPrefix otherPrefix) {
+    public boolean containsPrefix(@NonNull IpPrefix otherPrefix) {
         if (otherPrefix.getPrefixLength() < prefixLength) return false;
         final byte[] otherAddress = otherPrefix.getRawAddress();
         NetworkUtils.maskRawAddress(otherAddress, prefixLength);
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index 333603f..93dd2e4 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -25,6 +25,7 @@
 import static android.system.OsConstants.RT_SCOPE_SITE;
 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -170,7 +171,7 @@
      * Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with
      * the specified flags and scope. Flags and scope are not checked for validity.
      * @param address The IP address.
-     * @param prefixLength The prefix length.
+     * @param prefixLength The prefix length. Must be &gt;= 0 and &lt;= (32 or 128) (IPv4 or IPv6).
      * @param flags A bitmask of {@code IFA_F_*} values representing properties of the address.
      * @param scope An integer defining the scope in which the address is unique (e.g.,
      *              {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}).
@@ -178,7 +179,8 @@
      */
     @SystemApi
     @TestApi
-    public LinkAddress(InetAddress address, int prefixLength, int flags, int scope) {
+    public LinkAddress(@NonNull InetAddress address, @IntRange(from = 0, to = 128) int prefixLength,
+            int flags, int scope) {
         init(address, prefixLength, flags, scope);
     }
 
@@ -186,12 +188,13 @@
      * Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length.
      * The flags are set to zero and the scope is determined from the address.
      * @param address The IP address.
-     * @param prefixLength The prefix length.
+     * @param prefixLength The prefix length. Must be &gt;= 0 and &lt;= (32 or 128) (IPv4 or IPv6).
      * @hide
      */
     @SystemApi
     @TestApi
-    public LinkAddress(@NonNull InetAddress address, int prefixLength) {
+    public LinkAddress(@NonNull InetAddress address,
+            @IntRange(from = 0, to = 128) int prefixLength) {
         this(address, prefixLength, 0, 0);
         this.scope = scopeForUnicastAddress(address);
     }
@@ -202,7 +205,7 @@
      * @param interfaceAddress The interface address.
      * @hide
      */
-    public LinkAddress(InterfaceAddress interfaceAddress) {
+    public LinkAddress(@NonNull InterfaceAddress interfaceAddress) {
         this(interfaceAddress.getAddress(),
              interfaceAddress.getNetworkPrefixLength());
     }
@@ -306,6 +309,7 @@
     /**
      * Returns the prefix length of this {@code LinkAddress}.
      */
+    @IntRange(from = 0, to = 128)
     public int getPrefixLength() {
         return prefixLength;
     }
@@ -316,6 +320,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @IntRange(from = 0, to = 128)
     public int getNetworkPrefixLength() {
         return getPrefixLength();
     }
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index d5ca664..d3f48ac 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -316,9 +316,6 @@
     @SystemApi
     @TestApi
     public boolean removeLinkAddress(@NonNull LinkAddress toRemove) {
-        if (toRemove == null) {
-            return false;
-        }
         int i = findLinkAddressIndex(toRemove);
         if (i >= 0) {
             mLinkAddresses.remove(i);
@@ -391,10 +388,7 @@
     @TestApi
     @SystemApi
     public boolean removeDnsServer(@NonNull InetAddress dnsServer) {
-        if (dnsServer != null) {
-            return mDnses.remove(dnsServer);
-        }
-        return false;
+        return mDnses.remove(dnsServer);
     }
 
     /**
diff --git a/core/java/android/net/NetworkCapabilities.aidl b/core/java/android/net/NetworkCapabilities.aidl
index cd7d71c..01d3286 100644
--- a/core/java/android/net/NetworkCapabilities.aidl
+++ b/core/java/android/net/NetworkCapabilities.aidl
@@ -17,5 +17,5 @@
 
 package android.net;
 
-parcelable NetworkCapabilities;
+@JavaOnlyStableParcelable parcelable NetworkCapabilities;
 
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 51cbed4..4270740 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.net.NetworkCapabilities.NetCapability;
@@ -343,10 +344,14 @@
          * current value. A value of {@code SIGNAL_STRENGTH_UNSPECIFIED} means no value when
          * received and has no effect when requesting a callback.
          *
+         * <p>This method requires the caller to hold the
+         * {@link android.Manifest.permission#NETWORK_SIGNAL_STRENGTH_WAKEUP} permission
+         *
          * @param signalStrength the bearer-specific signal strength.
          * @hide
          */
         @SystemApi
+        @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP)
         public @NonNull Builder setSignalStrength(int signalStrength) {
             mNetworkCapabilities.setSignalStrength(signalStrength);
             return this;
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index b0239c8..52d3fc4 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -24,6 +26,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -51,20 +55,32 @@
  * (IPv4 or IPv6).
  */
 public final class RouteInfo implements Parcelable {
+    /** @hide */
+    @IntDef(value = {
+            RTN_UNICAST,
+            RTN_UNREACHABLE,
+            RTN_THROW,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RouteType {}
+
     /**
      * The IP destination address for this route.
      */
+    @NonNull
     private final IpPrefix mDestination;
 
     /**
      * The gateway address for this route.
      */
     @UnsupportedAppUsage
+    @Nullable
     private final InetAddress mGateway;
 
     /**
      * The interface for this route.
      */
+    @Nullable
     private final String mInterface;
 
 
@@ -108,13 +124,14 @@
      * @param destination the destination prefix
      * @param gateway the IP address to route packets through
      * @param iface the interface name to send packets on
+     * @param type the type of this route
      *
      * @hide
      */
     @SystemApi
     @TestApi
     public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
-            @Nullable String iface, int type) {
+            @Nullable String iface, @RouteType int type) {
         switch (type) {
             case RTN_UNICAST:
             case RTN_UNREACHABLE:
@@ -173,10 +190,24 @@
     }
 
     /**
-     *  @hide
+     * Constructs a {@code RouteInfo} object.
+     *
+     * If destination is null, then gateway must be specified and the
+     * constructed route is either the IPv4 default route <code>0.0.0.0</code>
+     * if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
+     * route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
+     * <p>
+     * Destination and gateway may not both be null.
+     *
+     * @param destination the destination address and prefix in an {@link IpPrefix}
+     * @param gateway the {@link InetAddress} to route packets through
+     * @param iface the interface name to send packets on
+     *
+     * @hide
      */
     @UnsupportedAppUsage
-    public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
+    public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway,
+            @Nullable String iface) {
         this(destination, gateway, iface, RTN_UNICAST);
     }
 
@@ -184,7 +215,8 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
+    public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway,
+            @Nullable String iface) {
         this(destination == null ? null :
                 new IpPrefix(destination.getAddress(), destination.getPrefixLength()),
                 gateway, iface);
@@ -205,7 +237,7 @@
      *
      * @hide
      */
-    public RouteInfo(IpPrefix destination, InetAddress gateway) {
+    public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway) {
         this(destination, gateway, null);
     }
 
@@ -215,7 +247,7 @@
      * TODO: Remove this.
      */
     @UnsupportedAppUsage
-    public RouteInfo(LinkAddress destination, InetAddress gateway) {
+    public RouteInfo(@Nullable LinkAddress destination, @Nullable InetAddress gateway) {
         this(destination, gateway, null);
     }
 
@@ -227,7 +259,7 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public RouteInfo(InetAddress gateway) {
+    public RouteInfo(@NonNull InetAddress gateway) {
         this((IpPrefix) null, gateway, null);
     }
 
@@ -239,35 +271,36 @@
      *
      * @hide
      */
-    public RouteInfo(IpPrefix destination) {
+    public RouteInfo(@NonNull IpPrefix destination) {
         this(destination, null, null);
     }
 
     /**
      * @hide
      */
-    public RouteInfo(LinkAddress destination) {
+    public RouteInfo(@NonNull LinkAddress destination) {
         this(destination, null, null);
     }
 
     /**
      * @hide
      */
-    public RouteInfo(IpPrefix destination, int type) {
+    public RouteInfo(@NonNull IpPrefix destination, @RouteType int type) {
         this(destination, null, null, type);
     }
 
     /**
      * @hide
      */
-    public static RouteInfo makeHostRoute(InetAddress host, String iface) {
+    public static RouteInfo makeHostRoute(@NonNull InetAddress host, @Nullable String iface) {
         return makeHostRoute(host, null, iface);
     }
 
     /**
      * @hide
      */
-    public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) {
+    public static RouteInfo makeHostRoute(@Nullable InetAddress host, @Nullable InetAddress gateway,
+            @Nullable String iface) {
         if (host == null) return null;
 
         if (host instanceof Inet4Address) {
@@ -290,6 +323,7 @@
      *
      * @return {@link IpPrefix} specifying the destination.  This is never {@code null}.
      */
+    @NonNull
     public IpPrefix getDestination() {
         return mDestination;
     }
@@ -298,6 +332,7 @@
      * TODO: Convert callers to use IpPrefix and then remove.
      * @hide
      */
+    @NonNull
     public LinkAddress getDestinationLinkAddress() {
         return new LinkAddress(mDestination.getAddress(), mDestination.getPrefixLength());
     }
@@ -308,6 +343,7 @@
      * @return {@link InetAddress} specifying the gateway or next hop.  This may be
      *                             {@code null} for a directly-connected route."
      */
+    @Nullable
     public InetAddress getGateway() {
         return mGateway;
     }
@@ -317,6 +353,7 @@
      *
      * @return The name of the interface used for this route.
      */
+    @Nullable
     public String getInterface() {
         return mInterface;
     }
@@ -330,6 +367,7 @@
      */
     @TestApi
     @SystemApi
+    @RouteType
     public int getType() {
         return mType;
     }
@@ -401,6 +439,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @Nullable
     public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
         if ((routes == null) || (dest == null)) return null;
 
diff --git a/services/net/java/android/net/StaticIpConfigurationParcelable.aidl b/core/java/android/net/StaticIpConfiguration.aidl
similarity index 78%
rename from services/net/java/android/net/StaticIpConfigurationParcelable.aidl
rename to core/java/android/net/StaticIpConfiguration.aidl
index 6fffb42..8aac701 100644
--- a/services/net/java/android/net/StaticIpConfigurationParcelable.aidl
+++ b/core/java/android/net/StaticIpConfiguration.aidl
@@ -17,11 +17,4 @@
 
 package android.net;
 
-import android.net.LinkAddress;
-
-parcelable StaticIpConfigurationParcelable {
-    LinkAddress ipAddress;
-    String gateway;
-    String[] dnsServers;
-    String domains;
-}
+@JavaOnlyStableParcelable parcelable StaticIpConfiguration;
\ No newline at end of file
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 565f36f..87f8739 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -22,6 +22,7 @@
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.net.shared.InetAddressUtils;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -33,20 +34,19 @@
 /**
  * Class that describes static IP configuration.
  *
- * This class is different from LinkProperties because it represents
+ * <p>This class is different from {@link LinkProperties} because it represents
  * configuration intent. The general contract is that if we can represent
  * a configuration here, then we should be able to configure it on a network.
  * The intent is that it closely match the UI we have for configuring networks.
  *
- * In contrast, LinkProperties represents current state. It is much more
+ * <p>In contrast, {@link LinkProperties} represents current state. It is much more
  * expressive. For example, it supports multiple IP addresses, multiple routes,
  * stacked interfaces, and so on. Because LinkProperties is so expressive,
  * using it to represent configuration intent as well as current state causes
  * problems. For example, we could unknowingly save a configuration that we are
  * not in fact capable of applying, or we could save a configuration that the
  * UI cannot display, which has the potential for malicious code to hide
- * hostile or unexpected configuration from the user: see, for example,
- * http://b/12663469 and http://b/16893413 .
+ * hostile or unexpected configuration from the user.
  *
  * @hide
  */
@@ -54,24 +54,24 @@
 @TestApi
 public final class StaticIpConfiguration implements Parcelable {
     /** @hide */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     @Nullable
     public LinkAddress ipAddress;
     /** @hide */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     @Nullable
     public InetAddress gateway;
     /** @hide */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     @NonNull
     public final ArrayList<InetAddress> dnsServers;
     /** @hide */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     @Nullable
     public String domains;
 
     public StaticIpConfiguration() {
-        dnsServers = new ArrayList<InetAddress>();
+        dnsServers = new ArrayList<>();
     }
 
     public StaticIpConfiguration(@Nullable StaticIpConfiguration source) {
@@ -92,32 +92,96 @@
         domains = null;
     }
 
+    /**
+     * Get the static IP address included in the configuration.
+     */
     public @Nullable LinkAddress getIpAddress() {
         return ipAddress;
     }
 
-    public void setIpAddress(@Nullable LinkAddress ipAddress) {
-        this.ipAddress = ipAddress;
-    }
-
+    /**
+     * Get the gateway included in the configuration.
+     */
     public @Nullable InetAddress getGateway() {
         return gateway;
     }
 
-    public void setGateway(@Nullable InetAddress gateway) {
-        this.gateway = gateway;
-    }
-
+    /**
+     * Get the DNS servers included in the configuration.
+     */
     public @NonNull List<InetAddress> getDnsServers() {
         return dnsServers;
     }
 
+    /**
+     * Get a {@link String} listing in priority order of the comma separated domains to search when
+     * resolving host names on the link.
+     */
     public @Nullable String getDomains() {
         return domains;
     }
 
-    public void setDomains(@Nullable String newDomains) {
-        domains = newDomains;
+    /**
+     * Helper class to build a new instance of {@link StaticIpConfiguration}.
+     */
+    public static final class Builder {
+        private LinkAddress mIpAddress;
+        private InetAddress mGateway;
+        private Iterable<InetAddress> mDnsServers;
+        private String mDomains;
+
+        /**
+         * Set the IP address to be included in the configuration; null by default.
+         * @return The {@link Builder} for chaining.
+         */
+        public @NonNull Builder setIpAddress(@Nullable LinkAddress ipAddress) {
+            mIpAddress = ipAddress;
+            return this;
+        }
+
+        /**
+         * Set the address of the gateway to be included in the configuration; null by default.
+         * @return The {@link Builder} for chaining.
+         */
+        public @NonNull Builder setGateway(@Nullable InetAddress gateway) {
+            mGateway = gateway;
+            return this;
+        }
+
+        /**
+         * Set the addresses of the DNS servers included in the configuration; empty by default.
+         * @return The {@link Builder} for chaining.
+         */
+        public @NonNull Builder setDnsServers(@NonNull Iterable<InetAddress> dnsServers) {
+            mDnsServers = dnsServers;
+            return this;
+        }
+
+        /**
+         * Sets the DNS domain search path to be used on the link; null by default.
+         * @param newDomains A {@link String} containing the comma separated domains to search when
+         *                   resolving host names on this link, in priority order.
+         * @return The {@link Builder} for chaining.
+         */
+        public @NonNull Builder setDomains(@Nullable String newDomains) {
+            mDomains = newDomains;
+            return this;
+        }
+
+        /**
+         * Create a {@link StaticIpConfiguration} from the parameters in this {@link Builder}.
+         * @return The newly created StaticIpConfiguration.
+         */
+        public @NonNull StaticIpConfiguration build() {
+            final StaticIpConfiguration config = new StaticIpConfiguration();
+            config.ipAddress = mIpAddress;
+            config.gateway = mGateway;
+            for (InetAddress server : mDnsServers) {
+                config.dnsServers.add(server);
+            }
+            config.domains = mDomains;
+            return config;
+        }
     }
 
     /**
@@ -129,16 +193,17 @@
 
     /**
      * Returns the network routes specified by this object. Will typically include a
-     * directly-connected route for the IP address's local subnet and a default route. If the
-     * default gateway is not covered by the directly-connected route, it will also contain a host
-     * route to the gateway as well. This configuration is arguably invalid, but it used to work
-     * in K and earlier, and other OSes appear to accept it.
+     * directly-connected route for the IP address's local subnet and a default route.
+     * @param iface Interface to include in the routes.
      */
     public @NonNull List<RouteInfo> getRoutes(@Nullable String iface) {
         List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
         if (ipAddress != null) {
             RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface);
             routes.add(connectedRoute);
+            // If the default gateway is not covered by the directly-connected route, also add a
+            // host route to the gateway as well. This configuration is arguably invalid, but it
+            // used to work in K and earlier, and other OSes appear to accept it.
             if (gateway != null && !connectedRoute.matches(gateway)) {
                 routes.add(RouteInfo.makeHostRoute(gateway, iface));
             }
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 9e0d95b..c3166e9 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Intent;
 import android.os.Environment;
@@ -380,9 +381,10 @@
      * returned as {@code tel:xxx-xxx-xxxx} and {@code http://example.com/path/to/item/} is
      * returned as {@code http://example.com/...}.
      * @return the common forms PII redacted string of this URI
+     * @hide
      */
-    @NonNull
-    public String toSafeString() {
+    @SystemApi
+    public @NonNull String toSafeString() {
         String scheme = getScheme();
         String ssp = getSchemeSpecificPart();
         if (scheme != null) {
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index ea245a4..ed7cddc 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -123,6 +123,11 @@
  * app must promote itself to the foreground after it's launched or the system
  * will shut down the app.
  *
+ * <h3>Developer's guide</h3>
+ *
+ * <p>To learn more about developing VPN apps, read the
+ * <a href="{@docRoot}guide/topics/connectivity/vpn">VPN developer's guide</a>.
+ *
  * @see Builder
  */
 public class VpnService extends Service {
diff --git a/services/net/java/android/net/StaticIpConfigurationParcelable.aidl b/core/java/android/net/apf/ApfCapabilities.aidl
similarity index 75%
copy from services/net/java/android/net/StaticIpConfigurationParcelable.aidl
copy to core/java/android/net/apf/ApfCapabilities.aidl
index 6fffb42..7c4d4c2 100644
--- a/services/net/java/android/net/StaticIpConfigurationParcelable.aidl
+++ b/core/java/android/net/apf/ApfCapabilities.aidl
@@ -15,13 +15,6 @@
 ** limitations under the License.
 */
 
-package android.net;
+package android.net.apf;
 
-import android.net.LinkAddress;
-
-parcelable StaticIpConfigurationParcelable {
-    LinkAddress ipAddress;
-    String gateway;
-    String[] dnsServers;
-    String domains;
-}
+@JavaOnlyStableParcelable parcelable ApfCapabilities;
\ No newline at end of file
diff --git a/core/java/android/net/apf/ApfCapabilities.java b/core/java/android/net/apf/ApfCapabilities.java
index 17a03c7c..4dd2ace 100644
--- a/core/java/android/net/apf/ApfCapabilities.java
+++ b/core/java/android/net/apf/ApfCapabilities.java
@@ -19,14 +19,17 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
-import android.content.Context;
+import android.content.res.Resources;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import com.android.internal.R;
 
 /**
- * APF program support capabilities.
+ * APF program support capabilities. APF stands for Android Packet Filtering and it is a flexible
+ * way to drop unwanted network packets to save power.
+ *
+ * See documentation at hardware/google/apf/apf.h
  *
  * This class is immutable.
  * @hide
@@ -104,10 +107,11 @@
     }
 
     /**
-     * Returns true if the APF interpreter advertises support for the data buffer access opcodes
-     * LDDW and STDW.
+     * Determines whether the APF interpreter advertises support for the data buffer access opcodes
+     * LDDW (LoaD Data Word) and STDW (STore Data Word). Full LDDW (LoaD Data Word) and
+     * STDW (STore Data Word) support is present from APFv4 on.
      *
-     * Full LDDW and STDW support is present from APFv4 on.
+     * @return {@code true} if the IWifiStaIface#readApfPacketFilterData is supported.
      */
     public boolean hasDataAccess() {
         return apfVersionSupported >= 4;
@@ -116,14 +120,14 @@
     /**
      * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames.
      */
-    public static boolean getApfDrop8023Frames(@NonNull Context context) {
-        return context.getResources().getBoolean(R.bool.config_apfDrop802_3Frames);
+    public static boolean getApfDrop8023Frames() {
+        return Resources.getSystem().getBoolean(R.bool.config_apfDrop802_3Frames);
     }
 
     /**
      * @return An array of blacklisted EtherType, packets with EtherTypes within it will be dropped.
      */
-    public static @NonNull int[] getApfEthTypeBlackList(@NonNull Context context) {
-        return context.getResources().getIntArray(R.array.config_apfEthTypeBlackList);
+    public static @NonNull int[] getApfEtherTypeBlackList() {
+        return Resources.getSystem().getIntArray(R.array.config_apfEthTypeBlackList);
     }
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 8970c62..1be6c4b 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -373,7 +373,8 @@
      * A callback to be invoked when the system successfully delivers your {@link NdefMessage}
      * to another device.
      * @see #setOnNdefPushCompleteCallback
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
     public interface OnNdefPushCompleteCallback {
@@ -398,7 +399,8 @@
      * content currently visible to the user. Alternatively, you can call {@link
      * #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the
      * same data.
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
     public interface CreateNdefMessageCallback {
@@ -427,7 +429,8 @@
 
 
      /**
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
     public interface CreateBeamUrisCallback {
@@ -981,7 +984,8 @@
      * @param uris an array of Uri(s) to push over Android Beam
      * @param activity activity for which the Uri(s) will be pushed
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
     public void setBeamPushUris(Uri[] uris, Activity activity) {
@@ -1068,7 +1072,8 @@
      * @param callback callback, or null to disable
      * @param activity activity for which the Uri(s) will be pushed
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
     public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
@@ -1157,7 +1162,8 @@
      *        to only register one at a time, and to do so in that activity's
      *        {@link Activity#onCreate}
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
     public void setNdefPushMessage(NdefMessage message, Activity activity,
@@ -1275,7 +1281,8 @@
      *        to only register one at a time, and to do so in that activity's
      *        {@link Activity#onCreate}
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
     public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
@@ -1361,7 +1368,8 @@
      *        to only register one at a time, and to do so in that activity's
      *        {@link Activity#onCreate}
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
     public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
@@ -1577,7 +1585,8 @@
      * @param activity the current foreground Activity that has registered data to share
      * @return whether the Beam animation was successfully invoked
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
     public boolean invokeBeam(Activity activity) {
@@ -1822,7 +1831,8 @@
      * @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS
      * @return true if NDEF Push feature is enabled
      * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
-     * @deprecated this feature is deprecated.
+     * @deprecated this feature is deprecated. File sharing can work using other technology like
+     * Bluetooth.
      */
     @java.lang.Deprecated
 
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index f23dc2d..c13f64e 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -34,6 +34,7 @@
 
 import java.util.HashMap;
 import java.util.List;
+import java.util.regex.Pattern;
 
 /**
  * This class can be used to query the state of
@@ -48,6 +49,7 @@
  * on the device.
  */
 public final class CardEmulation {
+    private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?");
     static final String TAG = "CardEmulation";
 
     /**
@@ -732,7 +734,7 @@
         }
 
         // Verify hex characters
-        if (!aid.matches("[0-9A-Fa-f]{10,32}\\*?\\#?")) {
+        if (!AID_PATTERN.matcher(aid).matches()) {
             Log.e(TAG, "AID " + aid + " is not a valid AID.");
             return false;
         }
diff --git a/core/java/android/os/BatterySaverPolicyConfig.java b/core/java/android/os/BatterySaverPolicyConfig.java
index bda4e27..3801cbd 100644
--- a/core/java/android/os/BatterySaverPolicyConfig.java
+++ b/core/java/android/os/BatterySaverPolicyConfig.java
@@ -58,7 +58,8 @@
         mAdvertiseIsEnabled = in.mAdvertiseIsEnabled;
         mDeferFullBackup = in.mDeferFullBackup;
         mDeferKeyValueBackup = in.mDeferKeyValueBackup;
-        mDeviceSpecificSettings = Collections.unmodifiableMap(in.mDeviceSpecificSettings);
+        mDeviceSpecificSettings = Collections.unmodifiableMap(
+                new ArrayMap<>(in.mDeviceSpecificSettings));
         mDisableAnimation = in.mDisableAnimation;
         mDisableAod = in.mDisableAod;
         mDisableLaunchBoost = in.mDisableLaunchBoost;
@@ -240,7 +241,10 @@
         return mDisableOptionalSensors;
     }
 
-    /** Whether or not to disable sound trigger while in Battery Saver. */
+    /**
+     * Whether or not to disable {@link android.hardware.soundtrigger.SoundTrigger}
+     * while in Battery Saver.
+     */
     public boolean getDisableSoundTrigger() {
         return mDisableSoundTrigger;
     }
@@ -260,7 +264,10 @@
         return mEnableDataSaver;
     }
 
-    /** Whether or not to enable the network firewall while in Battery Saver. */
+    /**
+     * Whether or not to enable network firewall rules to restrict background network use
+     * while in Battery Saver.
+     */
     public boolean getEnableFirewall() {
         return mEnableFirewall;
     }
@@ -280,7 +287,12 @@
         return mForceAllAppsStandby;
     }
 
-    /** Whether or not to force background check while in Battery Saver. */
+    /**
+     * Whether or not to force background check (disallow background services and manifest
+     * broadcast receivers) on all apps (not just apps targeting Android
+     * {@link Build.VERSION_CODES#O} and above)
+     * while in Battery Saver.
+     */
     public boolean getForceBackgroundCheck() {
         return mForceBackgroundCheck;
     }
@@ -400,7 +412,10 @@
             return this;
         }
 
-        /** Set whether or not to disable sound trigger while in Battery Saver. */
+        /**
+         * Set whether or not to disable  {@link android.hardware.soundtrigger.SoundTrigger}
+         * while in Battery Saver.
+         */
         @NonNull
         public Builder setDisableSoundTrigger(boolean disableSoundTrigger) {
             mDisableSoundTrigger = disableSoundTrigger;
@@ -428,7 +443,10 @@
             return this;
         }
 
-        /** Set whether or not to enable the network firewall while in Battery Saver. */
+        /**
+         * Set whether or not to enable network firewall rules to restrict background network use
+         * while in Battery Saver.
+         */
         @NonNull
         public Builder setEnableFirewall(boolean enableFirewall) {
             mEnableFirewall = enableFirewall;
@@ -456,7 +474,12 @@
             return this;
         }
 
-        /** Set whether or not to force background check while in Battery Saver. */
+        /**
+         * Set whether or not to force background check (disallow background services and manifest
+         * broadcast receivers) on all apps (not just apps targeting Android
+         * {@link Build.VERSION_CODES#O} and above)
+         * while in Battery Saver.
+         */
         @NonNull
         public Builder setForceBackgroundCheck(boolean forceBackgroundCheck) {
             mForceBackgroundCheck = forceBackgroundCheck;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b64fe00..00d522b 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
 import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
 
 import android.annotation.UnsupportedAppUsage;
@@ -859,7 +860,8 @@
          */
         public static final int[] CRITICAL_PROC_STATES = {
                 PROCESS_STATE_TOP,
-                PROCESS_STATE_FOREGROUND_SERVICE_LOCATION, PROCESS_STATE_FOREGROUND_SERVICE,
+                PROCESS_STATE_FOREGROUND_SERVICE_LOCATION,
+                PROCESS_STATE_BOUND_TOP, PROCESS_STATE_FOREGROUND_SERVICE,
                 PROCESS_STATE_FOREGROUND
         };
 
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index eb91860..66ddf21 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -444,24 +444,20 @@
      *
      * @param workSource The original UID responsible for the binder call.
      * @return token to restore original work source.
-     * @hide
      **/
     @CriticalNative
-    @SystemApi
     public static final native long setCallingWorkSourceUid(int workSource);
 
     /**
      * Returns the work source set by the caller.
      *
      * Unlike {@link Binder#getCallingUid()}, this result of this method cannot be trusted. The
-     * caller can set the value to whatever he wants. Only use this value if you trust the calling
+     * caller can set the value to whatever they want. Only use this value if you trust the calling
      * uid.
      *
      * @return The original UID responsible for the binder transaction.
-     * @hide
      */
     @CriticalNative
-    @SystemApi
     public static final native int getCallingWorkSourceUid();
 
     /**
@@ -484,10 +480,8 @@
      * </pre>
      *
      * @return token to restore original work source.
-     * @hide
      **/
     @CriticalNative
-    @SystemApi
     public static final native long clearCallingWorkSource();
 
     /**
@@ -503,11 +497,8 @@
      *   Binder.restoreCallingWorkSource(token);
      * }
      * </pre>
-     *
-     * @hide
      **/
     @CriticalNative
-    @SystemApi
     public static final native void restoreCallingWorkSource(long token);
 
     /**
diff --git a/core/java/android/os/ConditionVariable.java b/core/java/android/os/ConditionVariable.java
index 1e820f9..a13eaa6 100644
--- a/core/java/android/os/ConditionVariable.java
+++ b/core/java/android/os/ConditionVariable.java
@@ -104,32 +104,32 @@
 
     /**
      * Block the current thread until the condition is opened or until
-     * timeout milliseconds have passed.
+     * timeoutMs milliseconds have passed.
      *
      * <p>
      * If the condition is already opened, return immediately.
      *
-     * @param timeout the maximum time to wait in milliseconds.
+     * @param timeoutMs the maximum time to wait in milliseconds.
      *
      * @return true if the condition was opened, false if the call returns
      * because of the timeout.
      */
-    public boolean block(long timeout)
+    public boolean block(long timeoutMs)
     {
         // Object.wait(0) means wait forever, to mimic this, we just
         // call the other block() method in that case.  It simplifies
         // this code for the common case.
-        if (timeout != 0) {
+        if (timeoutMs != 0) {
             synchronized (this) {
-                long now = System.currentTimeMillis();
-                long end = now + timeout;
+                long now = SystemClock.elapsedRealtime();
+                long end = now + timeoutMs;
                 while (!mCondition && now < end) {
                     try {
                         this.wait(end-now);
                     }
                     catch (InterruptedException e) {
                     }
-                    now = System.currentTimeMillis();
+                    now = SystemClock.elapsedRealtime();
                 }
                 return mCondition;
             }
diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java
index b92e713..b7cccc6 100644
--- a/core/java/android/os/DropBoxManager.java
+++ b/core/java/android/os/DropBoxManager.java
@@ -69,7 +69,8 @@
     /**
      * Broadcast Action: This is broadcast when a new entry is added in the dropbox.
      * You must hold the {@link android.Manifest.permission#READ_LOGS} permission
-     * in order to receive this broadcast.
+     * in order to receive this broadcast. This broadcast can be rate limited for low priority
+     * entries
      *
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index cceb6ed..f7e927e 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -20,6 +20,8 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
+import android.app.AppGlobals;
+import android.app.AppOpsManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.os.storage.StorageManager;
@@ -1060,7 +1062,7 @@
      * @throws IllegalArgumentException if the path is not a valid storage
      *             device.
      */
-    public static boolean isExternalStorageRemovable(File path) {
+    public static boolean isExternalStorageRemovable(@NonNull File path) {
         final StorageVolume volume = StorageManager.getStorageVolume(path, UserHandle.myUserId());
         if (volume != null) {
             return volume.isRemovable();
@@ -1103,7 +1105,7 @@
      * @throws IllegalArgumentException if the path is not a valid storage
      *             device.
      */
-    public static boolean isExternalStorageEmulated(File path) {
+    public static boolean isExternalStorageEmulated(@NonNull File path) {
         final StorageVolume volume = StorageManager.getStorageVolume(path, UserHandle.myUserId());
         if (volume != null) {
             return volume.isEmulated();
@@ -1112,6 +1114,44 @@
         }
     }
 
+    /**
+     * Returns whether the shared/external storage media at the given path is a
+     * sandboxed view that only contains files owned by the app.
+     * <p>
+     * This value may be different from the value requested by
+     * {@code allowExternalStorageSandbox} in the app's manifest, since an app
+     * may inherit its sandboxed state based on when it was first installed.
+     * <p>
+     * Sandboxed apps can continue to discover and read media belonging to other
+     * apps via {@link android.provider.MediaStore}.
+     */
+    public static boolean isExternalStorageSandboxed() {
+        final File externalDir = sCurrentUser.getExternalDirs()[0];
+        return isExternalStorageSandboxed(externalDir);
+    }
+
+    /**
+     * Returns whether the shared/external storage media at the given path is a
+     * sandboxed view that only contains files owned by the app.
+     * <p>
+     * This value may be different from the value requested by
+     * {@code allowExternalStorageSandbox} in the app's manifest, since an app
+     * may inherit its sandboxed state based on when it was first installed.
+     * <p>
+     * Sandboxed apps can continue to discover and read media belonging to other
+     * apps via {@link android.provider.MediaStore}.
+     *
+     * @throws IllegalArgumentException if the path is not a valid storage
+     *             device.
+     */
+    public static boolean isExternalStorageSandboxed(@NonNull File path) {
+        final Context context = AppGlobals.getInitialApplication();
+        final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+        return appOps.noteOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE,
+                context.getApplicationInfo().uid,
+                context.getPackageName()) != AppOpsManager.MODE_ALLOWED;
+    }
+
     static File getDirectory(String variableName, String defaultPath) {
         String path = System.getenv(variableName);
         return path == null ? new File(defaultPath) : new File(path);
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 41691d7..53503f4 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -104,6 +104,13 @@
     }
 
     /**
+     * Check whether application is profileable
+     */
+    private static boolean isProfileable(Context context) {
+        return context.getApplicationInfo().isProfileableByShell();
+    }
+
+    /**
      * Store the layer paths available to the loader.
      */
     public void setLayerPaths(ClassLoader classLoader,
@@ -153,11 +160,11 @@
         String layerPaths = "";
 
         // Only enable additional debug functionality if the following conditions are met:
-        // 1. App is debuggable or device is rooted
+        // 1. App is debuggable, profileable, or device is rooted
         // 2. ENABLE_GPU_DEBUG_LAYERS is true
         // 3. Package name is equal to GPU_DEBUG_APP
 
-        if (isDebuggable(context) || (getCanLoadSystemLibraries() == 1)) {
+        if (isDebuggable(context) || isProfileable(context) || (getCanLoadSystemLibraries() == 1)) {
 
             final int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
 
@@ -330,6 +337,25 @@
     }
 
     /**
+     * Check for ANGLE debug package, but only for apps that can load them (dumpable)
+     */
+    private String getAngleDebugPackage(Context context, Bundle coreSettings) {
+        final boolean appIsDebuggable = isDebuggable(context);
+        final boolean appIsProfileable = isProfileable(context);
+        final boolean deviceIsDebuggable = getCanLoadSystemLibraries() == 1;
+        if (appIsDebuggable || appIsProfileable || deviceIsDebuggable) {
+
+            String debugPackage =
+                    coreSettings.getString(Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE);
+
+            if ((debugPackage != null) && (!debugPackage.isEmpty())) {
+                return debugPackage;
+            }
+        }
+        return "";
+    }
+
+    /**
      * Attempt to setup ANGLE with a temporary rules file.
      * True: Temporary rules file was loaded.
      * False: Temporary rules file was *not* loaded.
@@ -495,11 +521,23 @@
         }
 
         final ApplicationInfo angleInfo;
-        try {
-            angleInfo = pm.getApplicationInfo(anglePkgName, PackageManager.MATCH_SYSTEM_ONLY);
-        } catch (PackageManager.NameNotFoundException e) {
-            Log.w(TAG, "ANGLE package '" + anglePkgName + "' not installed");
-            return false;
+        String angleDebugPackage = getAngleDebugPackage(context, bundle);
+        if (!angleDebugPackage.isEmpty()) {
+            Log.i(TAG, "ANGLE debug package enabled: " + angleDebugPackage);
+            try {
+                // Note the debug package does not have to be pre-installed
+                angleInfo = pm.getApplicationInfo(angleDebugPackage, 0);
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "ANGLE debug package '" + angleDebugPackage + "' not installed");
+                return false;
+            }
+        } else {
+            try {
+                angleInfo = pm.getApplicationInfo(anglePkgName, PackageManager.MATCH_SYSTEM_ONLY);
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.w(TAG, "ANGLE package '" + anglePkgName + "' not installed");
+                return false;
+            }
         }
 
         final String abi = chooseAbi(angleInfo);
diff --git a/core/java/android/os/IIncidentManager.aidl b/core/java/android/os/IIncidentManager.aidl
index b67b99f..5e024b9 100644
--- a/core/java/android/os/IIncidentManager.aidl
+++ b/core/java/android/os/IIncidentManager.aidl
@@ -17,32 +17,57 @@
 package android.os;
 
 import android.os.IIncidentReportStatusListener;
+import android.os.IncidentManager;
 import android.os.IncidentReportArgs;
 
 /**
   * Binder interface to report system health incidents.
   * {@hide}
   */
-oneway interface IIncidentManager {
+interface IIncidentManager {
 
     /**
      * Takes a report with the given args, reporting status to the optional listener.
      *
      * When the report is completed, the system report listener will be notified.
      */
-    void reportIncident(in IncidentReportArgs args);
+    oneway void reportIncident(in IncidentReportArgs args);
 
     /**
      * Takes a report with the given args, reporting status to the optional listener.
      *
      * When the report is completed, the system report listener will be notified.
      */
-    void reportIncidentToStream(in IncidentReportArgs args,
+    oneway void reportIncidentToStream(in IncidentReportArgs args,
             @nullable IIncidentReportStatusListener listener,
             FileDescriptor stream);
 
     /**
      * Tell the incident daemon that the android system server is up and running.
      */
-    void systemRunning();
+    oneway void systemRunning();
+
+    /**
+     * List the incident reports for the given ComponentName.  This is called
+     * via IncidentCompanion, which validates that the package name matches
+     * the caller.
+     */
+    List<String> getIncidentReportList(String pkg, String cls);
+
+    /**
+     * Get the IncidentReport object.
+     */
+    IncidentManager.IncidentReport getIncidentReport(String pkg, String cls, String id);
+
+    /**
+     * Reduce the refcount on this receiver. This is called
+     * via IncidentCompanion, which validates that the package name matches
+     * the caller.
+     */
+    void deleteIncidentReports(String pkg, String cls, String id);
+
+    /**
+     * Delete all incident reports for this package.
+     */
+    void deleteAllIncidentReports(String pkg);
 }
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 6536fc9..03e8c15 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -330,12 +330,6 @@
      */
     void removeIdleTimer(String iface);
 
-    /**
-     * Configure name servers, search paths, and resolver parameters for the given network.
-     */
-    void setDnsConfigurationForNetwork(int netId, in String[] servers, in String[] domains,
-            in int[] params, String tlsHostname, in String[] tlsServers);
-
     void setFirewallEnabled(boolean enabled);
     boolean isFirewallEnabled();
     void setFirewallInterfaceRule(String iface, boolean allow);
@@ -381,11 +375,6 @@
     void createVirtualNetwork(int netId, boolean secure);
 
     /**
-     * Remove a network.
-     */
-    void removeNetwork(int netId);
-
-    /**
      * Add an interface to a network.
      */
     void addInterfaceToNetwork(String iface, int netId);
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index 6d4c5a0..311c86d 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -217,4 +217,9 @@
      */
      oneway void sendBinaryPushStateChangedAtom(in String trainName, in long trainVersionCode,
          in int options, in int state, in long[] experimentId);
+
+    /**
+     * Returns the most recently registered experiment IDs.
+     */
+    long[] getRegisteredExperimentIds();
 }
diff --git a/core/java/android/os/IncidentManager.java b/core/java/android/os/IncidentManager.java
index 0bdf6f1..08afe31 100644
--- a/core/java/android/os/IncidentManager.java
+++ b/core/java/android/os/IncidentManager.java
@@ -75,6 +75,13 @@
     public static final String URI_PARAM_ID = "id";
 
     /**
+     * Query parameter for the uris for the incident report id.
+     *
+     * @hide
+     */
+    public static final String URI_PARAM_REPORT_ID = "r";
+
+    /**
      * Query parameter for the uris for the pending report id.
      *
      * @hide
@@ -97,6 +104,13 @@
     public static final String URI_PARAM_FLAGS = "flags";
 
     /**
+     * Query parameter for the uris for the pending report id.
+     *
+     * @hide
+     */
+    public static final String URI_PARAM_RECEIVER_CLASS = "receiver";
+
+    /**
      * Do the confirmation with a dialog instead of the default, which is a notification.
      * It is possible for the dialog to be downgraded to a notification in some cases.
      */
@@ -243,12 +257,12 @@
     @SystemApi
     @TestApi
     public static class IncidentReport implements Parcelable, Closeable {
-        private final long mTimestampMs;
+        private final long mTimestampNs;
         private final int mPrivacyPolicy;
         private ParcelFileDescriptor mFileDescriptor;
 
         public IncidentReport(Parcel in) {
-            mTimestampMs = in.readLong();
+            mTimestampNs = in.readLong();
             mPrivacyPolicy = in.readInt();
             if (in.readInt() != 0) {
                 mFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(in);
@@ -272,10 +286,10 @@
 
         /**
          * Get the time at which this incident report was taken, in wall clock time
-         * ({@link System#uptimeMillis System.uptimeMillis()} time base).
+         * ({@link System#currenttimeMillis System.currenttimeMillis()} time base).
          */
         public long getTimestamp() {
-            return mTimestampMs;
+            return mTimestampNs / 1000000;
         }
 
         /**
@@ -310,7 +324,7 @@
          * @inheritDoc
          */
         public void writeToParcel(Parcel out, int flags) {
-            out.writeLong(mTimestampMs);
+            out.writeLong(mTimestampNs);
             out.writeInt(mPrivacyPolicy);
             if (mFileDescriptor != null) {
                 out.writeInt(1);
@@ -397,8 +411,8 @@
     public void requestAuthorization(int callingUid, String callingPackage, int flags,
             AuthListener listener) {
         try {
-            getCompanionServiceLocked().authorizeReport(callingUid, callingPackage, flags,
-                    listener.mBinder);
+            getCompanionServiceLocked().authorizeReport(callingUid, callingPackage, null, null,
+                    flags, listener.mBinder);
         } catch (RemoteException ex) {
             // System process going down
             throw new RuntimeException(ex);
@@ -477,7 +491,19 @@
             android.Manifest.permission.PACKAGE_USAGE_STATS
     })
     public @NonNull List<Uri> getIncidentReportList(String receiverClass) {
-        throw new RuntimeException("implement me");
+        List<String> strings;
+        try {
+            strings = getCompanionServiceLocked().getIncidentReportList(
+                    mContext.getPackageName(), receiverClass);
+        } catch (RemoteException ex) {
+            throw new RuntimeException("System server or incidentd going down", ex);
+        }
+        final int size = strings.size();
+        ArrayList<Uri> result = new ArrayList(size);
+        for (int i = 0; i < size; i++) {
+            result.add(Uri.parse(strings.get(i)));
+        }
+        return result;
     }
 
     /**
@@ -493,20 +519,74 @@
             android.Manifest.permission.PACKAGE_USAGE_STATS
     })
     public @Nullable IncidentReport getIncidentReport(Uri uri) {
-        throw new RuntimeException("implement me");
+        final String pkg = uri.getQueryParameter(URI_PARAM_CALLING_PACKAGE);
+        if (pkg == null) {
+            throw new RuntimeException("Invalid URI: No "
+                    + URI_PARAM_CALLING_PACKAGE + " parameter. " + uri);
+        }
+
+        final String cls = uri.getQueryParameter(URI_PARAM_RECEIVER_CLASS);
+        if (cls == null) {
+            throw new RuntimeException("Invalid URI: No "
+                    + URI_PARAM_RECEIVER_CLASS + " parameter. " + uri);
+        }
+
+        final String id = uri.getQueryParameter(URI_PARAM_REPORT_ID);
+        if (cls == null) {
+            // If there's no report id, it's a bug report, so we can't return the incident
+            // report.
+            return null;
+        }
+    
+        try {
+            return getCompanionServiceLocked().getIncidentReport(pkg, cls, id);
+        } catch (RemoteException ex) {
+            throw new RuntimeException("System server or incidentd going down", ex);
+        }
     }
 
     /**
      * Delete the incident report with the given URI id.
      *
-     * @param uri Identifier of the incident report.
+     * @param uri Identifier of the incident report. Pass null to delete all
+     *              incident reports owned by this application.
      */
     @RequiresPermission(allOf = {
             android.Manifest.permission.DUMP,
             android.Manifest.permission.PACKAGE_USAGE_STATS
     })
     public void deleteIncidentReports(Uri uri) {
-        throw new RuntimeException("implement me");
+        if (uri == null) {
+            try {
+                getCompanionServiceLocked().deleteAllIncidentReports(mContext.getPackageName());
+            } catch (RemoteException ex) {
+                throw new RuntimeException("System server or incidentd going down", ex);
+            }
+        } else {
+            final String pkg = uri.getQueryParameter(URI_PARAM_CALLING_PACKAGE);
+            if (pkg == null) {
+                throw new RuntimeException("Invalid URI: No "
+                        + URI_PARAM_CALLING_PACKAGE + " parameter. " + uri);
+            }
+
+            final String cls = uri.getQueryParameter(URI_PARAM_RECEIVER_CLASS);
+            if (cls == null) {
+                throw new RuntimeException("Invalid URI: No "
+                        + URI_PARAM_RECEIVER_CLASS + " parameter. " + uri);
+            }
+
+            final String id = uri.getQueryParameter(URI_PARAM_REPORT_ID);
+            if (cls == null) {
+                throw new RuntimeException("Invalid URI: No "
+                        + URI_PARAM_REPORT_ID + " parameter. " + uri);
+            }
+        
+            try {
+                getCompanionServiceLocked().deleteIncidentReports(pkg, cls, id);
+            } catch (RemoteException ex) {
+                throw new RuntimeException("System server or incidentd going down", ex);
+            }
+        }
     }
 
     private void reportIncidentInternal(IncidentReportArgs args) {
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 64e2f89..7d61bf6 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -773,8 +773,10 @@
      */
     public static final int LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF = 4;
 
-    static final int MIN_LOCATION_MODE = LOCATION_MODE_NO_CHANGE;
-    static final int MAX_LOCATION_MODE = LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF;
+    /** @hide */
+    public static final int MIN_LOCATION_MODE = LOCATION_MODE_NO_CHANGE;
+    /** @hide */
+    public static final int MAX_LOCATION_MODE = LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF;
 
     /**
      * @hide
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 6a01e56..7cc7ccd 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -30,6 +30,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.os.storage.IStorageManager;
 import android.provider.Settings;
 import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
@@ -38,6 +39,8 @@
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.internal.content.PackageHelper;
+
 import libcore.io.Streams;
 
 import java.io.ByteArrayInputStream;
@@ -854,6 +857,21 @@
     /** {@hide} */
     public static void rebootPromptAndWipeUserData(Context context, String reason)
             throws IOException {
+        boolean checkpointing = false;
+
+        // If we are running in checkpointing mode, we should not prompt a wipe.
+        // Checkpointing may save us. If it doesn't, we will wind up here again.
+        try {
+            IStorageManager storageManager = PackageHelper.getStorageManager();
+            if (storageManager.needsCheckpoint()) {
+                Log.i(TAG, "Rescue Party requested wipe. Aborting update instead.");
+                storageManager.abortChanges("rescueparty", false);
+            }
+            return;
+        } catch (RemoteException e) {
+            Log.i(TAG, "Failed to handle with checkpointing. Continuing with wipe.");
+        }
+
         String reasonArg = null;
         if (!TextUtils.isEmpty(reason)) {
             reasonArg = "--reason=" + sanitizeArg(reason);
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java
index 8ffafe4..f007dff 100644
--- a/core/java/android/os/SELinux.java
+++ b/core/java/android/os/SELinux.java
@@ -39,6 +39,13 @@
     private static final int SELINUX_ANDROID_RESTORECON_DATADATA = 16;
 
     /**
+     * Get context associated with path by file_contexts.
+     * @param path path to the regular file to get the security context for.
+     * @return a String representing the security context or null on failure.
+     */
+    public static final native String fileSelabelLookup(String path);
+
+    /**
      * Determine whether SELinux is disabled or enabled.
      * @return a boolean indicating whether SELinux is enabled.
      */
diff --git a/core/java/android/os/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java
index 33a6ee8..8f68723 100644
--- a/core/java/android/os/image/DynamicSystemClient.java
+++ b/core/java/android/os/image/DynamicSystemClient.java
@@ -19,19 +19,24 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
+import android.os.ParcelableException;
 import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.FeatureFlagUtils;
 import android.util.Slog;
 
 import java.lang.annotation.Retention;
@@ -43,20 +48,21 @@
  * <p>This class contains methods and constants used to start a {@code DynamicSystem} installation,
  * and a listener for status updates.</p>
  *
- * <p>{@code DynamicSystem} allows user to run certified system images in a non destructive manner
- * without needing to prior OEM unlock. While running in {@code DynamicSystem}, persitent storage
- * for factory reset protection (FRP) remains unchanged. The new system is installed in a
- * temporarily allocated partition. After the installation is completed, the device will be running
- * in the new system on next reboot. Then, when the user reboots the device again, it will leave
- * {@code DynamicSystem} and go back into the original system. Since the userdata for
- * {@code DynamicSystem} is also newly created during the installation, running in
- * {@code DynamicSystem} doesn't change user's app data.</p>
+ * <p>{@code DynamicSystem} allows users to run certified system images in a non destructive manner
+ * without needing to prior OEM unlock. It creates a temporary system partition to install the new
+ * system image, and a temporary data partition for the newly installed system to run with.</p>
+ *
+ * After the installation is completed, the device will be running in the new system on next the
+ * reboot. Then, when the user reboots the device again, it will leave {@code DynamicSystem} and go
+ * back to the original system. While running in {@code DynamicSystem}, persitent storage for
+ * factory reset protection (FRP) remains unchanged. Since the user is running the new system with
+ * a temporarily created data partition, their original user data are kept unchanged.</p>
  *
  * <p>With {@link #setOnStatusChangedListener}, API users can register an
- * {@link #OnStatusChangedListener} and get status updates and cause when the installation is
+ * {@link #OnStatusChangedListener} to get status updates and their causes when the installation is
  * started, stopped, or cancelled. It also sends progress updates during the installation. With
- * {@link #start}, API users can start an installation with the {@link Uri} to a gzipped system
- * image. The {@link Uri} can be a web URL or a content Uri to a local path.</p>
+ * {@link #start}, API users can start an installation with the {@link Uri} to a unsparsed and
+ * gzipped system image. The {@link Uri} can be a web URL or a content Uri to a local path.</p>
  *
  * @hide
  */
@@ -100,9 +106,10 @@
          * @param status status code, also defined in {@code DynamicSystemClient}.
          * @param cause cause code, also defined in {@code DynamicSystemClient}.
          * @param progress number of bytes installed.
+         * @param detail additional detail about the error if available, otherwise null.
          */
         void onStatusChanged(@InstallationStatus int status, @StatusChangedCause int cause,
-                @BytesLong long progress);
+                @BytesLong long progress, @Nullable Throwable detail);
     }
 
     /*
@@ -177,6 +184,12 @@
      */
     public static final String KEY_INSTALLED_SIZE = "KEY_INSTALLED_SIZE";
 
+    /**
+     * Message key, used when the service is sending exception detail to the client.
+     * @hide
+     */
+    public static final String KEY_EXCEPTION_DETAIL = "KEY_EXCEPTION_DETAIL";
+
     /*
      * Intent Actions
      */
@@ -198,12 +211,6 @@
      * Intent Keys
      */
     /**
-     * Intent key: URL to system image.
-     * @hide
-     */
-    public static final String KEY_SYSTEM_URL = "KEY_SYSTEM_URL";
-
-    /**
      * Intent key: Size of system image, in bytes.
      * @hide
      */
@@ -248,7 +255,7 @@
             } catch (RemoteException e) {
                 Slog.e(TAG, "Unable to get status from installation service");
                 mExecutor.execute(() -> {
-                    mListener.onStatusChanged(STATUS_UNKNOWN, CAUSE_ERROR_IPC, 0);
+                    mListener.onStatusChanged(STATUS_UNKNOWN, CAUSE_ERROR_IPC, 0, e);
                 });
             }
         }
@@ -308,8 +315,13 @@
      * allows it to send status updates to {@link #OnStatusChangedListener}. It is recommanded
      * to bind before calling {@link #start} and get status updates.
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+    @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
     public void bind() {
+        if (!featureFlagEnabled()) {
+            Slog.w(TAG, FeatureFlagUtils.DYNAMIC_SYSTEM + " not enabled; bind() aborted.");
+            return;
+        }
+
         Intent intent = new Intent();
         intent.setClassName("com.android.dynsystem",
                 "com.android.dynsystem.DynamicSystemInstallationService");
@@ -323,7 +335,7 @@
      * Unbind from {@code DynamicSystem} installation service. Unbinding from the installation
      * service stops it from sending following status updates.
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+    @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
     public void unbind() {
         if (!mBound) {
             return;
@@ -356,8 +368,8 @@
      * @param systemUrl A network URL or a file URL to system image.
      * @param systemSize size of system image.
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
-    public void start(@NonNull String systemUrl, @BytesLong long systemSize) {
+    @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
+    public void start(@NonNull Uri systemUrl, @BytesLong long systemSize) {
         start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE);
     }
 
@@ -373,37 +385,52 @@
      * @param systemSize size of system image.
      * @param userdataSize bytes reserved for userdata.
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
-    public void start(@NonNull String systemUrl, @BytesLong long systemSize,
+    @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
+    public void start(@NonNull Uri systemUrl, @BytesLong long systemSize,
             @BytesLong long userdataSize) {
+        if (!featureFlagEnabled()) {
+            Slog.w(TAG, FeatureFlagUtils.DYNAMIC_SYSTEM + " not enabled; start() aborted.");
+            return;
+        }
+
         Intent intent = new Intent();
 
         intent.setClassName("com.android.dynsystem",
                 "com.android.dynsystem.VerificationActivity");
 
+        intent.setData(systemUrl);
         intent.setAction(ACTION_START_INSTALL);
 
-        intent.putExtra(KEY_SYSTEM_URL, systemUrl);
         intent.putExtra(KEY_SYSTEM_SIZE, systemSize);
         intent.putExtra(KEY_USERDATA_SIZE, userdataSize);
 
         mContext.startActivity(intent);
     }
 
+    private boolean featureFlagEnabled() {
+        return SystemProperties.getBoolean(
+                FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.DYNAMIC_SYSTEM, false);
+    }
+
     private void handleMessage(Message msg) {
         switch (msg.what) {
             case MSG_POST_STATUS:
                 int status = msg.arg1;
                 int cause = msg.arg2;
                 // obj is non-null
-                long progress = ((Bundle) msg.obj).getLong(KEY_INSTALLED_SIZE);
+                Bundle bundle = (Bundle) msg.obj;
+                long progress = bundle.getLong(KEY_INSTALLED_SIZE);
+                ParcelableException t = (ParcelableException) bundle.getSerializable(
+                        KEY_EXCEPTION_DETAIL);
+
+                Throwable detail = t == null ? null : t.getCause();
 
                 if (mExecutor != null) {
                     mExecutor.execute(() -> {
-                        mListener.onStatusChanged(status, cause, progress);
+                        mListener.onStatusChanged(status, cause, progress, detail);
                     });
                 } else {
-                    mListener.onStatusChanged(status, cause, progress);
+                    mListener.onStatusChanged(status, cause, progress, detail);
                 }
                 break;
             default:
diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java
index 0458c2a..cec1945 100644
--- a/core/java/android/os/image/DynamicSystemManager.java
+++ b/core/java/android/os/image/DynamicSystemManager.java
@@ -159,6 +159,16 @@
         }
     }
 
+    /** @return {@code true} if the device has a dynamic system enabled */
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+    public boolean isEnabled() {
+        try {
+            return mService.isEnabled();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e.toString());
+        }
+    }
+
     /**
      * Remove DynamicSystem installation if present
      *
@@ -174,14 +184,13 @@
     }
 
     /**
-     * Enable DynamicSystem when it's not enabled, otherwise, disable it.
-     *
+     * Enable or disable DynamicSystem.
      * @return {@code true} if the call succeeds. {@code false} if there is no installed image.
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
-    public boolean toggle() {
+    public boolean setEnable(boolean enable) {
         try {
-            return mService.toggle();
+            return mService.setEnable(enable);
         } catch (RemoteException e) {
             throw new RuntimeException(e.toString());
         }
diff --git a/core/java/android/os/image/IDynamicSystemService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl
index 15f5b68..a34daca 100644
--- a/core/java/android/os/image/IDynamicSystemService.aidl
+++ b/core/java/android/os/image/IDynamicSystemService.aidl
@@ -58,6 +58,11 @@
     boolean isInstalled();
 
     /**
+     * @return true if the device has an DynamicSystem image enabled
+     */
+    boolean isEnabled();
+
+    /**
      * Remove DynamicSystem installation if present
      *
      * @return true if the call succeeds
@@ -65,11 +70,11 @@
     boolean remove();
 
     /**
-     * Enable DynamicSystem when it's not enabled, otherwise, disable it.
+     * Enable or disable DynamicSystem.
      *
      * @return true if the call succeeds
      */
-    boolean toggle();
+    boolean setEnable(boolean enable);
 
     /**
      * Write a chunk of the DynamicSystem system image
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 25f67f8..9db4111 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -193,4 +193,6 @@
     void commitChanges() = 83;
     boolean supportsCheckpoint() = 84;
     void startCheckpoint(int numTries) = 85;
+    boolean needsCheckpoint() = 86;
+    void abortChanges(in String message, boolean retry) = 87;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 3e60d51..c57bf91 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -16,7 +16,18 @@
 
 package android.os.storage;
 
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.OP_READ_MEDIA_AUDIO;
+import static android.app.AppOpsManager.OP_READ_MEDIA_IMAGES;
+import static android.app.AppOpsManager.OP_READ_MEDIA_VIDEO;
+import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.OP_WRITE_MEDIA_AUDIO;
+import static android.app.AppOpsManager.OP_WRITE_MEDIA_IMAGES;
+import static android.app.AppOpsManager.OP_WRITE_MEDIA_VIDEO;
 import static android.content.ContentResolver.DEPRECATE_DATA_PREFIX;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import android.annotation.BytesLong;
 import android.annotation.IntDef;
@@ -33,6 +44,7 @@
 import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
+import android.app.AppOpsManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -120,6 +132,7 @@
 @SystemService(Context.STORAGE_SERVICE)
 public class StorageManager {
     private static final String TAG = "StorageManager";
+    private static final boolean LOCAL_LOGV = Log.isLoggable(TAG, Log.VERBOSE);
 
     /** {@hide} */
     public static final String PROP_PRIMARY_PHYSICAL = "ro.vold.primary_physical";
@@ -139,8 +152,6 @@
     public static final String PROP_ISOLATED_STORAGE = "persist.sys.isolated_storage";
     /** {@hide} */
     public static final String PROP_ISOLATED_STORAGE_SNAPSHOT = "sys.isolated_storage_snapshot";
-    /** {@hide} */
-    public static final String PROP_LEGACY_GREYLIST = "persist.sys.legacy_greylist";
 
     /** {@hide} */
     public static final String PROP_FORCE_AUDIO = "persist.fw.force_audio";
@@ -238,8 +249,6 @@
     public static final int DEBUG_ISOLATED_STORAGE_FORCE_ON = 1 << 6;
     /** {@hide} */
     public static final int DEBUG_ISOLATED_STORAGE_FORCE_OFF = 1 << 7;
-    /** {@hide} */
-    public static final int DEBUG_LEGACY_GREYLIST = 1 << 8;
 
     /** {@hide} */
     public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE;
@@ -290,6 +299,7 @@
     private final ContentResolver mResolver;
 
     private final IStorageManager mStorageManager;
+    private final AppOpsManager mAppOps;
     private final Looper mLooper;
     private final AtomicInteger mNextNonce = new AtomicInteger(0);
 
@@ -500,6 +510,7 @@
         mResolver = context.getContentResolver();
         mLooper = looper;
         mStorageManager = IStorageManager.Stub.asInterface(ServiceManager.getServiceOrThrow("mount"));
+        mAppOps = mContext.getSystemService(AppOpsManager.class);
     }
 
     /**
@@ -1635,6 +1646,105 @@
         }
     }
 
+    /**
+     * Check that given app holds both permission and appop.
+     * @hide
+     */
+    public static boolean checkPermissionAndAppOp(Context context, boolean enforce,
+            int pid, int uid, String packageName, String permission, int op) {
+        if (context.checkPermission(permission, pid, uid) != PERMISSION_GRANTED) {
+            if (enforce) {
+                throw new SecurityException(
+                        "Permission " + permission + " denied for package " + packageName);
+            } else {
+                return false;
+            }
+        }
+
+        AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+        final int mode = appOps.noteOpNoThrow(op, uid, packageName);
+        switch (mode) {
+            case AppOpsManager.MODE_ALLOWED:
+                return true;
+            case AppOpsManager.MODE_DEFAULT:
+            case AppOpsManager.MODE_IGNORED:
+            case AppOpsManager.MODE_ERRORED:
+                if (enforce) {
+                    throw new SecurityException("Op " + AppOpsManager.opToName(op) + " "
+                            + AppOpsManager.modeToName(mode) + " for package " + packageName);
+                } else {
+                    return false;
+                }
+            default:
+                throw new IllegalStateException(
+                        AppOpsManager.opToName(op) + " has unknown mode "
+                                + AppOpsManager.modeToName(mode));
+        }
+    }
+
+    private boolean checkPermissionAndAppOp(boolean enforce,
+            int pid, int uid, String packageName, String permission, int op) {
+        return checkPermissionAndAppOp(mContext, enforce, pid, uid, packageName, permission, op);
+    }
+
+    // Callers must hold both the old and new permissions, so that we can
+    // handle obscure cases like when an app targets Q but was installed on
+    // a device that was originally running on P before being upgraded to Q.
+
+    /** {@hide} */
+    public boolean checkPermissionReadAudio(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
+        mAppOps.noteOpNoThrow(OP_READ_MEDIA_AUDIO, uid, packageName);
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionWriteAudio(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
+        mAppOps.noteOpNoThrow(OP_WRITE_MEDIA_AUDIO, uid, packageName);
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionReadVideo(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
+        mAppOps.noteOpNoThrow(OP_READ_MEDIA_VIDEO, uid, packageName);
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionWriteVideo(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
+        mAppOps.noteOpNoThrow(OP_WRITE_MEDIA_VIDEO, uid, packageName);
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionReadImages(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
+        mAppOps.noteOpNoThrow(OP_READ_MEDIA_IMAGES, uid, packageName);
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionWriteImages(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
+        mAppOps.noteOpNoThrow(OP_WRITE_MEDIA_IMAGES, uid, packageName);
+        return true;
+    }
+
     /** {@hide} */
     @VisibleForTesting
     public @NonNull ParcelFileDescriptor openProxyFileDescriptor(
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index 61511aa..55fae30 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -472,7 +472,7 @@
                 @NonNull UserHandle user) {
             super(context, SERVICE_INTERFACE, componentName, user.getIdentifier(),
                     service -> Log.e(TAG, "RemoteService " + service + " died"),
-                    context.getMainThreadHandler(), false, false, 1);
+                    context.getMainThreadHandler(), 0, false, 1);
         }
 
         /**
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 015146466..847b8e4 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -27,6 +27,8 @@
 import android.media.AudioManager;
 import android.media.Ringtone;
 import android.media.RingtoneManager;
+import android.media.audiopolicy.AudioProductStrategies;
+import android.media.audiopolicy.AudioVolumeGroups;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -41,6 +43,7 @@
 import android.widget.SeekBar.OnSeekBarChangeListener;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.SomeArgs;
 
 /**
  * Turns a {@link SeekBar} into a volume control.
@@ -62,6 +65,26 @@
         void onMuted(boolean muted, boolean zenMuted);
     }
 
+    private static final int MSG_GROUP_VOLUME_CHANGED = 1;
+    private final Handler mVolumeHandler = new VolumeHandler();
+    private final AudioProductStrategies mAudioProductStrategies;
+    private AudioAttributes mAttributes;
+    private int mVolumeGroupId;
+
+    private final AudioManager.VolumeGroupCallback mVolumeGroupCallback =
+            new AudioManager.VolumeGroupCallback() {
+        @Override
+        public void onAudioVolumeGroupChanged(int group, int flags) {
+            if (mHandler == null) {
+                return;
+            }
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = group;
+            args.arg2 = flags;
+            mVolumeHandler.sendMessage(mHandler.obtainMessage(MSG_GROUP_VOLUME_CHANGED, args));
+        }
+    };
+
     @UnsupportedAppUsage
     private final Context mContext;
     private final H mUiHandler = new H();
@@ -111,7 +134,7 @@
 
     @UnsupportedAppUsage
     public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) {
-        this(context, streamType, defaultUri, callback, false /* playSample */);
+        this(context, streamType, defaultUri, callback, true /* playSample */);
     }
 
     public SeekBarVolumizer(
@@ -137,6 +160,15 @@
             mRingerMode = mAudioManager.getRingerModeInternal();
         }
         mZenMode = mNotificationManager.getZenMode();
+
+        mAudioProductStrategies = mAudioManager.getAudioProductStrategies();
+        if (mAudioProductStrategies.size() > 0) {
+            mVolumeGroupId = mAudioProductStrategies.getVolumeGroupIdForLegacyStreamType(
+                    mStreamType);
+            mAttributes = mAudioProductStrategies.getAudioAttributesForLegacyStreamType(
+                    mStreamType);
+        }
+
         mMaxStreamVolume = mAudioManager.getStreamMaxVolume(mStreamType);
         mCallback = callback;
         mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType);
@@ -297,6 +329,9 @@
         postStopSample();
         mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
         mReceiver.setListening(false);
+        if (mAudioProductStrategies.size() > 0) {
+            unregisterVolumeGroupCb();
+        }
         mSeekBar.setOnSeekBarChangeListener(null);
         mHandler.getLooper().quitSafely();
         mHandler = null;
@@ -314,6 +349,9 @@
                 System.getUriFor(System.VOLUME_SETTINGS_INT[mStreamType]),
                 false, mVolumeObserver);
         mReceiver.setListening(true);
+        if (mAudioProductStrategies.size() > 0) {
+            registerVolumeGroupCb();
+        }
     }
 
     public void revertVolume() {
@@ -469,7 +507,9 @@
             if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
                 int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
                 int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
-                updateVolumeSlider(streamType, streamValue);
+                if (mAudioProductStrategies.size() == 0) {
+                    updateVolumeSlider(streamType, streamValue);
+                }
             } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
                 if (mNotificationOrRing) {
                     mRingerMode = mAudioManager.getRingerModeInternal();
@@ -479,8 +519,18 @@
                 }
             } else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
                 int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
-                int streamVolume = mAudioManager.getStreamVolume(streamType);
-                updateVolumeSlider(streamType, streamVolume);
+                if (mAudioProductStrategies.size() == 0) {
+                    int streamVolume = mAudioManager.getStreamVolume(streamType);
+                    updateVolumeSlider(streamType, streamVolume);
+                } else {
+                    int volumeGroup = mAudioProductStrategies.getVolumeGroupIdForLegacyStreamType(
+                            streamType);
+                    if (volumeGroup != AudioVolumeGroups.DEFAULT_VOLUME_GROUP
+                            && volumeGroup == mVolumeGroupId) {
+                        int streamVolume = mAudioManager.getStreamVolume(streamType);
+                        updateVolumeSlider(streamType, streamVolume);
+                    }
+                }
             } else if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED.equals(action)) {
                 mZenMode = mNotificationManager.getZenMode();
                 updateSlider();
@@ -506,4 +556,34 @@
             }
         }
     }
+
+    private void registerVolumeGroupCb() {
+        if (mVolumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
+            mAudioManager.registerVolumeGroupCallback(Runnable::run, mVolumeGroupCallback);
+            mLastProgress = mAudioManager.getVolumeIndexForAttributes(mAttributes);
+        }
+    }
+
+    private void unregisterVolumeGroupCb() {
+        if (mVolumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
+            mAudioManager.unregisterVolumeGroupCallback(mVolumeGroupCallback);
+        }
+    }
+
+    private class VolumeHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            SomeArgs args = (SomeArgs) msg.obj;
+            switch (msg.what) {
+                case MSG_GROUP_VOLUME_CHANGED:
+                    int group = (int) args.arg1;
+                    if (mVolumeGroupId != group
+                            || mVolumeGroupId == AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
+                        return;
+                    }
+                    updateSlider();
+                    break;
+            }
+        }
+    }
 }
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 44adc1c..ef28f07 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -35,7 +35,6 @@
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.DataUsageFeedback;
-import android.telecom.CallIdentification;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -605,69 +604,6 @@
         public static final String BLOCK_REASON = "block_reason";
 
         /**
-         * The package name of the {@link android.telecom.CallScreeningService} which provided
-         * {@link android.telecom.CallIdentification} for this call.
-         * <P>Type: TEXT</P>
-         */
-        public static final String CALL_ID_PACKAGE_NAME = "call_id_package_name";
-
-        /**
-         * The app name of the {@link android.telecom.CallScreeningService} which provided
-         * {@link android.telecom.CallIdentification} for this call.
-         * <P>Type: TEXT</P>
-         */
-        public static final String CALL_ID_APP_NAME = "call_id_app_name";
-
-        /**
-         * The {@link CallIdentification#getName() name} of a call, as provided by the
-         * {@link android.telecom.CallScreeningService}.
-         * <p>
-         * The name is provided by the app identified by {@link #CALL_ID_PACKAGE_NAME} and
-         * {@link #CALL_ID_APP_NAME}.
-         * <P>Type: TEXT</P>
-         */
-        public static final String CALL_ID_NAME = "call_id_name";
-
-        /**
-         * The {@link CallIdentification#getDescription() description} of a call, as provided by the
-         * {@link android.telecom.CallScreeningService}.
-         * <p>
-         * The description is provided by the app identified by {@link #CALL_ID_PACKAGE_NAME} and
-         * {@link #CALL_ID_APP_NAME}.
-         * <P>Type: TEXT</P>
-         */
-        public static final String CALL_ID_DESCRIPTION = "call_id_description";
-
-        /**
-         * The {@link CallIdentification#getDetails() details} of a call, as provided by the
-         * {@link android.telecom.CallScreeningService}.
-         * <p>
-         * The details field is provided by the app identified by {@link #CALL_ID_PACKAGE_NAME} and
-         * {@link #CALL_ID_APP_NAME}.
-         * <P>Type: TEXT</P>
-         */
-        public static final String CALL_ID_DETAILS = "call_id_details";
-
-        /**
-         * The {@link CallIdentification#getNuisanceConfidence() nuisance confidence} of a call, as
-         * provided by the {@link android.telecom.CallScreeningService}.
-         * <p>
-         * Valid values are defined in {@link CallIdentification}, and include:
-         * <ul>
-         *     <li>{@link CallIdentification#CONFIDENCE_NOT_NUISANCE}</li>
-         *     <li>{@link CallIdentification#CONFIDENCE_LIKELY_NOT_NUISANCE}</li>
-         *     <li>{@link CallIdentification#CONFIDENCE_UNKNOWN}</li>
-         *     <li>{@link CallIdentification#CONFIDENCE_LIKELY_NUISANCE}</li>
-         *     <li>{@link CallIdentification#CONFIDENCE_NUISANCE}</li>
-         * </ul>
-         * <p>
-         * The nuisance confidence is provided by the app identified by
-         * {@link #CALL_ID_PACKAGE_NAME} and {@link #CALL_ID_APP_NAME}.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String CALL_ID_NUISANCE_CONFIDENCE = "call_id_nuisance_confidence";
-
-        /**
          * Adds a call to the call log.
          *
          * @param ci the CallerInfo object to get the target contact from.  Can be null
@@ -696,8 +632,7 @@
                 presentation, callType, features, accountHandle, start, duration,
                 dataUsage, false /* addForAllUsers */, null /* userToBeInsertedTo */,
                 false /* isRead */, Calls.BLOCK_REASON_NOT_BLOCKED /* callBlockReason */,
-                null /* callScreeningAppName */, null /* callScreeningComponentName */,
-                null /* callIdentification */);
+                null /* callScreeningAppName */, null /* callScreeningComponentName */);
         }
 
 
@@ -737,8 +672,7 @@
                 features, accountHandle, start, duration, dataUsage, addForAllUsers,
                 userToBeInsertedTo, false /* isRead */ , Calls.BLOCK_REASON_NOT_BLOCKED
                 /* callBlockReason */, null /* callScreeningAppName */,
-                null /* callScreeningComponentName */,
-                null /* callIdentification */);
+                null /* callScreeningComponentName */);
         }
 
         /**
@@ -784,7 +718,7 @@
                 int features, PhoneAccountHandle accountHandle, long start, int duration,
                 Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
                 boolean isRead, int callBlockReason, CharSequence callScreeningAppName,
-                String callScreeningComponentName, CallIdentification callIdentification) {
+                String callScreeningComponentName) {
             if (VERBOSE_LOG) {
                 Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s",
                         number, userToBeInsertedTo, addForAllUsers));
@@ -839,26 +773,6 @@
             values.put(CALL_SCREENING_APP_NAME, charSequenceToString(callScreeningAppName));
             values.put(CALL_SCREENING_COMPONENT_NAME, callScreeningComponentName);
 
-            if (callIdentification != null) {
-                values.put(CALL_ID_PACKAGE_NAME, callIdentification.getCallScreeningPackageName());
-                values.put(CALL_ID_APP_NAME,
-                        charSequenceToString(callIdentification.getCallScreeningAppName()));
-                values.put(CALL_ID_NAME,
-                        charSequenceToString(callIdentification.getName()));
-                values.put(CALL_ID_DESCRIPTION,
-                        charSequenceToString(callIdentification.getDescription()));
-                values.put(CALL_ID_DETAILS,
-                        charSequenceToString(callIdentification.getDetails()));
-                values.put(CALL_ID_NUISANCE_CONFIDENCE, callIdentification.getNuisanceConfidence());
-            } else {
-                values.putNull(CALL_ID_PACKAGE_NAME);
-                values.putNull(CALL_ID_APP_NAME);
-                values.putNull(CALL_ID_NAME);
-                values.putNull(CALL_ID_DESCRIPTION);
-                values.putNull(CALL_ID_DETAILS);
-                values.putNull(CALL_ID_NUISANCE_CONFIDENCE);
-            }
-
             if ((ci != null) && (ci.contactIdOrZero > 0)) {
                 // Update usage information for the number associated with the contact ID.
                 // We need to use both the number and the ID for obtaining a data ID since other
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 728d77e..5631282 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -299,27 +299,6 @@
                 "device_identifier_access_restrictions_disabled";
     }
 
-    /**
-     * Telephony related properties definitions.
-     *
-     * @hide
-     */
-    public interface Telephony {
-        String NAMESPACE = "telephony";
-        /**
-         * Ringer ramping time in milliseconds.
-         */
-        String RAMPING_RINGER_DURATION = "ramping_ringer_duration";
-        /**
-         * Whether to apply ramping ringer on incoming phone calls.
-         */
-        String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled";
-        /**
-         * Vibration time in milliseconds before ramping ringer starts.
-         */
-        String RAMPING_RINGER_VIBRATION_DURATION = "ramping_ringer_vibration_duration";
-    }
-
     private static final Object sLock = new Object();
     @GuardedBy("sLock")
     private static ArrayMap<OnPropertyChangedListener, Pair<String, Executor>> sSingleListeners =
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index dc5fdc0..bda6ed1 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -31,6 +31,7 @@
 import android.app.Activity;
 import android.app.AppGlobals;
 import android.content.ClipData;
+import android.content.ContentInterface;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentUris;
@@ -115,9 +116,9 @@
      */
     public static final String VOLUME_EXTERNAL = "external";
 
-    /** {@hide} */ @TestApi
+    /** {@hide} */
     public static final String SCAN_FILE_CALL = "scan_file";
-    /** {@hide} */ @TestApi
+    /** {@hide} */
     public static final String SCAN_VOLUME_CALL = "scan_volume";
 
     /**
@@ -126,7 +127,6 @@
      *
      * {@hide}
      */
-    @TestApi
     public static final String EXTRA_ORIGINATED_FROM_SHELL =
             "android.intent.extra.originated_from_shell";
 
@@ -885,9 +885,7 @@
          *             access this path. Instead of trying to open this path
          *             directly, apps should use
          *             {@link ContentResolver#openFileDescriptor(Uri, String)}
-         *             to gain access. This value will always be {@code NULL}
-         *             for apps targeting
-         *             {@link android.os.Build.VERSION_CODES#Q} or higher.
+         *             to gain access.
          */
         @Deprecated
         @Column(Cursor.FIELD_TYPE_STRING)
@@ -1715,11 +1713,9 @@
                     url = cr.insert(EXTERNAL_CONTENT_URI, values);
 
                     if (source != null) {
-                        OutputStream imageOut = cr.openOutputStream(url);
-                        try {
-                            source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
-                        } finally {
-                            imageOut.close();
+                        try (OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(
+                                cr.openFile(url, "w", null))) {
+                            source.compress(Bitmap.CompressFormat.JPEG, 50, out);
                         }
 
                         long id = ContentUris.parseId(url);
@@ -1960,9 +1956,7 @@
              *             access this path. Instead of trying to open this path
              *             directly, apps should use
              *             {@link ContentResolver#loadThumbnail}
-             *             to gain access. This value will always be
-             *             {@code NULL} for apps targeting
-             *             {@link android.os.Build.VERSION_CODES#Q} or higher.
+             *             to gain access.
              */
             @Deprecated
             @Column(Cursor.FIELD_TYPE_STRING)
@@ -2443,9 +2437,7 @@
              *             access this path. Instead of trying to open this path
              *             directly, apps should use
              *             {@link ContentResolver#openFileDescriptor(Uri, String)}
-             *             to gain access. This value will always be
-             *             {@code NULL} for apps targeting
-             *             {@link android.os.Build.VERSION_CODES#Q} or higher.
+             *             to gain access.
              */
             @Deprecated
             @Column(Cursor.FIELD_TYPE_STRING)
@@ -2735,9 +2727,7 @@
              *             access this path. Instead of trying to open this path
              *             directly, apps should use
              *             {@link ContentResolver#loadThumbnail}
-             *             to gain access. This value will always be
-             *             {@code NULL} for apps targeting
-             *             {@link android.os.Build.VERSION_CODES#Q} or higher.
+             *             to gain access.
              */
             @Deprecated
             @Column(Cursor.FIELD_TYPE_STRING)
@@ -2824,9 +2814,7 @@
              *             access this path. Instead of trying to open this path
              *             directly, apps should use
              *             {@link ContentResolver#loadThumbnail}
-             *             to gain access. This value will always be
-             *             {@code NULL} for apps targeting
-             *             {@link android.os.Build.VERSION_CODES#Q} or higher.
+             *             to gain access.
              */
             @Deprecated
             @Column(Cursor.FIELD_TYPE_STRING)
@@ -3194,9 +3182,7 @@
              *             access this path. Instead of trying to open this path
              *             directly, apps should use
              *             {@link ContentResolver#openFileDescriptor(Uri, String)}
-             *             to gain access. This value will always be
-             *             {@code NULL} for apps targeting
-             *             {@link android.os.Build.VERSION_CODES#Q} or higher.
+             *             to gain access.
              */
             @Deprecated
             @Column(Cursor.FIELD_TYPE_STRING)
@@ -3539,12 +3525,32 @@
     }
 
     /** @hide */
+    @TestApi
     public static Uri scanFile(Context context, File file) {
+        return scan(context, SCAN_FILE_CALL, file, false);
+    }
+
+    /** @hide */
+    @TestApi
+    public static Uri scanFileFromShell(Context context, File file) {
+        return scan(context, SCAN_FILE_CALL, file, true);
+    }
+
+    /** @hide */
+    @TestApi
+    public static void scanVolume(Context context, File file) {
+        scan(context, SCAN_VOLUME_CALL, file, false);
+    }
+
+    /** @hide */
+    private static Uri scan(Context context, String method, File file,
+            boolean originatedFromShell) {
         final ContentResolver resolver = context.getContentResolver();
         try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) {
             final Bundle in = new Bundle();
             in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file));
-            final Bundle out = client.call(SCAN_FILE_CALL, null, in);
+            in.putBoolean(EXTRA_ORIGINATED_FROM_SHELL, originatedFromShell);
+            final Bundle out = client.call(method, null, in);
             return out.getParcelable(Intent.EXTRA_STREAM);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 702dc74..85feac8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1501,6 +1501,22 @@
             = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
 
     /**
+     * Activity Action: Show More default apps settings.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    @SystemApi
+    public static final String ACTION_MANAGE_MORE_DEFAULT_APPS_SETTINGS =
+            "android.settings.MANAGE_MORE_DEFAULT_APPS_SETTINGS";
+
+    /**
      * Activity Action: Show notification settings.
      *
      * @hide
@@ -1542,6 +1558,18 @@
             = "android.settings.CHANNEL_NOTIFICATION_SETTINGS";
 
     /**
+     * Activity Action: Show notification bubble settings for a single app.
+     * See {@link NotificationManager#areBubblesAllowed()}.
+     * <p>
+     *     Input: {@link #EXTRA_APP_PACKAGE}, the package to display.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS
+            = "android.settings.APP_NOTIFICATION_BUBBLE_SETTINGS";
+
+    /**
      * Activity Extra: The package owner of the notification channel settings to display.
      * <p>
      * This must be passed as an extra field to the {@link #ACTION_CHANNEL_NOTIFICATION_SETTINGS}.
@@ -7739,15 +7767,6 @@
                 "call_screening_default_component";
 
         /**
-         * Specifies the component name currently configured to be the default application to
-         * perform the user-defined call redirection service with Telecom.
-         * @hide
-         */
-        @UnsupportedAppUsage
-        public static final String CALL_REDIRECTION_DEFAULT_APPLICATION =
-                "call_redirection_default_application";
-
-        /**
          * Specifies the package name currently configured to be the emergency assistance application
          *
          * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE
@@ -8635,9 +8654,10 @@
                 "location_permissions_upgrade_to_q_mode";
 
         /**
-         * Comma separated list of enabled overlay packages for all android.theme.customization.*
-         * categories. If there is no corresponding package included for a category, then all
-         * overlay packages in that category must be disabled.
+         * Map of android.theme.customization.* categories to the enabled overlay package for that
+         * category, formatted as a serialized {@link org.json.JSONObject}. If there is no
+         * corresponding package included for a category, then all overlay packages in that
+         * category must be disabled.
          * @hide
          */
         @SystemApi
@@ -8645,7 +8665,7 @@
                 "theme_customization_overlay_packages";
 
         private static final Validator THEME_CUSTOMIZATION_OVERLAY_PACKAGES_VALIDATOR =
-                new SettingsValidators.PackageNameListValidator(",");
+                SettingsValidators.JSON_OBJECT_VALIDATOR;
 
         /**
          * Controls whether aware is enabled.
@@ -11509,15 +11529,6 @@
                 "background_activity_starts_enabled";
 
         /**
-         * The packages temporarily whitelisted to be able so start activities from background.
-         * The list of packages is {@code ":"} colon delimited.
-         *
-         * @hide
-         */
-        public static final String BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST =
-                "background_activity_starts_package_names_whitelist";
-
-        /**
          * @hide
          * @see com.android.server.appbinding.AppBindingConstants
          */
@@ -12395,6 +12406,19 @@
         public static final String EMERGENCY_AFFORDANCE_NEEDED = "emergency_affordance_needed";
 
         /**
+         * Whether to enable automatic system server heap dumps. This only works on userdebug or
+         * eng builds, not on user builds. This is set by the user and overrides the config value.
+         * 1 means enable, 0 means disable.
+         *
+         * @hide
+         */
+        public static final String ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS =
+                "enable_automatic_system_server_heap_dumps";
+
+        private static final Validator ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_VALIDATOR =
+                new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1"});
+
+        /**
          * See RIL_PreferredNetworkType in ril.h
          * @hide
          */
@@ -12428,6 +12452,14 @@
         public static final String GPU_DEBUG_APP = "gpu_debug_app";
 
         /**
+         * Package containing ANGLE libraries other than system, which are only available
+         * to dumpable apps that opt-in.
+         * @hide
+         */
+        public static final String GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE =
+                "angle_debug_package";
+
+        /**
          * Force all PKGs to use ANGLE, regardless of any other settings
          * The value is a boolean (1 or 0).
          * @hide
@@ -13464,24 +13496,6 @@
                 "hidden_api_blacklist_exemptions";
 
         /**
-         * Sampling rate for hidden API access event logs with libmetricslogger, as an integer in
-         * the range 0 to 0x10000 inclusive.
-         *
-         * @hide
-         */
-        public static final String HIDDEN_API_ACCESS_LOG_SAMPLING_RATE =
-                "hidden_api_access_log_sampling_rate";
-
-        /**
-         * Sampling rate for hidden API access event logging with statslog, as an integer in the
-         * range 0 to 0x10000 inclusive.
-         *
-         * @hide
-         */
-        public static final String HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE =
-                "hidden_api_access_statslog_sampling_rate";
-
-        /**
          * Hidden API enforcement policy for apps.
          *
          * Values correspond to @{@link
@@ -13565,6 +13579,7 @@
             EMERGENCY_TONE,
             CALL_AUTO_RETRY,
             DOCK_AUDIO_MEDIA_ENABLED,
+            ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS,
             ENCODED_SURROUND_OUTPUT,
             ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
             LOW_POWER_MODE_TRIGGER_LEVEL,
@@ -13607,6 +13622,8 @@
             VALIDATORS.put(EMERGENCY_TONE, EMERGENCY_TONE_VALIDATOR);
             VALIDATORS.put(CALL_AUTO_RETRY, CALL_AUTO_RETRY_VALIDATOR);
             VALIDATORS.put(DOCK_AUDIO_MEDIA_ENABLED, DOCK_AUDIO_MEDIA_ENABLED_VALIDATOR);
+            VALIDATORS.put(ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS,
+                    ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_VALIDATOR);
             VALIDATORS.put(ENCODED_SURROUND_OUTPUT, ENCODED_SURROUND_OUTPUT_VALIDATOR);
             VALIDATORS.put(ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
                     ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS_VALIDATOR);
@@ -14716,7 +14733,6 @@
          *
          * @hide
          */
-        // TODO(b/117663715): require a new write permission restricted to a single source
         @RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG)
         static void resetToDefaults(@NonNull ContentResolver resolver, @ResetMode int resetMode,
                 @Nullable String prefix) {
diff --git a/core/java/android/provider/SettingsValidators.java b/core/java/android/provider/SettingsValidators.java
index 25e77867..4051213 100644
--- a/core/java/android/provider/SettingsValidators.java
+++ b/core/java/android/provider/SettingsValidators.java
@@ -19,9 +19,13 @@
 import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.net.Uri;
+import android.text.TextUtils;
 
 import com.android.internal.util.ArrayUtils;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import java.util.Locale;
 
 /**
@@ -162,6 +166,19 @@
         }
     };
 
+    /** {@link Validator} that checks whether a value is a valid {@link JSONObject}. */
+    public static final Validator JSON_OBJECT_VALIDATOR = (value) -> {
+        if (TextUtils.isEmpty(value)) {
+            return false;
+        }
+        try {
+            new JSONObject(value);
+            return true;
+        } catch (JSONException e) {
+            return false;
+        }
+    };
+
     public interface Validator {
         /**
          * Returns whether the input value is valid. Subclasses should handle the case where the
diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java
index 6629233..af5bf74 100644
--- a/core/java/android/service/carrier/CarrierIdentifier.java
+++ b/core/java/android/service/carrier/CarrierIdentifier.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telephony.Rlog;
 import android.telephony.TelephonyManager;
 
 import com.android.internal.telephony.uicc.IccUtils;
@@ -223,7 +224,7 @@
               + "mcc=" + mMcc
               + ",mnc=" + mMnc
               + ",spn=" + mSpn
-              + ",imsi=" + mImsi
+              + ",imsi=" + Rlog.pii(false, mImsi)
               + ",gid1=" + mGid1
               + ",gid2=" + mGid2
               + ",carrierid=" + mCarrierId
diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java
index c351d89..aeb186b 100644
--- a/core/java/android/service/carrier/CarrierService.java
+++ b/core/java/android/service/carrier/CarrierService.java
@@ -114,9 +114,7 @@
      * this UX, so a carrier app must be sure to call with active set to false
      * sometime after calling with it set to true.
      * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
-     * or the calling app has carrier privileges.
+     * Requires Permission: calling app has carrier privileges.
      *
      * @param active Whether the carrier network change is or shortly will be
      *               active. Set this value to true to begin showing
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index fb07aba..dc57a15 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -17,6 +17,8 @@
 
 import static android.view.contentcapture.ContentCaptureHelper.sDebug;
 import static android.view.contentcapture.ContentCaptureHelper.sVerbose;
+import static android.view.contentcapture.ContentCaptureHelper.toList;
+import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID;
 
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
@@ -36,9 +38,10 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.service.autofill.AutofillService;
-import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseIntArray;
+import android.view.contentcapture.ContentCaptureCondition;
 import android.view.contentcapture.ContentCaptureContext;
 import android.view.contentcapture.ContentCaptureEvent;
 import android.view.contentcapture.ContentCaptureManager;
@@ -52,7 +55,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
@@ -116,7 +118,7 @@
         }
 
         @Override
-        public void onSessionStarted(ContentCaptureContext context, String sessionId, int uid,
+        public void onSessionStarted(ContentCaptureContext context, int sessionId, int uid,
                 IResultReceiver clientReceiver, int initialState) {
             mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnCreateSession,
                     ContentCaptureService.this, context, sessionId, uid, clientReceiver,
@@ -124,14 +126,14 @@
         }
 
         @Override
-        public void onActivitySnapshot(String sessionId, SnapshotData snapshotData) {
+        public void onActivitySnapshot(int sessionId, SnapshotData snapshotData) {
             mHandler.sendMessage(
                     obtainMessage(ContentCaptureService::handleOnActivitySnapshot,
                             ContentCaptureService.this, sessionId, snapshotData));
         }
 
         @Override
-        public void onSessionFinished(String sessionId) {
+        public void onSessionFinished(int sessionId) {
             mHandler.sendMessage(obtainMessage(ContentCaptureService::handleFinishSession,
                     ContentCaptureService.this, sessionId));
         }
@@ -170,7 +172,7 @@
      * <p>This map is populated when an session is started, which is called by the system server
      * and can be trusted. Then subsequent calls made by the app are verified against this map.
      */
-    private final ArrayMap<String, Integer> mSessionUids = new ArrayMap<>();
+    private final SparseIntArray mSessionUids = new SparseIntArray();
 
     @CallSuper
     @Override
@@ -216,8 +218,40 @@
         }
     }
 
-    private <T> ArrayList<T> toList(@Nullable Set<T> set) {
-        return set == null ? null : new ArrayList<T>(set);
+    /**
+     * Explicitly sets the conditions for which content capture should be available by an app.
+     *
+     * <p>Typically used to restrict content capture to a few websites on browser apps. Example:
+     *
+     * <code>
+     *   ArraySet<ContentCaptureCondition> conditions = new ArraySet<>(1);
+     *   conditions.add(new ContentCaptureCondition(new LocusId("^https://.*\\.example\\.com$"),
+     *       ContentCaptureCondition.FLAG_IS_REGEX));
+     *   service.setContentCaptureConditions("com.example.browser_app", conditions);
+     *
+     * </code>
+     *
+     * <p>NOTE: </p> this method doesn't automatically disable content capture for the given
+     * conditions; it's up to the {@code packageName} implementation to call
+     * {@link ContentCaptureManager#getContentCaptureConditions()} and disable it accordingly.
+     *
+     * @param packageName name of the packages where the restrictions are set.
+     * @param conditions list of conditions, or {@code null} to reset the conditions for the
+     * package.
+     */
+    public final void setContentCaptureConditions(@NonNull String packageName,
+            @Nullable Set<ContentCaptureCondition> conditions) {
+        final IContentCaptureServiceCallback callback = mCallback;
+        if (callback == null) {
+            Log.w(TAG, "setContentCaptureConditions(): no server callback");
+            return;
+        }
+
+        try {
+            callback.setContentCaptureConditions(packageName, toList(conditions));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
     }
 
     /**
@@ -351,7 +385,7 @@
     // so we don't need to create a temporary InteractionSessionId for each event.
 
     private void handleOnCreateSession(@NonNull ContentCaptureContext context,
-            @NonNull String sessionId, int uid, IResultReceiver clientReceiver, int initialState) {
+            int sessionId, int uid, IResultReceiver clientReceiver, int initialState) {
         mSessionUids.put(sessionId, uid);
         onCreateContentCaptureSession(context, new ContentCaptureSessionId(sessionId));
 
@@ -376,27 +410,27 @@
 
         // Most events belong to the same session, so we can keep a reference to the last one
         // to avoid creating too many ContentCaptureSessionId objects
-        String lastSessionId = null;
+        int lastSessionId = NO_SESSION_ID;
         ContentCaptureSessionId sessionId = null;
 
         final List<ContentCaptureEvent> events = parceledEvents.getList();
         for (int i = 0; i < events.size(); i++) {
             final ContentCaptureEvent event = events.get(i);
             if (!handleIsRightCallerFor(event, uid)) continue;
-            String sessionIdString = event.getSessionId();
-            if (!sessionIdString.equals(lastSessionId)) {
-                sessionId = new ContentCaptureSessionId(sessionIdString);
-                lastSessionId = sessionIdString;
+            int sessionIdInt = event.getSessionId();
+            if (sessionIdInt != lastSessionId) {
+                sessionId = new ContentCaptureSessionId(sessionIdInt);
+                lastSessionId = sessionIdInt;
             }
             switch (event.getType()) {
                 case ContentCaptureEvent.TYPE_SESSION_STARTED:
                     final ContentCaptureContext clientContext = event.getContentCaptureContext();
                     clientContext.setParentSessionId(event.getParentSessionId());
-                    mSessionUids.put(sessionIdString, uid);
+                    mSessionUids.put(sessionIdInt, uid);
                     onCreateContentCaptureSession(clientContext, sessionId);
                     break;
                 case ContentCaptureEvent.TYPE_SESSION_FINISHED:
-                    mSessionUids.remove(sessionIdString);
+                    mSessionUids.delete(sessionIdInt);
                     onDestroyContentCaptureSession(sessionId);
                     break;
                 default:
@@ -405,13 +439,12 @@
         }
     }
 
-    private void handleOnActivitySnapshot(@NonNull String sessionId,
-            @NonNull SnapshotData snapshotData) {
+    private void handleOnActivitySnapshot(int sessionId, @NonNull SnapshotData snapshotData) {
         onActivitySnapshot(new ContentCaptureSessionId(sessionId), snapshotData);
     }
 
-    private void handleFinishSession(@NonNull String sessionId) {
-        mSessionUids.remove(sessionId);
+    private void handleFinishSession(int sessionId) {
+        mSessionUids.delete(sessionId);
         onDestroyContentCaptureSession(new ContentCaptureSessionId(sessionId));
     }
 
@@ -427,7 +460,7 @@
      * Checks if the given {@code uid} owns the session associated with the event.
      */
     private boolean handleIsRightCallerFor(@NonNull ContentCaptureEvent event, int uid) {
-        final String sessionId;
+        final int sessionId;
         switch (event.getType()) {
             case ContentCaptureEvent.TYPE_SESSION_STARTED:
             case ContentCaptureEvent.TYPE_SESSION_FINISHED:
@@ -436,8 +469,7 @@
             default:
                 sessionId = event.getSessionId();
         }
-        final Integer rightUid = mSessionUids.get(sessionId);
-        if (rightUid == null) {
+        if (mSessionUids.indexOfKey(sessionId) < 0) {
             if (sVerbose) {
                 Log.v(TAG, "handleIsRightCallerFor(" + event + "): no session for " + sessionId
                         + ": " + mSessionUids);
@@ -445,6 +477,7 @@
             // Just ignore, as the session could have been finished already
             return false;
         }
+        final int rightUid = mSessionUids.get(sessionId);
         if (rightUid != uid) {
             Log.e(TAG, "invalid call from UID " + uid + ": session " + sessionId + " belongs to "
                     + rightUid);
diff --git a/core/java/android/service/contentcapture/IContentCaptureService.aidl b/core/java/android/service/contentcapture/IContentCaptureService.aidl
index 6be7a80..03e1b78 100644
--- a/core/java/android/service/contentcapture/IContentCaptureService.aidl
+++ b/core/java/android/service/contentcapture/IContentCaptureService.aidl
@@ -35,10 +35,10 @@
 oneway interface IContentCaptureService {
     void onConnected(IBinder callback, boolean verbose, boolean debug);
     void onDisconnected();
-    void onSessionStarted(in ContentCaptureContext context, String sessionId, int uid,
+    void onSessionStarted(in ContentCaptureContext context, int sessionId, int uid,
                           in IResultReceiver clientReceiver, int initialState);
-    void onSessionFinished(String sessionId);
-    void onActivitySnapshot(String sessionId, in SnapshotData snapshotData);
+    void onSessionFinished(int sessionId);
+    void onActivitySnapshot(int sessionId, in SnapshotData snapshotData);
     void onUserDataRemovalRequest(in UserDataRemovalRequest request);
     void onActivityEvent(in ActivityEvent event);
 }
diff --git a/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl b/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl
index 8bc8def..0550ad3 100644
--- a/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl
+++ b/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl
@@ -17,6 +17,7 @@
 package android.service.contentcapture;
 
 import android.content.ComponentName;
+import android.view.contentcapture.ContentCaptureCondition;
 
 import java.util.List;
 
@@ -27,5 +28,6 @@
  */
 oneway interface IContentCaptureServiceCallback {
     void setContentCaptureWhitelist(in List<String> packages, in List<ComponentName> activities);
+    void setContentCaptureConditions(String packageName, in List<ContentCaptureCondition> conditions);
     void disableSelf();
  }
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index c35423f..d32bdad 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -87,6 +87,10 @@
      * This intent may also define a {@link Intent#EXTRA_COMPONENT_NAME} value
      * to indicate the {@link ComponentName} that caused the preferences to be
      * opened.
+     * <p>
+     * To ensure that the activity can only be launched through quick settings
+     * UI provided by this service, apps can protect it with the
+     * BIND_QUICK_SETTINGS_TILE permission.
      */
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
     public static final String ACTION_QS_TILE_PREFERENCES
diff --git a/core/java/android/service/wallpaper/IWallpaperService.aidl b/core/java/android/service/wallpaper/IWallpaperService.aidl
index 99a81f5..56e2486 100644
--- a/core/java/android/service/wallpaper/IWallpaperService.aidl
+++ b/core/java/android/service/wallpaper/IWallpaperService.aidl
@@ -26,4 +26,5 @@
     void attach(IWallpaperConnection connection,
             IBinder windowToken, int windowType, boolean isPreview,
             int reqWidth, int reqHeight, in Rect padding, int displayId);
+    void detach();
 }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index e1762df..d645e3f 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -72,6 +72,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Supplier;
 
 /**
@@ -1309,6 +1310,7 @@
         final int mDisplayId;
         final DisplayManager mDisplayManager;
         final Display mDisplay;
+        private final AtomicBoolean mDetached = new AtomicBoolean();
 
         Engine mEngine;
 
@@ -1399,8 +1401,23 @@
             mCaller.sendMessage(msg);
         }
 
+        public void detach() {
+            mDetached.set(true);
+        }
+
+        private void doDetachEngine() {
+            mActiveEngines.remove(mEngine);
+            mEngine.detach();
+        }
+
         @Override
         public void executeMessage(Message message) {
+            if (mDetached.get()) {
+                if (mActiveEngines.contains(mEngine)) {
+                    doDetachEngine();
+                }
+                return;
+            }
             switch (message.what) {
                 case DO_ATTACH: {
                     try {
@@ -1416,8 +1433,7 @@
                     return;
                 }
                 case DO_DETACH: {
-                    mActiveEngines.remove(mEngine);
-                    mEngine.detach();
+                    doDetachEngine();
                     return;
                 }
                 case DO_SET_DESIRED_SIZE: {
@@ -1497,6 +1513,7 @@
      */
     class IWallpaperServiceWrapper extends IWallpaperService.Stub {
         private final WallpaperService mTarget;
+        private IWallpaperEngineWrapper mEngineWrapper;
 
         public IWallpaperServiceWrapper(WallpaperService context) {
             mTarget = context;
@@ -1506,9 +1523,14 @@
         public void attach(IWallpaperConnection conn, IBinder windowToken,
                 int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding,
                 int displayId) {
-            new IWallpaperEngineWrapper(mTarget, conn, windowToken,
+            mEngineWrapper = new IWallpaperEngineWrapper(mTarget, conn, windowToken,
                     windowType, isPreview, reqWidth, reqHeight, padding, displayId);
         }
+
+        @Override
+        public void detach() {
+            mEngineWrapper.detach();
+        }
     }
 
     @Override
diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
new file mode 100644
index 0000000..015fba1
--- /dev/null
+++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.watchdog;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A service to provide packages supporting explicit health checks and route checks to these
+ * packages on behalf of the package watchdog.
+ *
+ * <p>To extend this class, you must declare the service in your manifest file with the
+ * {@link android.Manifest.permission#BIND_EXPLICIT_HEALTH_CHECK_SERVICE} permission,
+ * and include an intent filter with the {@link #SERVICE_INTERFACE} action. In adddition,
+ * your implementation must live in {@link PackageManger#SYSTEM_SHARED_LIBRARY_SERVICES}.
+ * For example:</p>
+ * <pre>
+ *     &lt;service android:name=".FooExplicitHealthCheckService"
+ *             android:exported="true"
+ *             android:priority="100"
+ *             android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"&gt;
+ *         &lt;intent-filter&gt;
+ *             &lt;action android:name="android.service.watchdog.ExplicitHealthCheckService" /&gt;
+ *         &lt;/intent-filter&gt;
+ *     &lt;/service&gt;
+ * </pre>
+ * @hide
+ */
+@SystemApi
+public abstract class ExplicitHealthCheckService extends Service {
+
+    private static final String TAG = "ExplicitHealthCheckService";
+
+    /**
+     * {@link Bundle} key for a {@link List} of {@link String} value.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_SUPPORTED_PACKAGES =
+            "android.service.watchdog.extra.supported_packages";
+
+    /**
+     * {@link Bundle} key for a {@link List} of {@link String} value.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_REQUESTED_PACKAGES =
+            "android.service.watchdog.extra.requested_packages";
+
+    /**
+     * {@link Bundle} key for a {@link String} value.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE =
+            "android.service.watchdog.extra.health_check_passed_package";
+
+    /**
+     * The Intent action that a service must respond to. Add it to the intent filter of the service
+     * in its manifest.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.service.watchdog.ExplicitHealthCheckService";
+
+    /**
+     * The permission that a service must require to ensure that only Android system can bind to it.
+     * If this permission is not enforced in the AndroidManifest of the service, the system will
+     * skip that service.
+     */
+    public static final String BIND_PERMISSION =
+            "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
+
+    private final ExplicitHealthCheckServiceWrapper mWrapper =
+            new ExplicitHealthCheckServiceWrapper();
+
+    /**
+     * Called when the system requests an explicit health check for {@code packageName}.
+     *
+     * <p> When {@code packageName} passes the check, implementors should call
+     * {@link #notifyHealthCheckPassed} to inform the system.
+     *
+     * <p> It could take many hours before a {@code packageName} passes a check and implementors
+     * should never drop requests unless {@link onCancel} is called or the service dies.
+     *
+     * <p> Requests should not be queued and additional calls while expecting a result for
+     * {@code packageName} should have no effect.
+     */
+    public abstract void onRequestHealthCheck(@NonNull String packageName);
+
+    /**
+     * Called when the system cancels the explicit health check request for {@code packageName}.
+     * Should do nothing if there are is no active request for {@code packageName}.
+     */
+    public abstract void onCancelHealthCheck(@NonNull String packageName);
+
+    /**
+     * Called when the system requests for all the packages supporting explicit health checks. The
+     * system may request an explicit health check for any of these packages with
+     * {@link #onRequestHealthCheck}.
+     *
+     * @return all packages supporting explicit health checks
+     */
+    @NonNull public abstract List<String> onGetSupportedPackages();
+
+    /**
+     * Called when the system requests for all the packages that it has currently requested
+     * an explicit health check for.
+     *
+     * @return all packages expecting an explicit health check result
+     */
+    @NonNull public abstract List<String> onGetRequestedPackages();
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
+    @Nullable private RemoteCallback mCallback;
+
+    @Override
+    @NonNull
+    public final IBinder onBind(@NonNull Intent intent) {
+        return mWrapper;
+    }
+
+    /**
+     * Implementors should call this to notify the system when explicit health check passes
+     * for {@code packageName};
+     */
+    public final void notifyHealthCheckPassed(@NonNull String packageName) {
+        mHandler.post(() -> {
+            if (mCallback != null) {
+                Objects.requireNonNull(packageName,
+                        "Package passing explicit health check must be non-null");
+                Bundle bundle = new Bundle();
+                bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName);
+                mCallback.sendResult(bundle);
+            } else {
+                Log.wtf(TAG, "System missed explicit health check result for " + packageName);
+            }
+        });
+    }
+
+    private class ExplicitHealthCheckServiceWrapper extends IExplicitHealthCheckService.Stub {
+        @Override
+        public void setCallback(RemoteCallback callback) throws RemoteException {
+            mHandler.post(() -> {
+                mCallback = callback;
+            });
+        }
+
+        @Override
+        public void request(String packageName) throws RemoteException {
+            mHandler.post(() -> ExplicitHealthCheckService.this.onRequestHealthCheck(packageName));
+        }
+
+        @Override
+        public void cancel(String packageName) throws RemoteException {
+            mHandler.post(() -> ExplicitHealthCheckService.this.onCancelHealthCheck(packageName));
+        }
+
+        @Override
+        public void getSupportedPackages(RemoteCallback callback) throws RemoteException {
+            mHandler.post(() -> sendPackages(callback, EXTRA_SUPPORTED_PACKAGES,
+                    ExplicitHealthCheckService.this.onGetSupportedPackages()));
+        }
+
+        @Override
+        public void getRequestedPackages(RemoteCallback callback) throws RemoteException {
+            mHandler.post(() -> sendPackages(callback, EXTRA_REQUESTED_PACKAGES,
+                    ExplicitHealthCheckService.this.onGetRequestedPackages()));
+        }
+
+        private void sendPackages(RemoteCallback callback, String key, List<String> packages) {
+            Objects.requireNonNull(packages,
+                    "Supported and requested package list must be non-null");
+            Bundle bundle = new Bundle();
+            bundle.putStringArrayList(key, new ArrayList<>(packages));
+            callback.sendResult(bundle);
+        }
+    }
+}
diff --git a/packages/NetworkStackPermissionStub/src/com/android/server/NetworkStackPermissionStub.java b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl
similarity index 62%
copy from packages/NetworkStackPermissionStub/src/com/android/server/NetworkStackPermissionStub.java
copy to core/java/android/service/watchdog/IExplicitHealthCheckService.aidl
index 01e59d2..78c0328d 100644
--- a/packages/NetworkStackPermissionStub/src/com/android/server/NetworkStackPermissionStub.java
+++ b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl
@@ -14,13 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.server;
+package android.service.watchdog;
 
-import android.app.Application;
+import android.os.RemoteCallback;
 
 /**
- * Empty application for NetworkStackStub that only exists because soong builds complain if APKs
- * have no source file.
+ * @hide
  */
-public class NetworkStackPermissionStub extends Application {
+oneway interface IExplicitHealthCheckService
+{
+    void setCallback(in @nullable RemoteCallback callback);
+    void request(String packageName);
+    void cancel(String packageName);
+    void getSupportedPackages(in RemoteCallback callback);
+    void getRequestedPackages(in RemoteCallback callback);
 }
diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java
index a7b280b..2fab404 100644
--- a/core/java/android/speech/tts/TtsEngines.java
+++ b/core/java/android/speech/tts/TtsEngines.java
@@ -15,8 +15,10 @@
  */
 package android.speech.tts;
 
-import org.xmlpull.v1.XmlPullParserException;
+import static android.provider.Settings.Secure.getString;
 
+import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -27,10 +29,6 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
-
-import static android.provider.Settings.Secure.getString;
-
-import android.annotation.UnsupportedAppUsage;
 import android.provider.Settings;
 import android.speech.tts.TextToSpeech.Engine;
 import android.speech.tts.TextToSpeech.EngineInfo;
@@ -39,6 +37,8 @@
 import android.util.Log;
 import android.util.Xml;
 
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -522,7 +522,8 @@
      * read back, will evaluate to {@link Locale#getDefault()}.
      */
     @UnsupportedAppUsage
-    public synchronized void updateLocalePrefForEngine(String engineName, Locale newLocale) {
+    public synchronized void updateLocalePrefForEngine(
+            @NonNull String engineName, Locale newLocale) {
         final String prefList = Settings.Secure.getString(mContext.getContentResolver(),
                 Settings.Secure.TTS_DEFAULT_LOCALE);
         if (DBG) {
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index 077d12d..d7baa10 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -92,10 +92,15 @@
      * @return formatted string with the number
      */
     public static String formatFileSize(@Nullable Context context, long sizeBytes) {
+        return formatFileSize(context, sizeBytes, FLAG_SI_UNITS);
+    }
+
+    /** @hide */
+    public static String formatFileSize(@Nullable Context context, long sizeBytes, int flags) {
         if (context == null) {
             return "";
         }
-        final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SI_UNITS);
+        final BytesResult res = formatBytes(context.getResources(), sizeBytes, flags);
         return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix,
                 res.value, res.units));
     }
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index 436cb4f..e2af6f5 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -16,12 +16,12 @@
 
 package android.util;
 
-import libcore.util.EmptyArray;
-
 import android.annotation.UnsupportedAppUsage;
 
 import com.android.internal.util.ArrayUtils;
 
+import libcore.util.EmptyArray;
+
 import java.util.Collection;
 import java.util.ConcurrentModificationException;
 import java.util.Map;
@@ -453,6 +453,10 @@
      * @return Returns the key stored at the given index.
      */
     public K keyAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return (K)mArray[index << 1];
     }
 
@@ -462,6 +466,10 @@
      * @return Returns the value stored at the given index.
      */
     public V valueAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return (V)mArray[(index << 1) + 1];
     }
 
@@ -472,6 +480,10 @@
      * @return Returns the previous value at the given index.
      */
     public V setValueAt(int index, V value) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         index = (index << 1) + 1;
         V old = (V)mArray[index];
         mArray[index] = value;
@@ -665,6 +677,11 @@
      * @return Returns the value that was stored at this index.
      */
     public V removeAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
+
         final Object old = mArray[(index << 1) + 1];
         final int osize = mSize;
         final int nsize;
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index da6ef4c..5d33b49 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -41,6 +41,7 @@
     public static final String GLOBAL_ACTIONS_GRID_ENABLED = "settings_global_actions_grid_enabled";
     public static final String GLOBAL_ACTIONS_PANEL_ENABLED =
             "settings_global_actions_panel_enabled";
+    public static final String DYNAMIC_SYSTEM = "settings_dynamic_system";
 
     private static final Map<String, String> DEFAULT_FLAGS;
 
@@ -52,10 +53,10 @@
         DEFAULT_FLAGS.put("settings_slice_injection", "true");
         DEFAULT_FLAGS.put("settings_systemui_theme", "true");
         DEFAULT_FLAGS.put("settings_mainline_module", "true");
-        DEFAULT_FLAGS.put("settings_dynamic_system", "false");
+        DEFAULT_FLAGS.put(DYNAMIC_SYSTEM, "false");
         DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false");
         DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
-        DEFAULT_FLAGS.put(SAFETY_HUB, "false");
+        DEFAULT_FLAGS.put(SAFETY_HUB, "true");
         DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
         DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "true");
         DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true");
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index cf49803..e4de704 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -21,9 +21,6 @@
 
 import libcore.util.EmptyArray;
 
-import java.util.Arrays;
-import java.util.Objects;
-
 /**
  * SparseArray mapping longs to Objects.  Unlike a normal array of Objects,
  * there can be gaps in the indices.  It is intended to be more memory efficient
@@ -147,6 +144,10 @@
      * Removes the mapping at the specified index.
      */
     public void removeAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         if (mValues[index] != DELETED) {
             mValues[index] = DELETED;
             mGarbage = true;
@@ -236,6 +237,10 @@
      * key.</p>
      */
     public long keyAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         if (mGarbage) {
             gc();
         }
@@ -256,6 +261,10 @@
      */
     @SuppressWarnings("unchecked")
     public E valueAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         if (mGarbage) {
             gc();
         }
@@ -269,6 +278,10 @@
      * LongSparseArray stores.
      */
     public void setValueAt(int index, E value) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         if (mGarbage) {
             gc();
         }
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index 8dcdb40..f167f00 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -16,14 +16,13 @@
 
 package android.util;
 
+import android.annotation.UnsupportedAppUsage;
+
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
-import android.annotation.UnsupportedAppUsage;
 import libcore.util.EmptyArray;
 
-import java.util.Arrays;
-
 /**
  * Map of {@code long} to {@code long}. Unlike a normal array of longs, there
  * can be gaps in the indices. It is intended to be more memory efficient than using a
@@ -173,6 +172,10 @@
      * key.</p>
      */
     public long keyAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return mKeys[index];
     }
 
@@ -188,6 +191,10 @@
      * associated with the largest key.</p>
      */
     public long valueAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return mValues[index];
     }
 
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 89ea2d3..67dfb02 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -16,10 +16,11 @@
 
 package android.util;
 
+import android.annotation.UnsupportedAppUsage;
+
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
-import android.annotation.UnsupportedAppUsage;
 import libcore.util.EmptyArray;
 
 /**
@@ -171,6 +172,10 @@
      * the behavior is undefined.</p>
      */
     public void removeAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         if (mValues[index] != DELETED) {
             mValues[index] = DELETED;
             mGarbage = true;
@@ -279,6 +284,10 @@
      * the behavior is undefined.</p>
      */
     public int keyAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         if (mGarbage) {
             gc();
         }
@@ -302,6 +311,10 @@
      */
     @SuppressWarnings("unchecked")
     public E valueAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         if (mGarbage) {
             gc();
         }
@@ -317,6 +330,10 @@
      * <p>For indices outside of the range <code>0...size()-1</code>, the behavior is undefined.</p>
      */
     public void setValueAt(int index, E value) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         if (mGarbage) {
             gc();
         }
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index d4c4095..03fa1c9 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -16,10 +16,11 @@
 
 package android.util;
 
+import android.annotation.UnsupportedAppUsage;
+
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
-import android.annotation.UnsupportedAppUsage;
 import libcore.util.EmptyArray;
 
 /**
@@ -167,6 +168,10 @@
      * key.</p>
      */
     public int keyAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return mKeys[index];
     }
 
@@ -182,6 +187,10 @@
      * associated with the largest key.</p>
      */
     public boolean valueAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return mValues[index];
     }
 
@@ -189,11 +198,19 @@
      * Directly set the value at a particular index.
      */
     public void setValueAt(int index, boolean value) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         mValues[index] = value;
     }
 
     /** @hide */
     public void setKeyAt(int index, int key) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         mKeys[index] = key;
     }
 
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index 9e6bad1..c68dc4e 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -16,14 +16,15 @@
 
 package android.util;
 
+import android.annotation.UnsupportedAppUsage;
+
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
-import java.util.Arrays;
-
-import android.annotation.UnsupportedAppUsage;
 import libcore.util.EmptyArray;
 
+import java.util.Arrays;
+
 /**
  * SparseIntArrays map integers to integers.  Unlike a normal array of integers,
  * there can be gaps in the indices.  It is intended to be more memory efficient
@@ -171,6 +172,10 @@
      * key.</p>
      */
     public int keyAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return mKeys[index];
     }
 
@@ -186,6 +191,10 @@
      * associated with the largest key.</p>
      */
     public int valueAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return mValues[index];
     }
 
@@ -193,6 +202,10 @@
      * Directly set the value at a particular index.
      */
     public void setValueAt(int index, int value) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         mValues[index] = value;
     }
 
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index 81db2b7..37a9202 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -182,6 +182,10 @@
      * key.</p>
      */
     public int keyAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return mKeys[index];
     }
 
@@ -197,6 +201,10 @@
      * associated with the largest key.</p>
      */
     public long valueAt(int index) {
+        if (index >= mSize) {
+            // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+            throw new ArrayIndexOutOfBoundsException(index);
+        }
         return mValues[index];
     }
 
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 610f7ed..715181f 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -512,8 +512,8 @@
      * @hide
      */
     public DisplayCutout inset(int insetLeft, int insetTop, int insetRight, int insetBottom) {
-        if (isBoundsEmpty()
-                || insetLeft == 0 && insetTop == 0 && insetRight == 0 && insetBottom == 0) {
+        if (insetLeft == 0 && insetTop == 0 && insetRight == 0 && insetBottom == 0
+                || isBoundsEmpty()) {
             return this;
         }
 
@@ -534,6 +534,12 @@
             safeInsets.right = atLeastZero(safeInsets.right - insetRight);
         }
 
+        // If we are not cutting off part of the cutout by insetting it on bottom/right, and we also
+        // don't move it around, we can avoid the allocation and copy of the instance.
+        if (insetLeft == 0 && insetTop == 0 && mSafeInsets.equals(safeInsets)) {
+            return this;
+        }
+
         Rect[] bounds = mBounds.getRects();
         for (int i = 0; i < bounds.length; ++i) {
             if (!bounds[i].equals(ZERO_RECT)) {
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index c794a69..8fbbcf4 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -16,11 +16,20 @@
 
 package android.view;
 
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION;
+
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
+import android.os.SystemClock;
+import android.util.StatsLog;
 
 /**
  * Detects various gestures and events using the supplied {@link MotionEvent}s.
@@ -251,8 +260,12 @@
     private boolean mAlwaysInTapRegion;
     private boolean mAlwaysInBiggerTapRegion;
     private boolean mIgnoreNextUpEvent;
+    // Whether a classification has been recorded by statsd for the current event stream. Reset on
+    // ACTION_DOWN.
+    private boolean mHasRecordedClassification;
 
     private MotionEvent mCurrentDownEvent;
+    private MotionEvent mCurrentMotionEvent;
     private MotionEvent mPreviousUpEvent;
 
     /**
@@ -297,6 +310,7 @@
                     break;
 
                 case LONG_PRESS:
+                    recordGestureClassification(msg.arg1);
                     dispatchLongPress();
                     break;
 
@@ -304,6 +318,8 @@
                     // If the user's finger is still down, do not count it as a tap
                     if (mDoubleTapListener != null) {
                         if (!mStillDown) {
+                            recordGestureClassification(
+                                    TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP);
                             mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent);
                         } else {
                             mDeferConfirmSingleTap = true;
@@ -501,6 +517,11 @@
 
         final int action = ev.getAction();
 
+        if (mCurrentMotionEvent != null) {
+            mCurrentMotionEvent.recycle();
+        }
+        mCurrentMotionEvent = MotionEvent.obtain(ev);
+
         if (mVelocityTracker == null) {
             mVelocityTracker = VelocityTracker.obtain();
         }
@@ -569,6 +590,8 @@
                             && isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {
                         // This is a second tap
                         mIsDoubleTapping = true;
+                        recordGestureClassification(
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP);
                         // Give a callback with the first tap of the double-tap
                         handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
                         // Give a callback with down event of the double-tap
@@ -590,11 +613,17 @@
                 mStillDown = true;
                 mInLongPress = false;
                 mDeferConfirmSingleTap = false;
+                mHasRecordedClassification = false;
 
                 if (mIsLongpressEnabled) {
                     mHandler.removeMessages(LONG_PRESS);
-                    mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
-                            + ViewConfiguration.getLongPressTimeout());
+                    mHandler.sendMessageAtTime(
+                            mHandler.obtainMessage(
+                                    LONG_PRESS,
+                                    TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS,
+                                    0 /* arg2 */),
+                            mCurrentDownEvent.getDownTime()
+                                    + ViewConfiguration.getLongPressTimeout());
                 }
                 mHandler.sendEmptyMessageAtTime(SHOW_PRESS,
                         mCurrentDownEvent.getDownTime() + TAP_TIMEOUT);
@@ -613,6 +642,8 @@
                 final float scrollY = mLastFocusY - focusY;
                 if (mIsDoubleTapping) {
                     // Give the move events of the double-tap
+                    recordGestureClassification(
+                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP);
                     handled |= mDoubleTapListener.onDoubleTapEvent(ev);
                 } else if (mAlwaysInTapRegion) {
                     final int deltaX = (int) (focusX - mDownFocusX);
@@ -635,8 +666,12 @@
                             // reschedule long press with a modified timeout.
                             mHandler.removeMessages(LONG_PRESS);
                             final long longPressTimeout = ViewConfiguration.getLongPressTimeout();
-                            mHandler.sendEmptyMessageAtTime(LONG_PRESS, ev.getDownTime()
-                                    + (long) (longPressTimeout * multiplier));
+                            mHandler.sendMessageAtTime(
+                                    mHandler.obtainMessage(
+                                            LONG_PRESS,
+                                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS,
+                                            0 /* arg2 */),
+                                    ev.getDownTime() + (long) (longPressTimeout * multiplier));
                         }
                         // Inhibit default scroll. If a gesture is ambiguous, we prevent scroll
                         // until the gesture is resolved.
@@ -646,6 +681,8 @@
                     }
 
                     if (distance > slopSquare) {
+                        recordGestureClassification(
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL);
                         handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
                         mLastFocusX = focusX;
                         mLastFocusY = focusY;
@@ -659,6 +696,7 @@
                         mAlwaysInBiggerTapRegion = false;
                     }
                 } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) {
+                    recordGestureClassification(TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL);
                     handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY);
                     mLastFocusX = focusX;
                     mLastFocusY = focusY;
@@ -667,7 +705,11 @@
                         motionClassification == MotionEvent.CLASSIFICATION_DEEP_PRESS;
                 if (deepPress && hasPendingLongPress) {
                     mHandler.removeMessages(LONG_PRESS);
-                    mHandler.sendEmptyMessage(LONG_PRESS);
+                    mHandler.sendMessage(
+                            mHandler.obtainMessage(
+                                  LONG_PRESS,
+                                  TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS,
+                                  0 /* arg2 */));
                 }
                 break;
 
@@ -676,11 +718,15 @@
                 MotionEvent currentUpEvent = MotionEvent.obtain(ev);
                 if (mIsDoubleTapping) {
                     // Finally, give the up event of the double-tap
+                    recordGestureClassification(
+                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP);
                     handled |= mDoubleTapListener.onDoubleTapEvent(ev);
                 } else if (mInLongPress) {
                     mHandler.removeMessages(TAP);
                     mInLongPress = false;
                 } else if (mAlwaysInTapRegion && !mIgnoreNextUpEvent) {
+                    recordGestureClassification(
+                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP);
                     handled = mListener.onSingleTapUp(ev);
                     if (mDeferConfirmSingleTap && mDoubleTapListener != null) {
                         mDoubleTapListener.onSingleTapConfirmed(ev);
@@ -821,4 +867,26 @@
         mInLongPress = true;
         mListener.onLongPress(mCurrentDownEvent);
     }
+
+    private void recordGestureClassification(int classification) {
+        if (mHasRecordedClassification
+                || classification
+                    == TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION) {
+            // Only record the first classification for an event stream.
+            return;
+        }
+        if (mCurrentDownEvent == null || mCurrentMotionEvent == null) {
+            // If the complete event stream wasn't seen, don't record anything.
+            mHasRecordedClassification = true;
+            return;
+        }
+        StatsLog.write(
+                StatsLog.TOUCH_GESTURE_CLASSIFIED,
+                getClass().getName(),
+                classification,
+                (int) (SystemClock.uptimeMillis() - mCurrentMotionEvent.getDownTime()),
+                (float) Math.hypot(mCurrentMotionEvent.getRawX() - mCurrentDownEvent.getRawX(),
+                                   mCurrentMotionEvent.getRawY() - mCurrentDownEvent.getRawY()));
+        mHasRecordedClassification = true;
+    }
 }
diff --git a/telecomm/java/android/telecom/CallIdentification.aidl b/core/java/android/view/IInputMonitorHost.aidl
similarity index 75%
copy from telecomm/java/android/telecom/CallIdentification.aidl
copy to core/java/android/view/IInputMonitorHost.aidl
index 532535c..bde737d 100644
--- a/telecomm/java/android/telecom/CallIdentification.aidl
+++ b/core/java/android/view/IInputMonitorHost.aidl
@@ -1,5 +1,5 @@
-/*
- * Copyright 2018, The Android Open Source Project
+/**
+ * Copyright (c) 2019, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,12 @@
  * limitations under the License.
  */
 
-package android.telecom;
+package android.view;
 
 /**
- * {@hide}
+ * @hide
  */
-parcelable CallIdentification;
+oneway interface IInputMonitorHost {
+    void pilferPointers();
+    void dispose();
+}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 87efb3f..d317df0 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -255,12 +255,11 @@
     void updatePointerIcon(IWindow window);
 
     /**
-     * Update a tap exclude region with a rectangular area identified by provided id in the window.
-     * Touches on this region will not switch focus to this window. Passing an empty rect will
-     * remove the area from the exclude region of this window.
+     * Update a tap exclude region identified by provided id in the window. Touches on this region
+     * will neither be dispatched to this window nor change the focus to this window. Passing an
+     * invalid region will remove the area from the exclude region of this window.
      */
-    void updateTapExcludeRegion(IWindow window, int regionId, int left, int top, int width,
-            int height);
+    void updateTapExcludeRegion(IWindow window, int regionId, in Region region);
 
     /**
      * Called when the client has changed the local insets state, and now the server should reflect
diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java
index af2b992..ecb727c 100644
--- a/core/java/android/view/InputChannel.java
+++ b/core/java/android/view/InputChannel.java
@@ -17,8 +17,8 @@
 package android.view;
 
 import android.annotation.UnsupportedAppUsage;
-import android.os.Parcel;
 import android.os.IBinder;
+import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Slog;
 
@@ -31,9 +31,9 @@
  */
 public final class InputChannel implements Parcelable {
     private static final String TAG = "InputChannel";
-    
+
     private static final boolean DEBUG = false;
-    
+
     @UnsupportedAppUsage
     public static final @android.annotation.NonNull Parcelable.Creator<InputChannel> CREATOR
             = new Parcelable.Creator<InputChannel>() {
@@ -42,12 +42,12 @@
             result.readFromParcel(source);
             return result;
         }
-        
+
         public InputChannel[] newArray(int size) {
             return new InputChannel[size];
         }
     };
-    
+
     @SuppressWarnings("unused")
     @UnsupportedAppUsage
     private long mPtr; // used by native code
@@ -81,7 +81,7 @@
             super.finalize();
         }
     }
-    
+
     /**
      * Creates a new input channel pair.  One channel should be provided to the input
      * dispatcher and the other to the application's input queue.
@@ -100,7 +100,7 @@
         }
         return nativeOpenInputChannelPair(name);
     }
-    
+
     /**
      * Gets the name of the input channel.
      * @return The input channel name.
@@ -118,7 +118,7 @@
     public void dispose() {
         nativeDispose(false);
     }
-    
+
     /**
      * Transfers ownership of the internal state of the input channel to another
      * instance and invalidates this instance.  This is used to pass an input channel
@@ -129,7 +129,7 @@
         if (outParameter == null) {
             throw new IllegalArgumentException("outParameter must not be null");
         }
-        
+
         nativeTransferTo(outParameter);
     }
 
@@ -151,7 +151,7 @@
         if (in == null) {
             throw new IllegalArgumentException("in must not be null");
         }
-        
+
         nativeReadFromParcel(in);
     }
 
@@ -160,7 +160,7 @@
         if (out == null) {
             throw new IllegalArgumentException("out must not be null");
         }
-        
+
         nativeWriteToParcel(out);
 
         if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0) {
diff --git a/media/java/android/media/session/ControllerCallbackLink.aidl b/core/java/android/view/InputMonitor.aidl
similarity index 82%
rename from media/java/android/media/session/ControllerCallbackLink.aidl
rename to core/java/android/view/InputMonitor.aidl
index 8ee8c7d..bdd14fe 100644
--- a/media/java/android/media/session/ControllerCallbackLink.aidl
+++ b/core/java/android/view/InputMonitor.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.media.session;
 
-parcelable ControllerCallbackLink;
+package android.view;
+
+parcelable InputMonitor;
diff --git a/core/java/android/view/InputMonitor.java b/core/java/android/view/InputMonitor.java
new file mode 100644
index 0000000..693f287
--- /dev/null
+++ b/core/java/android/view/InputMonitor.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+
+/**
+ * @hide
+ */
+public final class InputMonitor implements Parcelable {
+    private static final String TAG = "InputMonitor";
+
+    private static final boolean DEBUG = false;
+
+    public static final Parcelable.Creator<InputMonitor> CREATOR =
+            new Parcelable.Creator<InputMonitor>() {
+
+            public InputMonitor createFromParcel(Parcel source) {
+                return new InputMonitor(source);
+            }
+
+            public InputMonitor[] newArray(int size) {
+                return new InputMonitor[size];
+            }
+    };
+
+    @NonNull
+    private final String mName;
+    @NonNull
+    private final InputChannel mChannel;
+    @NonNull
+    private final IInputMonitorHost mHost;
+
+    public InputMonitor(@NonNull String name, @NonNull InputChannel channel,
+            @NonNull IInputMonitorHost host) {
+        mName = name;
+        mChannel = channel;
+        mHost = host;
+    }
+
+    public InputMonitor(Parcel in) {
+        mName = in.readString();
+        mChannel = in.readParcelable(null);
+        mHost = IInputMonitorHost.Stub.asInterface(in.readStrongBinder());
+    }
+
+    /**
+     * Get the {@link InputChannel} corresponding to this InputMonitor
+     */
+    public InputChannel getInputChannel() {
+        return mChannel;
+    }
+
+    /**
+     * Get the name of this channel.
+     */
+    public String getName() {
+        return mName;
+    }
+
+
+    /**
+     * Takes all of the current pointer events streams that are currently being sent to this
+     * monitor and generates appropriate cancellations for the windows that would normally get
+     * them.
+     *
+     * This method should be used with caution as unexpected pilfering can break fundamental user
+     * interactions.
+     */
+    public void pilferPointers() {
+        try {
+            mHost.pilferPointers();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Disposes the input monitor.
+     *
+     * Explicitly release all of the resources this monitor is holding on to (e.g. the
+     * InputChannel). Once this method is called, this monitor and any resources it's provided may
+     * no longer be used.
+     */
+    public void dispose() {
+        mChannel.dispose();
+        try {
+            mHost.dispose();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mName);
+        out.writeParcelable(mChannel, flags);
+        out.writeStrongBinder(mHost.asBinder());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "InputMonitor{mName=" + mName + ", mChannel=" + mChannel + ", mHost=" + mHost + "}";
+    }
+}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 13b0cc0..b76f2a1 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -17,7 +17,10 @@
 package android.view;
 
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
+import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES;
 import static android.view.WindowInsets.Type.SIZE;
+import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
 import static android.view.WindowInsets.Type.indexOf;
 
 import android.annotation.IntDef;
@@ -55,6 +58,12 @@
             TYPE_SIDE_BAR_1,
             TYPE_SIDE_BAR_2,
             TYPE_SIDE_BAR_3,
+            TYPE_TOP_GESTURES,
+            TYPE_BOTTOM_GESTURES,
+            TYPE_LEFT_GESTURES,
+            TYPE_RIGHT_GESTURES,
+            TYPE_TOP_TAPPABLE_ELEMENT,
+            TYPE_BOTTOM_TAPPABLE_ELEMENT,
             TYPE_IME
     })
     public @interface InternalInsetType {}
@@ -73,8 +82,16 @@
     public static final int TYPE_SIDE_BAR_2 = 2;
     public static final int TYPE_SIDE_BAR_3 = 3;
 
+    public static final int TYPE_TOP_GESTURES = 4;
+    public static final int TYPE_BOTTOM_GESTURES = 5;
+    public static final int TYPE_LEFT_GESTURES = 6;
+    public static final int TYPE_RIGHT_GESTURES = 7;
+    public static final int TYPE_TOP_TAPPABLE_ELEMENT = 8;
+    public static final int TYPE_BOTTOM_TAPPABLE_ELEMENT = 9;
+
     /** Input method window. */
-    public static final int TYPE_IME = 4;
+    public static final int TYPE_IME = 10;
+
     static final int LAST_TYPE = TYPE_IME;
 
     // Derived types
@@ -137,17 +154,6 @@
                 && legacyContentInsets != null && legacyStableInsets != null) {
             WindowInsets.assignCompatInsets(typeInsetsMap, legacyContentInsets);
             WindowInsets.assignCompatInsets(typeMaxInsetsMap, legacyStableInsets);
-
-            // TODO: set system gesture insets based on actual system gesture area.
-            typeInsetsMap[Type.indexOf(Type.systemGestures())] = Insets.of(legacyContentInsets);
-            typeInsetsMap[Type.indexOf(Type.mandatorySystemGestures())] =
-                    Insets.of(legacyContentInsets);
-            typeInsetsMap[Type.indexOf(Type.tappableElement())] = Insets.of(legacyContentInsets);
-
-            typeMaxInsetsMap[Type.indexOf(Type.systemGestures())] = Insets.of(legacyStableInsets);
-            typeMaxInsetsMap[Type.indexOf(Type.mandatorySystemGestures())] =
-                    Insets.of(legacyStableInsets);
-            typeMaxInsetsMap[Type.indexOf(Type.tappableElement())] = Insets.of(legacyStableInsets);
         }
         for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
             InsetsSource source = mSources.get(type);
@@ -159,7 +165,9 @@
                     && (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR);
             boolean skipIme = source.getType() == TYPE_IME
                     && (legacySoftInputMode & LayoutParams.SOFT_INPUT_ADJUST_RESIZE) == 0;
-            if (skipSystemBars || skipIme) {
+            boolean skipLegacyTypes = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
+                    && (toPublicType(type) & Type.compatSystemInsets()) != 0;
+            if (skipSystemBars || skipIme || skipLegacyTypes) {
                 typeVisibilityMap[indexOf(toPublicType(type))] = source.isVisible();
                 continue;
             }
@@ -183,7 +191,25 @@
             @Nullable boolean[] typeVisibilityMap) {
         Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility);
 
-        int index = indexOf(toPublicType(source.getType()));
+        int type = toPublicType(source.getType());
+        processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+                insets, type);
+
+        if (type == MANDATORY_SYSTEM_GESTURES) {
+            // Mandatory system gestures are also system gestures.
+            // TODO: find a way to express this more generally. One option would be to define
+            //       Type.systemGestureInsets() as NORMAL | MANDATORY, but then we lose the
+            //       ability to set systemGestureInsets() independently from
+            //       mandatorySystemGestureInsets() in the Builder.
+            processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
+                    insets, SYSTEM_GESTURES);
+        }
+    }
+
+    private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap,
+            @InsetSide @Nullable SparseIntArray typeSideMap,
+            @Nullable boolean[] typeVisibilityMap, Insets insets, int type) {
+        int index = indexOf(type);
         Insets existing = typeInsetsMap[index];
         if (existing == null) {
             typeInsetsMap[index] = insets;
@@ -300,6 +326,15 @@
                 return Type.SIDE_BARS;
             case TYPE_IME:
                 return Type.IME;
+            case TYPE_TOP_GESTURES:
+            case TYPE_BOTTOM_GESTURES:
+                return Type.MANDATORY_SYSTEM_GESTURES;
+            case TYPE_LEFT_GESTURES:
+            case TYPE_RIGHT_GESTURES:
+                return Type.SYSTEM_GESTURES;
+            case TYPE_TOP_TAPPABLE_ELEMENT:
+            case TYPE_BOTTOM_TAPPABLE_ELEMENT:
+                return Type.TAPPABLE_ELEMENT;
             default:
                 throw new IllegalArgumentException("Unknown type: " + type);
         }
@@ -336,10 +371,20 @@
                 return "TYPE_SIDE_BAR_2";
             case TYPE_SIDE_BAR_3:
                 return "TYPE_SIDE_BAR_3";
-            case TYPE_IME:
-                return "TYPE_IME";
+            case TYPE_TOP_GESTURES:
+                return "TYPE_TOP_GESTURES";
+            case TYPE_BOTTOM_GESTURES:
+                return "TYPE_BOTTOM_GESTURES";
+            case TYPE_LEFT_GESTURES:
+                return "TYPE_LEFT_GESTURES";
+            case TYPE_RIGHT_GESTURES:
+                return "TYPE_RIGHT_GESTURES";
+            case TYPE_TOP_TAPPABLE_ELEMENT:
+                return "TYPE_TOP_TAPPABLE_ELEMENT";
+            case TYPE_BOTTOM_TAPPABLE_ELEMENT:
+                return "TYPE_BOTTOM_TAPPABLE_ELEMENT";
             default:
-                return "TYPE_UNKNOWN";
+                return "TYPE_UNKNOWN_" + type;
         }
     }
 
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 35cf129..f9b629c8 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -566,7 +566,7 @@
         String layout = res.getResourceEntryName(resource);
 
         try {
-            Class clazz = mPrecompiledClassLoader.loadClass("" + pkg + ".CompiledView");
+            Class clazz = Class.forName("" + pkg + ".CompiledView", false, mPrecompiledClassLoader);
             Method inflater = clazz.getMethod(layout, Context.class, int.class);
             View view = (View) inflater.invoke(null, mContext, resource);
 
@@ -827,8 +827,8 @@
 
             if (constructor == null) {
                 // Class not found in the cache, see if it's real, and try to add it
-                clazz = mContext.getClassLoader().loadClass(
-                        prefix != null ? (prefix + name) : name).asSubclass(View.class);
+                clazz = Class.forName(prefix != null ? (prefix + name) : name, false,
+                        mContext.getClassLoader()).asSubclass(View.class);
 
                 if (mFilter != null && clazz != null) {
                     boolean allowed = mFilter.onLoadClass(clazz);
@@ -846,8 +846,8 @@
                     Boolean allowedState = mFilterMap.get(name);
                     if (allowedState == null) {
                         // New class -- remember whether it is allowed
-                        clazz = mContext.getClassLoader().loadClass(
-                                prefix != null ? (prefix + name) : name).asSubclass(View.class);
+                        clazz = Class.forName(prefix != null ? (prefix + name) : name, false,
+                                mContext.getClassLoader()).asSubclass(View.class);
 
                         boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
                         mFilterMap.put(name, allowed);
diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java
index a3cd0ba..8b3b10f 100644
--- a/core/java/android/view/MenuInflater.java
+++ b/core/java/android/view/MenuInflater.java
@@ -23,7 +23,7 @@
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
-import android.graphics.PorterDuff;
+import android.graphics.BlendMode;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -308,7 +308,7 @@
         private CharSequence itemTitleCondensed;
         private int itemIconResId;
         private ColorStateList itemIconTintList = null;
-        private PorterDuff.Mode itemIconTintMode = null;
+        private BlendMode mItemIconBlendMode = null;
         private char itemAlphabeticShortcut;
         private int itemAlphabeticModifiers;
         private char itemNumericShortcut;
@@ -401,12 +401,12 @@
             itemTitleCondensed = a.getText(com.android.internal.R.styleable.MenuItem_titleCondensed);
             itemIconResId = a.getResourceId(com.android.internal.R.styleable.MenuItem_icon, 0);
             if (a.hasValue(com.android.internal.R.styleable.MenuItem_iconTintMode)) {
-                itemIconTintMode = Drawable.parseTintMode(a.getInt(
+                mItemIconBlendMode = Drawable.parseBlendMode(a.getInt(
                         com.android.internal.R.styleable.MenuItem_iconTintMode, -1),
-                        itemIconTintMode);
+                        mItemIconBlendMode);
             } else {
                 // Reset to null so that it's not carried over to the next item
-                itemIconTintMode = null;
+                mItemIconBlendMode = null;
             }
             if (a.hasValue(com.android.internal.R.styleable.MenuItem_iconTint)) {
                 itemIconTintList = a.getColorStateList(
@@ -487,8 +487,8 @@
                 item.setShowAsAction(itemShowAsAction);
             }
 
-            if (itemIconTintMode != null) {
-                item.setIconTintMode(itemIconTintMode);
+            if (mItemIconBlendMode != null) {
+                item.setIconTintMode(mItemIconBlendMode);
             }
 
             if (itemIconTintList != null) {
diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java
index ad160cb..3785310 100644
--- a/core/java/android/view/MenuItem.java
+++ b/core/java/android/view/MenuItem.java
@@ -18,11 +18,13 @@
 
 import android.annotation.DrawableRes;
 import android.annotation.LayoutRes;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.app.Activity;
 import android.content.Intent;
 import android.content.res.ColorStateList;
+import android.graphics.BlendMode;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.view.ContextMenu.ContextMenuInfo;
@@ -268,8 +270,33 @@
      * @attr ref android.R.styleable#MenuItem_iconTintMode
      * @see #setIconTintList(ColorStateList)
      * @see Drawable#setTintMode(PorterDuff.Mode)
+     * @see Drawable#setTintMode(BlendMode)
+     *
+     * @deprecated use {@link #setIconTintMode(BlendMode)} instead
      */
-    public default MenuItem setIconTintMode(@Nullable PorterDuff.Mode tintMode) { return this; }
+    @Deprecated
+    default @NonNull MenuItem setIconTintMode(@Nullable PorterDuff.Mode tintMode) {
+        return this;
+    }
+
+    /**
+     * Specifies the blending mode used to apply the tint specified by
+     * {@link #setIconTintList(ColorStateList)} to this item's icon. The default mode is
+     * {@link BlendMode#SRC_IN}.
+     *
+     * @param blendMode the blending mode used to apply the tint, may be
+     *                 {@code null} to clear tint
+     * @attr ref android.R.styleable#MenuItem_iconTintMode
+     * @see #setIconTintList(ColorStateList)
+     */
+    default @NonNull MenuItem setIconTintMode(@Nullable BlendMode blendMode) {
+        PorterDuff.Mode mode = BlendMode.blendModeToPorterDuffMode(blendMode);
+        if (mode != null) {
+            return setIconTintMode(mode);
+        } else {
+            return this;
+        }
+    }
 
     /**
      * Returns the blending mode used to apply the tint to this item's icon, if specified.
@@ -277,9 +304,31 @@
      * @return the blending mode used to apply the tint to this item's icon
      * @attr ref android.R.styleable#MenuItem_iconTintMode
      * @see #setIconTintMode(PorterDuff.Mode)
+     * @see #setIconTintMode(BlendMode)
+     *
+     * @deprecated Use {@link #getIconTintBlendMode()} instead
      */
+    @Deprecated
     @Nullable
     public default PorterDuff.Mode getIconTintMode() { return null; }
+
+    /**
+     * Returns the blending mode used to apply the tint to this item's icon, if specified.
+     *
+     * @return the blending mode used to apply the tint to this item's icon
+     * @attr ref android.R.styleable#MenuItem_iconTintMode
+     * @see #setIconTintMode(BlendMode)
+     *
+     */
+    @Nullable
+    default BlendMode getIconTintBlendMode() {
+        PorterDuff.Mode mode = getIconTintMode();
+        if (mode != null) {
+            return BlendMode.fromValue(mode.nativeInt);
+        } else {
+            return null;
+        }
+    }
     
     /**
      * Change the Intent associated with this item.  By default there is no
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 0043d32..e3b0b7a 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -978,17 +978,6 @@
         }
     }
 
-    private static void closeTransaction(boolean sync) {
-        synchronized(SurfaceControl.class) {
-            if (sTransactionNestCount == 0) {
-                Log.e(TAG, "Call to SurfaceControl.closeTransaction without matching openTransaction");
-            } else if (--sTransactionNestCount > 0) {
-                return;
-            }
-            sGlobalTransaction.apply(sync);
-        }
-    }
-
     /**
      * Merge the supplied transaction in to the deprecated "global" transaction.
      * This clears the supplied transaction in an identical fashion to {@link Transaction#merge}.
@@ -1003,19 +992,20 @@
         }
     }
 
-    /** end a transaction 
-     * @hide 
+    /** end a transaction
+     * @hide
      */
     @UnsupportedAppUsage
     public static void closeTransaction() {
-        closeTransaction(false);
-    }
-
-    /**
-     * @hide
-     */
-    public static void closeTransactionSync() {
-        closeTransaction(true);
+        synchronized(SurfaceControl.class) {
+            if (sTransactionNestCount == 0) {
+                Log.e(TAG,
+                        "Call to SurfaceControl.closeTransaction without matching openTransaction");
+            } else if (--sTransactionNestCount > 0) {
+                return;
+            }
+            sGlobalTransaction.apply();
+        }
     }
 
     /**
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index e931448..8070e76 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -491,7 +491,7 @@
         if (mBackgroundControl == null) {
             return;
         }
-        if ((mSubLayer > 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) {
+        if ((mSubLayer < 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) {
             mBackgroundControl.show();
             mBackgroundControl.setLayer(Integer.MIN_VALUE);
         } else {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2357db4..65fe87f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17,6 +17,10 @@
 package android.view;
 
 import static android.content.res.Resources.ID_NULL;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP;
+import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED;
 
@@ -50,6 +54,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
+import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Insets;
@@ -85,7 +90,6 @@
 import android.sysprop.DisplayProperties;
 import android.text.InputType;
 import android.text.TextUtils;
-import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.LayoutDirection;
@@ -96,6 +100,7 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.StateSet;
+import android.util.StatsLog;
 import android.util.SuperNotCalledException;
 import android.util.TypedValue;
 import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
@@ -4062,11 +4067,11 @@
     }, formatToHexString = true)
 
     /* @hide */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769414)
     public int mPrivateFlags;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768943)
     int mPrivateFlags2;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 129147060)
     int mPrivateFlags3;
 
     private int mPrivateFlags4;
@@ -4506,7 +4511,7 @@
 
     static class TintInfo {
         ColorStateList mTintList;
-        PorterDuff.Mode mTintMode;
+        BlendMode mBlendMode;
         boolean mHasTintMode;
         boolean mHasTintList;
     }
@@ -5687,7 +5692,7 @@
                     if (mBackgroundTint == null) {
                         mBackgroundTint = new TintInfo();
                     }
-                    mBackgroundTint.mTintMode = Drawable.parseTintMode(a.getInt(
+                    mBackgroundTint.mBlendMode = Drawable.parseBlendMode(a.getInt(
                             R.styleable.View_backgroundTintMode, -1), null);
                     mBackgroundTint.mHasTintMode = true;
                     break;
@@ -5707,7 +5712,7 @@
                     break;
                 case R.styleable.View_foregroundTintMode:
                     if (targetSdkVersion >= Build.VERSION_CODES.M || this instanceof FrameLayout) {
-                        setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null));
+                        setForegroundTintMode(Drawable.parseBlendMode(a.getInt(attr, -1), null));
                     }
                     break;
                 case R.styleable.View_foregroundTint:
@@ -7955,6 +7960,8 @@
      *                               View is not a pane.
      *
      * {@see AccessibilityNodeInfo#setPaneTitle(CharSequence)}
+     *
+     * @attr ref android.R.styleable#View_accessibilityPaneTitle
      */
     public void setAccessibilityPaneTitle(@Nullable CharSequence accessibilityPaneTitle) {
         if (!TextUtils.equals(accessibilityPaneTitle, mAccessibilityPaneTitle)) {
@@ -7970,6 +7977,8 @@
      * @return The current pane title.
      *
      * {@see #setAccessibilityPaneTitle}.
+     *
+     * @attr ref android.R.styleable#View_accessibilityPaneTitle
      */
     @InspectableProperty
     @Nullable
@@ -8524,11 +8533,11 @@
     }
 
     /**
-     * Populates a {@link ViewStructure} for Content Capture.
+     * Populates a {@link ViewStructure} for content capture.
      *
-     * <p>This method is called after a view is that is eligible for Content Capture
+     * <p>This method is called after a view is that is eligible for content capture
      * (for example, if it {@link #isImportantForAutofill()}, an intelligence service is enabled for
-     * the user, and the activity rendering the view is enabled for Content Capture) is laid out and
+     * the user, and the activity rendering the view is enabled for content capture) is laid out and
      * is visible.
      *
      * <p>The populated structure is then passed to the service through
@@ -8547,6 +8556,16 @@
      * {@code childStructure.getAutofillId()} or
      * {@link ContentCaptureSession#newAutofillId(AutofillId, long)}.
      *
+     * <p>When the virtual view hierarchy represents a web page, you should also:
+     *
+     * <ul>
+     *   <li>Call {@link ContentCaptureManager#getContentCaptureConditions()} to infer content
+     *   capture events should be generate for that URL.
+     *   <li>Create a new {@link ContentCaptureSession} child for every HTML element that
+     *   renders a new URL (like an {@code IFRAME}) and use that session to notify events from
+     *   that subtree.
+     * </ul>
+     *
      * <p><b>Note: </b>the following methods of the {@code structure} will be ignored:
      * <ul>
      *   <li>{@link ViewStructure#setChildCount(int)}
@@ -9263,11 +9282,13 @@
     }
 
     /**
-     * Hints the Android System whether this view is considered important for Content Capture, based
+     * Hints the Android System whether this view is considered important for content capture, based
      * on the value explicitly set by {@link #setImportantForContentCapture(int)} and heuristics
      * when it's {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO}.
      *
-     * @return whether the view is considered important for autofill.
+     * <p>See {@link ContentCaptureManager} for more info about content capture.
+     *
+     * @return whether the view is considered important for content capture.
      *
      * @see #setImportantForContentCapture(int)
      * @see #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO
@@ -9466,7 +9487,7 @@
      * Sets the (optional) {@link ContentCaptureSession} associated with this view.
      *
      * <p>This method should be called when you need to associate a {@link ContentCaptureContext} to
-     * the Content Capture events associated with this view or its view hierarchy (if it's a
+     * the content capture events associated with this view or its view hierarchy (if it's a
      * {@link ViewGroup}).
      *
      * <p>For example, if your activity is associated with a web domain, first you would need to
@@ -9497,7 +9518,7 @@
     }
 
     /**
-     * Gets the session used to notify Content Capture events.
+     * Gets the session used to notify content capture events.
      *
      * @return session explicitly set by {@link #setContentCaptureSession(ContentCaptureSession)},
      * inherited by ancestors, default session or {@code null} if content capture is disabled for
@@ -9718,7 +9739,7 @@
     }
 
     /**
-     * Dispatches the initial Content Capture events for a view structure.
+     * Dispatches the initial content capture events for a view structure.
      *
      * @hide
      */
@@ -12100,6 +12121,8 @@
      * @see #setScreenReaderFocusable(boolean)
      *
      * @return Whether the view should be treated as a focusable unit by screen reader.
+     *
+     * @attr ref android.R.styleable#View_screenReaderFocusable
      */
     @InspectableProperty
     public boolean isScreenReaderFocusable() {
@@ -12118,6 +12141,8 @@
      *
      * @param screenReaderFocusable Whether the view should be treated as a unit by screen reader
      *                              accessibility tools.
+     *
+     * @attr ref android.R.styleable#View_screenReaderFocusable
      */
     public void setScreenReaderFocusable(boolean screenReaderFocusable) {
         updatePflags3AndNotifyA11yIfChanged(PFLAG3_SCREEN_READER_FOCUSABLE, screenReaderFocusable);
@@ -13899,6 +13924,16 @@
     }
 
     /**
+     * Returns whether this view can receive pointer events.
+     *
+     * @return {@code true} if this view can receive pointer events.
+     * @hide
+     */
+    protected boolean canReceivePointerEvents() {
+        return (mViewFlags & VISIBILITY_MASK) == VISIBLE || getAnimation() != null;
+    }
+
+    /**
      * Filter the touch event to apply security policies.
      *
      * @param event The motion event to be filtered.
@@ -14541,7 +14576,12 @@
                     if (clickable) {
                         setPressed(true, x, y);
                     }
-                    checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y);
+                    checkForLongClick(
+                            ViewConfiguration.getLongPressTimeout(),
+                            x,
+                            y,
+                            // This is not a touch gesture -- do not classify it as one.
+                            TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION);
                     return true;
                 }
             }
@@ -15282,7 +15322,11 @@
                     mHasPerformedLongPress = false;
 
                     if (!clickable) {
-                        checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y);
+                        checkForLongClick(
+                                ViewConfiguration.getLongPressTimeout(),
+                                x,
+                                y,
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
                         break;
                     }
 
@@ -15306,7 +15350,11 @@
                     } else {
                         // Not inside a scrolling container, so show the feedback right away
                         setPressed(true, x, y);
-                        checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y);
+                        checkForLongClick(
+                                ViewConfiguration.getLongPressTimeout(),
+                                x,
+                                y,
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
                     }
                     break;
 
@@ -15343,7 +15391,11 @@
                                     * ambiguousMultiplier);
                             // Subtract the time already spent
                             delay -= event.getEventTime() - event.getDownTime();
-                            checkForLongClick(delay, x, y);
+                            checkForLongClick(
+                                    delay,
+                                    x,
+                                    y,
+                                    TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
                         }
                         touchSlop *= ambiguousMultiplier;
                     }
@@ -15365,7 +15417,11 @@
                     if (deepPress && hasPendingLongPressCallback()) {
                         // process the long click action immediately
                         removeLongPressCallback();
-                        checkForLongClick(0 /* send immediately */, x, y);
+                        checkForLongClick(
+                                0 /* send immediately */,
+                                x,
+                                y,
+                                TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS);
                     }
 
                     break;
@@ -17938,7 +17994,7 @@
         final int scrollX = mScrollX;
         final int scrollY = mScrollY;
         invalidateInternal(dirty.left - scrollX, dirty.top - scrollY,
-                dirty.right - scrollX, dirty.bottom - scrollY, true, false);
+                dirty.right - scrollX, dirty.bottom - scrollY, true);
     }
 
     /**
@@ -17964,7 +18020,7 @@
     public void invalidate(int l, int t, int r, int b) {
         final int scrollX = mScrollX;
         final int scrollY = mScrollY;
-        invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
+        invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true);
     }
 
     /**
@@ -17994,11 +18050,10 @@
      */
     @UnsupportedAppUsage
     public void invalidate(boolean invalidateCache) {
-        invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
+        invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache);
     }
 
-    void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
-            boolean fullInvalidate) {
+    void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache) {
         if (mGhostView != null) {
             mGhostView.invalidate(true);
             return;
@@ -18015,11 +18070,9 @@
         if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
                 || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)
                 || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED
-                || (fullInvalidate && isOpaque() != mLastIsOpaque)) {
-            if (fullInvalidate) {
-                mLastIsOpaque = isOpaque();
-                mPrivateFlags &= ~PFLAG_DRAWN;
-            }
+                || isOpaque() != mLastIsOpaque) {
+            mLastIsOpaque = isOpaque();
+            mPrivateFlags &= ~PFLAG_DRAWN;
 
             mPrivateFlags |= PFLAG_DIRTY;
 
@@ -22564,12 +22617,7 @@
     @Override
     public void invalidateDrawable(@NonNull Drawable drawable) {
         if (verifyDrawable(drawable)) {
-            final Rect dirty = drawable.getDirtyBounds();
-            final int scrollX = mScrollX;
-            final int scrollY = mScrollY;
-
-            invalidate(dirty.left + scrollX, dirty.top + scrollY,
-                    dirty.right + scrollX, dirty.bottom + scrollY);
+            invalidate();
             rebuildOutline();
         }
     }
@@ -23266,7 +23314,7 @@
 
     /**
      * Applies a tint to the background drawable. Does not modify the current tint
-     * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+     * mode, which is {@link BlendMode#SRC_IN} by default.
      * <p>
      * Subsequent calls to {@link #setBackground(Drawable)} will automatically
      * mutate the drawable and apply the specified tint and tint mode using
@@ -23311,12 +23359,36 @@
      * @attr ref android.R.styleable#View_backgroundTintMode
      * @see #getBackgroundTintMode()
      * @see Drawable#setTintMode(PorterDuff.Mode)
+     *
+     * @deprecated use @setBackgroundTintMode(BlendMode) instead
      */
+    @Deprecated
     public void setBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
+        BlendMode mode = null;
+        if (tintMode != null) {
+            mode = BlendMode.fromValue(tintMode.nativeInt);
+        }
+
+        setBackgroundTintMode(mode);
+    }
+
+    /**
+     * Specifies the blending mode used to apply the tint specified by
+     * {@link #setBackgroundTintList(ColorStateList)}} to the background
+     * drawable. The default mode is {@link BlendMode#SRC_IN}.
+     *
+     * @param blendMode the blending mode used to apply the tint, may be
+     *                 {@code null} to clear tint
+     * @attr ref android.R.styleable#View_backgroundTintMode
+     * @see #getBackgroundTintMode()
+     * @see Drawable#setTintMode(BlendMode)
+     */
+    public void setBackgroundTintMode(@Nullable BlendMode blendMode) {
         if (mBackgroundTint == null) {
             mBackgroundTint = new TintInfo();
         }
-        mBackgroundTint.mTintMode = tintMode;
+
+        mBackgroundTint.mBlendMode = blendMode;
         mBackgroundTint.mHasTintMode = true;
 
         applyBackgroundTint();
@@ -23329,12 +23401,34 @@
      * @return the blending mode used to apply the tint to the background
      *         drawable
      * @attr ref android.R.styleable#View_backgroundTintMode
-     * @see #setBackgroundTintMode(PorterDuff.Mode)
+     * @see #setBackgroundTintMode(BlendMode)
+     *
+     * @deprecated use #getBackgroundBlendMode() instead
      */
     @Nullable
     @InspectableProperty
+    @Deprecated
     public PorterDuff.Mode getBackgroundTintMode() {
-        return mBackgroundTint != null ? mBackgroundTint.mTintMode : null;
+        PorterDuff.Mode porterDuffMode;
+        if (mBackgroundTint != null && mBackgroundTint.mBlendMode != null) {
+            porterDuffMode = BlendMode.blendModeToPorterDuffMode(mBackgroundTint.mBlendMode);
+        } else {
+            porterDuffMode = null;
+        }
+        return porterDuffMode;
+    }
+
+    /**
+     * Return the blending mode used to apply the tint to the background
+     * drawable, if specified.
+     *
+     * @return the blending mode used to apply the tint to the background
+     *         drawable, null if no blend has previously been configured
+     * @attr ref android.R.styleable#View_backgroundTintMode
+     * @see #setBackgroundTintMode(BlendMode)
+     */
+    public @Nullable BlendMode getBackgroundBlendMode() {
+        return mBackgroundTint != null ? mBackgroundTint.mBlendMode : null;
     }
 
     private void applyBackgroundTint() {
@@ -23348,7 +23442,7 @@
                 }
 
                 if (tintInfo.mHasTintMode) {
-                    mBackground.setTintMode(tintInfo.mTintMode);
+                    mBackground.setTintMode(tintInfo.mBlendMode);
                 }
 
                 // The drawable (or one of its children) may not have been
@@ -23532,15 +23626,37 @@
      * @attr ref android.R.styleable#View_foregroundTintMode
      * @see #getForegroundTintMode()
      * @see Drawable#setTintMode(PorterDuff.Mode)
+     *
+     * @deprecated use #setForegroundTintMode(BlendMode)
      */
+    @Deprecated
     public void setForegroundTintMode(@Nullable PorterDuff.Mode tintMode) {
+        BlendMode mode = null;
+        if (tintMode != null) {
+            mode = BlendMode.fromValue(tintMode.nativeInt);
+        }
+        setForegroundTintMode(mode);
+    }
+
+    /**
+     * Specifies the blending mode used to apply the tint specified by
+     * {@link #setForegroundTintList(ColorStateList)}} to the background
+     * drawable. The default mode is {@link BlendMode#SRC_IN}.
+     *
+     * @param blendMode the blending mode used to apply the tint, may be
+     *                 {@code null} to clear tint
+     * @attr ref android.R.styleable#View_foregroundTintMode
+     * @see #getForegroundTintMode()
+     * @see Drawable#setTintMode(BlendMode)
+     */
+    public void setForegroundTintMode(@Nullable BlendMode blendMode) {
         if (mForegroundInfo == null) {
             mForegroundInfo = new ForegroundInfo();
         }
         if (mForegroundInfo.mTintInfo == null) {
             mForegroundInfo.mTintInfo = new TintInfo();
         }
-        mForegroundInfo.mTintInfo.mTintMode = tintMode;
+        mForegroundInfo.mTintInfo.mBlendMode = blendMode;
         mForegroundInfo.mTintInfo.mHasTintMode = true;
 
         applyForegroundTint();
@@ -23554,12 +23670,35 @@
      *         drawable
      * @attr ref android.R.styleable#View_foregroundTintMode
      * @see #setForegroundTintMode(PorterDuff.Mode)
+     *
+     * @deprecated use #getForegroundBlendMode() instead
      */
     @InspectableProperty
     @Nullable
+    @Deprecated
     public PorterDuff.Mode getForegroundTintMode() {
+        BlendMode blendMode = mForegroundInfo != null && mForegroundInfo.mTintInfo != null
+                ? mForegroundInfo.mTintInfo.mBlendMode : null;
+        if (blendMode != null) {
+            return BlendMode.blendModeToPorterDuffMode(blendMode);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Return the blending mode used to apply the tint to the foreground
+     * drawable, if specified.
+     *
+     * @return the blending mode used to apply the tint to the foreground
+     *         drawable
+     * @attr ref android.R.styleable#View_foregroundTintMode
+     * @see #setForegroundTintMode(BlendMode)
+     *
+     */
+    public @Nullable BlendMode getForegroundBlendMode() {
         return mForegroundInfo != null && mForegroundInfo.mTintInfo != null
-                ? mForegroundInfo.mTintInfo.mTintMode : null;
+                ? mForegroundInfo.mTintInfo.mBlendMode : null;
     }
 
     private void applyForegroundTint() {
@@ -23574,7 +23713,7 @@
                 }
 
                 if (tintInfo.mHasTintMode) {
-                    mForegroundInfo.mDrawable.setTintMode(tintInfo.mTintMode);
+                    mForegroundInfo.mDrawable.setTintMode(tintInfo.mBlendMode);
                 }
 
                 // The drawable (or one of its children) may not have been
@@ -26030,7 +26169,7 @@
         }
     }
 
-    private void checkForLongClick(long delay, float x, float y) {
+    private void checkForLongClick(long delay, float x, float y, int classification) {
         if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE || (mViewFlags & TOOLTIP) == TOOLTIP) {
             mHasPerformedLongPress = false;
 
@@ -26040,6 +26179,7 @@
             mPendingCheckForLongPress.setAnchor(x, y);
             mPendingCheckForLongPress.rememberWindowAttachCount();
             mPendingCheckForLongPress.rememberPressedState();
+            mPendingCheckForLongPress.setClassification(classification);
             postDelayed(mPendingCheckForLongPress, delay);
         }
     }
@@ -27597,11 +27737,17 @@
         private float mX;
         private float mY;
         private boolean mOriginalPressedState;
+        /**
+         * The classification of the long click being checked: one of the
+         * StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__* constants.
+         */
+        private int mClassification;
 
         @Override
         public void run() {
             if ((mOriginalPressedState == isPressed()) && (mParent != null)
                     && mOriginalWindowAttachCount == mWindowAttachCount) {
+                recordGestureClassification(mClassification);
                 if (performLongClick(mX, mY)) {
                     mHasPerformedLongPress = true;
                 }
@@ -27620,6 +27766,10 @@
         public void rememberPressedState() {
             mOriginalPressedState = isPressed();
         }
+
+        public void setClassification(int classification) {
+            mClassification = classification;
+        }
     }
 
     private final class CheckForTap implements Runnable {
@@ -27632,17 +27782,28 @@
             setPressed(true, x, y);
             final long delay =
                     ViewConfiguration.getLongPressTimeout() - ViewConfiguration.getTapTimeout();
-            checkForLongClick(delay, x, y);
+            checkForLongClick(delay, x, y, TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS);
         }
     }
 
     private final class PerformClick implements Runnable {
         @Override
         public void run() {
+            recordGestureClassification(TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP);
             performClickInternal();
         }
     }
 
+    /** Records a classification for the current event stream. */
+    private void recordGestureClassification(int classification) {
+        if (classification == TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION) {
+            return;
+        }
+        // To avoid negatively impacting View performance, the latency and displacement metrics
+        // are omitted.
+        StatsLog.write(StatsLog.TOUCH_GESTURE_CLASSIFIED, getClass().getName(), classification);
+    }
+
     /**
      * This method returns a ViewPropertyAnimator object, which can be used to animate
      * specific properties on this View.
@@ -28486,8 +28647,7 @@
          * hierarchy is traversed: value is either the view itself for appearead events, or its
          * autofill id for disappeared.
          */
-        // TODO(b/121197119): use SparseArray once session id becomes integer
-        ArrayMap<String, ArrayList<Object>> mContentCaptureEvents;
+        SparseArray<ArrayList<Object>> mContentCaptureEvents;
 
         /**
          * Cached reference to the {@link ContentCaptureManager}.
@@ -28517,9 +28677,9 @@
                 @NonNull View view, boolean appeared) {
             if (mContentCaptureEvents == null) {
                 // Most of the time there will be just one session, so intial capacity is 1
-                mContentCaptureEvents = new ArrayMap<>(1);
+                mContentCaptureEvents = new SparseArray<>(1);
             }
-            String sessionId = session.getId();
+            int sessionId = session.getId();
             // TODO: life would be much easier if we provided a MultiMap implementation somwhere...
             ArrayList<Object> events = mContentCaptureEvents.get(sessionId);
             if (events == null) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 4851476..937bd1b 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2011,7 +2011,7 @@
             for (int i = childrenCount - 1; i >= 0; i--) {
                 final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
                 final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
-                if (!canViewReceivePointerEvents(child)
+                if (!child.canReceivePointerEvents()
                         || !isTransformedTouchPointInView(x, y, child, null)) {
                     continue;
                 }
@@ -2094,7 +2094,7 @@
                             childrenCount, i, customOrder);
                     final View child = getAndVerifyPreorderedView(
                             preorderedList, children, childIndex);
-                    if (!canViewReceivePointerEvents(child)
+                    if (!child.canReceivePointerEvents()
                             || !isTransformedTouchPointInView(x, y, child, null)) {
                         continue;
                     }
@@ -2314,7 +2314,7 @@
                                 getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
                         final View child =
                                 getAndVerifyPreorderedView(preorderedList, children, childIndex);
-                        if (!canViewReceivePointerEvents(child)
+                        if (!child.canReceivePointerEvents()
                                 || !isTransformedTouchPointInView(x, y, child, null)) {
                             continue;
                         }
@@ -2500,7 +2500,7 @@
             for (int i = childrenCount - 1; i >= 0; i--) {
                 final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
                 final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
-                if (!canViewReceivePointerEvents(child)
+                if (!child.canReceivePointerEvents()
                         || !isTransformedTouchPointInView(x, y, child, null)) {
                     continue;
                 }
@@ -2680,7 +2680,7 @@
                                 i = childrenCount - 1;
                             }
 
-                            if (!canViewReceivePointerEvents(child)
+                            if (!child.canReceivePointerEvents()
                                     || !isTransformedTouchPointInView(x, y, child, null)) {
                                 ev.setTargetAccessibilityFocus(false);
                                 continue;
@@ -2970,15 +2970,6 @@
         }
     }
 
-    /**
-     * Returns true if a child view can receive pointer events.
-     * @hide
-     */
-    private static boolean canViewReceivePointerEvents(@NonNull View child) {
-        return (child.mViewFlags & VISIBILITY_MASK) == VISIBLE
-                || child.getAnimation() != null;
-    }
-
     private float[] getTempPoint() {
         if (mTempPoint == null) {
             mTempPoint = new float[2];
@@ -7199,6 +7190,46 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public void subtractObscuredTouchableRegion(Region touchableRegion, View view) {
+        final int childrenCount = mChildrenCount;
+        final ArrayList<View> preorderedList = buildTouchDispatchChildList();
+        final boolean customOrder = preorderedList == null && isChildrenDrawingOrderEnabled();
+        final View[] children = mChildren;
+        for (int i = childrenCount - 1; i >= 0; i--) {
+            final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+            final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
+            if (child == view) {
+                // We've reached the target view.
+                break;
+            }
+            if (!child.canReceivePointerEvents()) {
+                // This child cannot be touched. Skip it.
+                continue;
+            }
+            applyOpToRegionByBounds(touchableRegion, child, Region.Op.DIFFERENCE);
+        }
+
+        // The touchable region should not exceed the bounds of its container.
+        applyOpToRegionByBounds(touchableRegion, this, Region.Op.INTERSECT);
+
+        final ViewParent parent = getParent();
+        if (parent != null) {
+            parent.subtractObscuredTouchableRegion(touchableRegion, this);
+        }
+    }
+
+    private static void applyOpToRegionByBounds(Region region, View view, Region.Op op) {
+        final int[] locationInWindow = new int[2];
+        view.getLocationInWindow(locationInWindow);
+        final int x = locationInWindow[0];
+        final int y = locationInWindow[1];
+        region.op(x, y, x + view.getWidth(), y + view.getHeight(), op);
+    }
+
     @Override
     public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
         insets = super.dispatchApplyWindowInsets(insets);
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 572e69b..feba7bb 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Bundle;
 import android.view.accessibility.AccessibilityEvent;
 
@@ -660,4 +661,17 @@
      * @return true if the action was consumed by this ViewParent
      */
     public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle arguments);
+
+    /**
+     * Given a touchable region of a child, this method reduces region by the bounds of all views on
+     * top of the child for which {@link View#canReceivePointerEvents} returns {@code true}. This
+     * applies recursively for all views in the view hierarchy on top of this one.
+     *
+     * @param touchableRegion The touchable region we want to modify.
+     * @param view A child view of this ViewGroup which indicates the z-order of the touchable
+     *             region.
+     * @hide
+     */
+    default void subtractObscuredTouchableRegion(Region touchableRegion, View view) {
+    }
 }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2880e7f..f3b7ad5 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1455,6 +1455,8 @@
 
     @Override
     public void onDescendantInvalidated(@NonNull View child, @NonNull View descendant) {
+        // TODO: Re-enable after camera is fixed or consider targetSdk checking this
+        // checkThread();
         if ((descendant.mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) {
             mIsAnimating = true;
         }
@@ -1915,16 +1917,10 @@
             }
             contentInsets = ensureInsetsNonNegative(contentInsets, "content");
             stableInsets = ensureInsetsNonNegative(stableInsets, "stable");
-            if (sNewInsetsMode != NEW_INSETS_MODE_NONE) {
-                mLastWindowInsets = mInsetsController.calculateInsets(
-                        mContext.getResources().getConfiguration().isScreenRound(),
-                        mAttachInfo.mAlwaysConsumeSystemBars, displayCutout,
-                        contentInsets, stableInsets, mWindowAttributes.softInputMode);
-            } else {
-                mLastWindowInsets = new WindowInsets(contentInsets, stableInsets,
-                        mContext.getResources().getConfiguration().isScreenRound(),
-                        mAttachInfo.mAlwaysConsumeSystemBars, displayCutout);
-            }
+            mLastWindowInsets = mInsetsController.calculateInsets(
+                    mContext.getResources().getConfiguration().isScreenRound(),
+                    mAttachInfo.mAlwaysConsumeSystemBars, displayCutout,
+                    contentInsets, stableInsets, mWindowAttributes.softInputMode);
         }
         return mLastWindowInsets;
     }
@@ -1985,7 +1981,6 @@
         mIsInTraversal = true;
         mWillDrawSoon = true;
         boolean windowSizeMayChange = false;
-        boolean newSurface = false;
         boolean surfaceChanged = false;
         WindowManager.LayoutParams lp = mWindowAttributes;
 
@@ -2386,13 +2381,7 @@
                 if (!hadSurface) {
                     if (mSurface.isValid()) {
                         // If we are creating a new surface, then we need to
-                        // completely redraw it.  Also, when we get to the
-                        // point of drawing it we will hold off and schedule
-                        // a new traversal instead.  This is so we can tell the
-                        // window manager about all of the windows being displayed
-                        // before actually drawing them, so it can display then
-                        // all at once.
-                        newSurface = true;
+                        // completely redraw it.
                         mFullRedrawNeeded = true;
                         mPreviousTransparentRegion.setEmpty();
 
@@ -2777,7 +2766,7 @@
 
         boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
 
-        if (!cancelDraw && !newSurface) {
+        if (!cancelDraw) {
             if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
                 for (int i = 0; i < mPendingTransitions.size(); ++i) {
                     mPendingTransitions.get(i).startChangingAnimations();
@@ -2811,8 +2800,7 @@
             MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager
                     .getMainContentCaptureSession();
             for (int i = 0; i < mAttachInfo.mContentCaptureEvents.size(); i++) {
-                String sessionId = mAttachInfo.mContentCaptureEvents
-                        .keyAt(i);
+                int sessionId = mAttachInfo.mContentCaptureEvents.keyAt(i);
                 mainSession.notifyViewTreeEvent(sessionId, /* started= */ true);
                 ArrayList<Object> events = mAttachInfo.mContentCaptureEvents
                         .valueAt(i);
@@ -2827,8 +2815,8 @@
                             Log.w(mTag, "no content capture session on view: " + view);
                             continue for_each_event;
                         }
-                        String actualId = session.getId().toString();
-                        if (!actualId.equals(sessionId)) {
+                        int actualId = session.getId();
+                        if (actualId != sessionId) {
                             Log.w(mTag, "content capture session mismatch for view (" + view
                                     + "): was " + sessionId + " before, it's " + actualId + " now");
                             continue for_each_event;
@@ -3986,7 +3974,7 @@
 
     void systemGestureExclusionChanged() {
         final List<Rect> rectsForWindowManager = mGestureExclusionTracker.computeChangedRects();
-        if (rectsForWindowManager != null) {
+        if (rectsForWindowManager != null && mView != null) {
             try {
                 mWindowSession.reportSystemGestureExclusionChanged(mWindow, rectsForWindowManager);
             } catch (RemoteException e) {
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index ffa769a..2d292ef 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -29,9 +29,6 @@
 import static android.view.WindowInsets.Type.all;
 import static android.view.WindowInsets.Type.compatSystemInsets;
 import static android.view.WindowInsets.Type.indexOf;
-import static android.view.WindowInsets.Type.mandatorySystemGestures;
-import static android.view.WindowInsets.Type.systemGestures;
-import static android.view.WindowInsets.Type.tappableElement;
 
 import android.annotation.IntDef;
 import android.annotation.IntRange;
@@ -225,10 +222,6 @@
         }
         Insets[] typeInsetMap = new Insets[SIZE];
         assignCompatInsets(typeInsetMap, insets);
-        // TODO: set system gesture insets based on actual system gesture area.
-        typeInsetMap[indexOf(systemGestures())] = Insets.of(insets);
-        typeInsetMap[indexOf(mandatorySystemGestures())] = Insets.of(insets);
-        typeInsetMap[indexOf(tappableElement())] = Insets.of(insets);
         return typeInsetMap;
     }
 
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index df8690d..f9e601f 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -105,11 +105,7 @@
                 Log.i(LOG_TAG, "Caching window: " + window.getId());
             }
             final int windowId = window.getId();
-            AccessibilityWindowInfo oldWindow = mWindowCache.get(windowId);
-            if (oldWindow != null) {
-                oldWindow.recycle();
-            }
-            mWindowCache.put(windowId, AccessibilityWindowInfo.obtain(window));
+            mWindowCache.put(windowId, new AccessibilityWindowInfo(window));
         }
     }
 
@@ -225,7 +221,7 @@
             if (info != null) {
                 // Return a copy since the client calls to AccessibilityNodeInfo#recycle()
                 // will wipe the data of the cached info.
-                info = AccessibilityNodeInfo.obtain(info);
+                info = new AccessibilityNodeInfo(info);
             }
             if (DEBUG) {
                 Log.i(LOG_TAG, "get(" + accessibilityNodeId + ") = " + info);
@@ -257,7 +253,7 @@
                 List<AccessibilityWindowInfo> windows = new ArrayList<>(sortedWindowCount);
                 for (int i = sortedWindowCount - 1; i >= 0; i--) {
                     AccessibilityWindowInfo window = sortedWindows.valueAt(i);
-                    windows.add(AccessibilityWindowInfo.obtain(window));
+                    windows.add(new AccessibilityWindowInfo(window));
                     sortedWindows.removeAt(i);
                 }
 
@@ -271,7 +267,7 @@
         synchronized (mLock) {
             AccessibilityWindowInfo window = mWindowCache.get(windowId);
             if (window != null) {
-               return AccessibilityWindowInfo.obtain(window);
+                return new AccessibilityWindowInfo(window);
             }
             return null;
         }
@@ -326,14 +322,12 @@
                 final long oldParentId = oldInfo.getParentNodeId();
                 if (info.getParentNodeId() != oldParentId) {
                     clearSubTreeLocked(windowId, oldParentId);
-                } else {
-                    oldInfo.recycle();
                 }
            }
 
             // Cache a copy since the client calls to AccessibilityNodeInfo#recycle()
             // will wipe the data of the cached info.
-            AccessibilityNodeInfo clone = AccessibilityNodeInfo.obtain(info);
+            AccessibilityNodeInfo clone = new AccessibilityNodeInfo(info);
             nodes.put(sourceId, clone);
             if (clone.isAccessibilityFocused()) {
                 if (mAccessibilityFocus != AccessibilityNodeInfo.UNDEFINED_ITEM_ID
@@ -371,12 +365,7 @@
     }
 
     private void clearWindowCache() {
-        final int windowCount = mWindowCache.size();
-        for (int i = windowCount - 1; i >= 0; i--) {
-            AccessibilityWindowInfo window = mWindowCache.valueAt(i);
-            window.recycle();
-            mWindowCache.removeAt(i);
-        }
+        mWindowCache.clear();
         mIsAllWindowsCached = false;
     }
 
@@ -391,13 +380,6 @@
         if (nodes == null) {
             return;
         }
-        // Recycle the nodes before clearing the cache.
-        final int nodeCount = nodes.size();
-        for (int i = nodeCount - 1; i >= 0; i--) {
-            AccessibilityNodeInfo info = nodes.valueAt(i);
-            nodes.removeAt(i);
-            info.recycle();
-        }
         mNodeCache.remove(windowId);
     }
 
@@ -440,11 +422,9 @@
         for (int i = 0; i < childCount; i++) {
             final long childNodeId = current.getChildId(i);
             if (clearSubTreeRecursiveLocked(nodes, childNodeId)) {
-                current.recycle();
                 return true;
             }
         }
-        current.recycle();
         return false;
     }
 
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index a8a787e..774a359 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -654,6 +654,7 @@
      */
     private static final int VIRTUAL_DESCENDANT_ID_SHIFT = 32;
 
+    // TODO(b/129300068): Remove sNumInstancesInUse.
     private static AtomicInteger sNumInstancesInUse;
 
     /**
@@ -766,6 +767,11 @@
         /* do nothing */
     }
 
+    /** @hide */
+    AccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        init(info);
+    }
+
     /**
      * Sets the source.
      * <p>
@@ -1676,17 +1682,29 @@
     }
 
     /**
-     * Gets the node bounds in parent coordinates.
+     * Gets the node bounds in the viewParent's coordinates.
+     * {@link #getParent()} does not represent the source's viewParent.
+     * Instead it represents the result of {@link View#getParentForAccessibility()},
+     * which returns the closest ancestor where {@link View#isImportantForAccessibility()} is true.
+     * So this method is not reliable.
      *
      * @param outBounds The output node bounds.
+     * @deprecated Use {@link #getBoundsInScreen(Rect)} instead.
+     *
      */
+    @Deprecated
     public void getBoundsInParent(Rect outBounds) {
         outBounds.set(mBoundsInParent.left, mBoundsInParent.top,
                 mBoundsInParent.right, mBoundsInParent.bottom);
     }
 
     /**
-     * Sets the node bounds in parent coordinates.
+     * Sets the node bounds in the viewParent's coordinates.
+     * {@link #getParent()} does not represent the source's viewParent.
+     * Instead it represents the result of {@link View#getParentForAccessibility()},
+     * which returns the closest ancestor where {@link View#isImportantForAccessibility()} is true.
+     * So this method is not reliable.
+     *
      * <p>
      *   <strong>Note:</strong> Cannot be called from an
      *   {@link android.accessibilityservice.AccessibilityService}.
@@ -1696,7 +1714,9 @@
      * @param bounds The node bounds.
      *
      * @throws IllegalStateException If called from an AccessibilityService.
+     * @deprecated Accessibility services should not care about these bounds.
      */
+    @Deprecated
     public void setBoundsInParent(Rect bounds) {
         enforceNotSealed();
         mBoundsInParent.set(bounds.left, bounds.top, bounds.right, bounds.bottom);
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index 4383f8a..1e2321c 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -96,6 +96,7 @@
     private static final int MAX_POOL_SIZE = 10;
     private static final SynchronizedPool<AccessibilityWindowInfo> sPool =
             new SynchronizedPool<AccessibilityWindowInfo>(MAX_POOL_SIZE);
+    // TODO(b/129300068): Remove sNumInstancesInUse.
     private static AtomicInteger sNumInstancesInUse;
 
     // Data.
@@ -115,6 +116,11 @@
         /* do nothing - hide constructor */
     }
 
+    /** @hide */
+    AccessibilityWindowInfo(AccessibilityWindowInfo info) {
+        init(info);
+    }
+
     /**
      * Gets the title of the window.
      *
@@ -448,26 +454,7 @@
      */
     public static AccessibilityWindowInfo obtain(AccessibilityWindowInfo info) {
         AccessibilityWindowInfo infoClone = obtain();
-
-        infoClone.mType = info.mType;
-        infoClone.mLayer = info.mLayer;
-        infoClone.mBooleanProperties = info.mBooleanProperties;
-        infoClone.mId = info.mId;
-        infoClone.mParentId = info.mParentId;
-        infoClone.mBoundsInScreen.set(info.mBoundsInScreen);
-        infoClone.mTitle = info.mTitle;
-        infoClone.mAnchorId = info.mAnchorId;
-
-        if (info.mChildIds != null && info.mChildIds.size() > 0) {
-            if (infoClone.mChildIds == null) {
-                infoClone.mChildIds = info.mChildIds.clone();
-            } else {
-                infoClone.mChildIds.addAll(info.mChildIds);
-            }
-        }
-
-        infoClone.mConnectionId = info.mConnectionId;
-
+        infoClone.init(info);
         return infoClone;
     }
 
@@ -529,6 +516,32 @@
         parcel.writeInt(mConnectionId);
     }
 
+    /**
+     * Initializes this instance from another one.
+     *
+     * @param other The other instance.
+     */
+    private void init(AccessibilityWindowInfo other) {
+        mType = other.mType;
+        mLayer = other.mLayer;
+        mBooleanProperties = other.mBooleanProperties;
+        mId = other.mId;
+        mParentId = other.mParentId;
+        mBoundsInScreen.set(other.mBoundsInScreen);
+        mTitle = other.mTitle;
+        mAnchorId = other.mAnchorId;
+
+        if (other.mChildIds != null && other.mChildIds.size() > 0) {
+            if (mChildIds == null) {
+                mChildIds = other.mChildIds.clone();
+            } else {
+                mChildIds.addAll(other.mChildIds);
+            }
+        }
+
+        mConnectionId = other.mConnectionId;
+    }
+
     private void initFromParcel(Parcel parcel) {
         mType = parcel.readInt();
         mLayer = parcel.readInt();
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 77a0c4c..6503a80 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -2178,6 +2178,18 @@
             boolean saveOnAllViewsInvisible, boolean saveOnFinish,
             @Nullable AutofillId[] fillableIds, @Nullable AutofillId saveTriggerId) {
         synchronized (mLock) {
+            if (sVerbose) {
+                Log.v(TAG, "setTrackedViews(): sessionId=" + sessionId
+                        + ", trackedIds=" + Arrays.toString(trackedIds)
+                        + ", saveOnAllViewsInvisible=" + saveOnAllViewsInvisible
+                        + ", saveOnFinish=" + saveOnFinish
+                        + ", fillableIds=" + Arrays.toString(fillableIds)
+                        + ", saveTrigerId=" + saveTriggerId
+                        + ", mFillableIds=" + mFillableIds
+                        + ", mEnabled=" + mEnabled
+                        + ", mSessionId=" + mSessionId);
+
+            }
             if (mEnabled && mSessionId == sessionId) {
                 if (saveOnAllViewsInvisible) {
                     mTrackedViews = new TrackedViews(trackedIds);
@@ -2192,10 +2204,6 @@
                     for (AutofillId id : fillableIds) {
                         mFillableIds.add(id);
                     }
-                    if (sVerbose) {
-                        Log.v(TAG, "setTrackedViews(): fillableIds=" + Arrays.toString(fillableIds)
-                                + ", mFillableIds" + mFillableIds);
-                    }
                 }
 
                 if (mSaveTriggerId != null && !mSaveTriggerId.equals(saveTriggerId)) {
diff --git a/core/java/android/view/autofill/AutofillManagerInternal.java b/core/java/android/view/autofill/AutofillManagerInternal.java
index d5862bd..3de1a03 100644
--- a/core/java/android/view/autofill/AutofillManagerInternal.java
+++ b/core/java/android/view/autofill/AutofillManagerInternal.java
@@ -33,7 +33,10 @@
     public abstract void onBackKeyPressed();
 
     /**
-     * Gets autofill options for a package
+     * Gets autofill options for a package.
+     *
+     * <p><b>NOTE: </b>this method is called by the {@code ActivityManager} service and hence cannot
+     * hold the main service lock.
      *
      * @param packageName The package for which to query.
      * @param versionCode The package version code.
diff --git a/telecomm/java/android/telecom/CallIdentification.aidl b/core/java/android/view/contentcapture/ContentCaptureCondition.aidl
similarity index 80%
rename from telecomm/java/android/telecom/CallIdentification.aidl
rename to core/java/android/view/contentcapture/ContentCaptureCondition.aidl
index 532535c..99f8894 100644
--- a/telecomm/java/android/telecom/CallIdentification.aidl
+++ b/core/java/android/view/contentcapture/ContentCaptureCondition.aidl
@@ -1,5 +1,5 @@
-/*
- * Copyright 2018, The Android Open Source Project
+/**
+ * Copyright (c) 2019, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,6 @@
  * limitations under the License.
  */
 
-package android.telecom;
+package android.view.contentcapture;
 
-/**
- * {@hide}
- */
-parcelable CallIdentification;
+parcelable ContentCaptureCondition;
diff --git a/core/java/android/view/contentcapture/ContentCaptureCondition.java b/core/java/android/view/contentcapture/ContentCaptureCondition.java
new file mode 100644
index 0000000..cf171d7
--- /dev/null
+++ b/core/java/android/view/contentcapture/ContentCaptureCondition.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.contentcapture;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.LocusId;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.DebugUtils;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Defines a condition for when content capture should be allowed.
+ *
+ * <p>See {@link ContentCaptureManager#getContentCaptureConditions()} for more.
+ */
+public final class ContentCaptureCondition implements Parcelable {
+
+    /**
+     * When set, package should use the {@link LocusId#getId()} as a regular expression.
+     */
+    public static final int FLAG_IS_REGEX = 0x2;
+
+    /** @hide */
+    @IntDef(prefix = { "FLAG" }, flag = true, value = {
+            FLAG_IS_REGEX
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface Flags {}
+
+    private final @NonNull LocusId mLocusId;
+    private final @Flags int mFlags;
+
+    /**
+     * Default constructor.
+     *
+     * @param locusId id of the condition, as defined by
+     * {@link ContentCaptureContext#getLocusId()}.
+     * @param flags either {@link ContentCaptureCondition#FLAG_IS_REGEX} or {@code 0}.
+     */
+    public ContentCaptureCondition(@NonNull LocusId locusId, @Flags int flags) {
+        this.mLocusId = Preconditions.checkNotNull(locusId);
+        this.mFlags = flags;
+    }
+
+    /**
+     * Gets the {@code LocusId} per se.
+     */
+    @NonNull
+    public LocusId getLocusId() {
+        return mLocusId;
+    }
+
+    /**
+     * Gets the flags associates with this condition.
+     *
+     * @return either {@link ContentCaptureCondition#FLAG_IS_REGEX} or {@code 0}.
+     */
+    public @Flags int getFlags() {
+        return mFlags;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + mFlags;
+        result = prime * result + ((mLocusId == null) ? 0 : mLocusId.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        final ContentCaptureCondition other = (ContentCaptureCondition) obj;
+        if (mFlags != other.mFlags) return false;
+        if (mLocusId == null) {
+            if (other.mLocusId != null) return false;
+        } else {
+            if (!mLocusId.equals(other.mLocusId)) return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder string = new StringBuilder(mLocusId.toString()); // LocusID is PII safe
+        if (mFlags != 0) {
+            string
+                .append(" (")
+                .append(DebugUtils.flagsToString(ContentCaptureCondition.class, "FLAG_", mFlags))
+                .append(')');
+        }
+        return string.toString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeParcelable(mLocusId, flags);
+        parcel.writeInt(mFlags);
+    }
+
+    public static final @NonNull Parcelable.Creator<ContentCaptureCondition> CREATOR =
+            new Parcelable.Creator<ContentCaptureCondition>() {
+
+                @Override
+                public ContentCaptureCondition createFromParcel(@NonNull Parcel parcel) {
+                    return new ContentCaptureCondition(parcel.readParcelable(null),
+                            parcel.readInt());
+                }
+
+                @Override
+                public ContentCaptureCondition[] newArray(int size) {
+                    return new ContentCaptureCondition[size];
+                }
+    };
+}
diff --git a/core/java/android/view/contentcapture/ContentCaptureContext.java b/core/java/android/view/contentcapture/ContentCaptureContext.java
index 5a27e94..94e548f 100644
--- a/core/java/android/view/contentcapture/ContentCaptureContext.java
+++ b/core/java/android/view/contentcapture/ContentCaptureContext.java
@@ -15,6 +15,8 @@
  */
 package android.view.contentcapture;
 
+import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -35,9 +37,9 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-
 /**
- * Context associated with a {@link ContentCaptureSession}.
+ * Context associated with a {@link ContentCaptureSession} - see {@link ContentCaptureManager} for
+ * more info.
  */
 public final class ContentCaptureContext implements Parcelable {
 
@@ -50,8 +52,7 @@
 
     /**
      * Flag used to indicate that the app explicitly disabled content capture for the activity
-     * (using
-     * {@link android.view.contentcapture.ContentCaptureManager#setContentCaptureEnabled(boolean)}),
+     * (using {@link ContentCaptureManager#setContentCaptureEnabled(boolean)}),
      * in which case the service will just receive activity-level events.
      *
      * @hide
@@ -107,7 +108,7 @@
     private final int mDisplayId;
 
     // Fields below are set by the service upon "delivery" and are not marshalled in the parcel
-    private @Nullable String mParentSessionId;
+    private int mParentSessionId = NO_SESSION_ID;
 
     /** @hide */
     public ContentCaptureContext(@Nullable ContentCaptureContext clientContext,
@@ -198,11 +199,12 @@
     @SystemApi
     @TestApi
     public @Nullable ContentCaptureSessionId getParentSessionId() {
-        return mParentSessionId == null ?  null : new ContentCaptureSessionId(mParentSessionId);
+        return mParentSessionId == NO_SESSION_ID ? null
+                : new ContentCaptureSessionId(mParentSessionId);
     }
 
     /** @hide */
-    public void setParentSessionId(@NonNull String parentSessionId) {
+    public void setParentSessionId(int parentSessionId) {
         mParentSessionId = parentSessionId;
     }
 
@@ -260,9 +262,10 @@
          *   <li>A unique identifier of the application state (for example, a conversation between
          *   2 users in a chat app).
          *
+         * <p>See {@link ContentCaptureManager} for more info about the content capture context.
+         *
          * @param id id associated with this context.
          */
-        // TODO(b/123577059): make sure this is well documented and understandable
         public Builder(@NonNull LocusId id) {
             mId = Preconditions.checkNotNull(id);
         }
@@ -316,7 +319,7 @@
         }
         pw.print(", taskId="); pw.print(mTaskId);
         pw.print(", displayId="); pw.print(mDisplayId);
-        if (mParentSessionId != null) {
+        if (mParentSessionId != NO_SESSION_ID) {
             pw.print(", parentId="); pw.print(mParentSessionId);
         }
         if (mFlags > 0) {
@@ -348,7 +351,7 @@
                 builder.append(", hasExtras");
             }
         }
-        if (mParentSessionId != null) {
+        if (mParentSessionId != NO_SESSION_ID) {
             builder.append(", parentId=").append(mParentSessionId);
         }
         return builder.append(']').toString();
diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java
index 8188e05..bd38629 100644
--- a/core/java/android/view/contentcapture/ContentCaptureEvent.java
+++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java
@@ -16,6 +16,7 @@
 package android.view.contentcapture;
 
 import static android.view.contentcapture.ContentCaptureHelper.getSanitizedString;
+import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -126,25 +127,25 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface EventType{}
 
-    private final @NonNull String mSessionId;
+    private final int mSessionId;
     private final int mType;
     private final long mEventTime;
     private @Nullable AutofillId mId;
     private @Nullable ArrayList<AutofillId> mIds;
     private @Nullable ViewNode mNode;
     private @Nullable CharSequence mText;
-    private @Nullable String mParentSessionId;
+    private int mParentSessionId = NO_SESSION_ID;
     private @Nullable ContentCaptureContext mClientContext;
 
     /** @hide */
-    public ContentCaptureEvent(@NonNull String sessionId, int type, long eventTime) {
+    public ContentCaptureEvent(int sessionId, int type, long eventTime) {
         mSessionId = sessionId;
         mType = type;
         mEventTime = eventTime;
     }
 
     /** @hide */
-    public ContentCaptureEvent(@NonNull String sessionId, int type) {
+    public ContentCaptureEvent(int sessionId, int type) {
         this(sessionId, type, System.currentTimeMillis());
     }
 
@@ -185,7 +186,7 @@
      *
      * @hide
      */
-    public ContentCaptureEvent setParentSessionId(@NonNull String parentSessionId) {
+    public ContentCaptureEvent setParentSessionId(int parentSessionId) {
         mParentSessionId = parentSessionId;
         return this;
     }
@@ -202,7 +203,7 @@
 
     /** @hide */
     @NonNull
-    public String getSessionId() {
+    public int getSessionId() {
         return mSessionId;
     }
 
@@ -212,7 +213,7 @@
      * @hide
      */
     @Nullable
-    public String getParentSessionId() {
+    public int getParentSessionId() {
         return mParentSessionId;
     }
 
@@ -357,10 +358,10 @@
         if (mNode != null) {
             pw.print(", mNode.id="); pw.print(mNode.getAutofillId());
         }
-        if (mSessionId != null) {
+        if (mSessionId != NO_SESSION_ID) {
             pw.print(", sessionId="); pw.print(mSessionId);
         }
-        if (mParentSessionId != null) {
+        if (mParentSessionId != NO_SESSION_ID) {
             pw.print(", parentSessionId="); pw.print(mParentSessionId);
         }
         if (mText != null) {
@@ -377,7 +378,7 @@
         final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=")
                 .append(getTypeAsString(mType));
         string.append(", session=").append(mSessionId);
-        if (mType == TYPE_SESSION_STARTED && mParentSessionId != null) {
+        if (mType == TYPE_SESSION_STARTED && mParentSessionId != NO_SESSION_ID) {
             string.append(", parent=").append(mParentSessionId);
         }
         if (mId != null) {
@@ -409,7 +410,7 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeString(mSessionId);
+        parcel.writeInt(mSessionId);
         parcel.writeInt(mType);
         parcel.writeLong(mEventTime);
         parcel.writeParcelable(mId, flags);
@@ -417,7 +418,7 @@
         ViewNode.writeToParcel(parcel, mNode, flags);
         parcel.writeCharSequence(mText);
         if (mType == TYPE_SESSION_STARTED || mType == TYPE_SESSION_FINISHED) {
-            parcel.writeString(mParentSessionId);
+            parcel.writeInt(mParentSessionId);
         }
         if (mType == TYPE_SESSION_STARTED || mType == TYPE_CONTEXT_UPDATED) {
             parcel.writeParcelable(mClientContext, flags);
@@ -430,7 +431,7 @@
         @Override
         @NonNull
         public ContentCaptureEvent createFromParcel(Parcel parcel) {
-            final String sessionId = parcel.readString();
+            final int sessionId = parcel.readInt();
             final int type = parcel.readInt();
             final long eventTime  = parcel.readLong();
             final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, type, eventTime);
@@ -448,7 +449,7 @@
             }
             event.setText(parcel.readCharSequence());
             if (type == TYPE_SESSION_STARTED || type == TYPE_SESSION_FINISHED) {
-                event.setParentSessionId(parcel.readString());
+                event.setParentSessionId(parcel.readInt());
             }
             if (type == TYPE_SESSION_STARTED || type == TYPE_CONTEXT_UPDATED) {
                 event.setClientContext(parcel.readParcelable(null));
diff --git a/core/java/android/view/contentcapture/ContentCaptureHelper.java b/core/java/android/view/contentcapture/ContentCaptureHelper.java
index 6bc3829..c7ca220 100644
--- a/core/java/android/view/contentcapture/ContentCaptureHelper.java
+++ b/core/java/android/view/contentcapture/ContentCaptureHelper.java
@@ -23,9 +23,14 @@
 import android.annotation.Nullable;
 import android.os.Build;
 import android.provider.DeviceConfig;
+import android.util.ArraySet;
 import android.util.Log;
 import android.view.contentcapture.ContentCaptureManager.LoggingLevel;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 /**
  * Helper class for this package and server's.
  *
@@ -101,6 +106,22 @@
         }
     }
 
+    /**
+     * Converts a set to a list.
+     */
+    @Nullable
+    public static <T> ArrayList<T> toList(@Nullable Set<T> set) {
+        return set == null ? null : new ArrayList<T>(set);
+    }
+
+    /**
+     * Converts a list to a set.
+     */
+    @Nullable
+    public static <T> ArraySet<T> toSet(@Nullable List<T> list) {
+        return list == null ? null : new ArraySet<T>(list);
+    }
+
     private ContentCaptureHelper() {
         throw new UnsupportedOperationException("contains only static methods");
     }
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 9e546a8..2539356 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -17,6 +17,7 @@
 
 import static android.view.contentcapture.ContentCaptureHelper.sDebug;
 import static android.view.contentcapture.ContentCaptureHelper.sVerbose;
+import static android.view.contentcapture.ContentCaptureHelper.toSet;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -28,12 +29,15 @@
 import android.content.ComponentName;
 import android.content.ContentCaptureOptions;
 import android.content.Context;
+import android.graphics.Canvas;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
+import android.view.View;
+import android.view.ViewStructure;
 import android.view.contentcapture.ContentCaptureSession.FlushReason;
 
 import com.android.internal.annotations.GuardedBy;
@@ -43,9 +47,152 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Set;
 
 /**
- * TODO(b/123577059): add javadocs / mention it can be null
+ * <p>The {@link ContentCaptureManager} provides additional ways for for apps to
+ * integrate with the content capture subsystem.
+ *
+ * <p>Content capture provides real-time, continuous capture of application activity, display and
+ * events to an intelligence service that is provided by the Android system. The intelligence
+ * service then uses that info to mediate and speed user journey through different apps. For
+ * example, when the user receives a restaurant address in a chat app and switchs to a map app
+ * to search for that restaurant, the intelligence service could offer an autofill dialog to
+ * let the user automatically select its address.
+ *
+ * <p>Content capture was designed with two major concerns in mind: privacy and performance.
+ *
+ * <ul>
+ *   <li><b>Privacy:</b> the intelligence service is a trusted component provided that is provided
+ *   by the device manufacturer and that cannot be changed by the user (although the user can
+ *   globaly disable content capture using the Android Settings app). This service can only use the
+ *   data for in-device machine learning, which is enforced both by process isolation and
+ *   <a href="https://source.android.com/compatibility/cdd">CDD requirements</a>.
+ *   <li><b>Performance:</b> content capture is highly optimized to minimize its impact in the app
+ *   jankiness and overall device system health. For example, its only enabled on apps (or even
+ *   specific activities from an app) that were explicitly whitelisted by the intelligence service,
+ *   and it buffers the events so they are sent in a batch to the service (see
+ *   {@link #isContentCaptureEnabled()} for other cases when its disabled).
+ * </ul>
+ *
+ * <p>In fact, before using this manager, the app developer should check if it's available. Example:
+ *  <code>
+ *  ContentCaptureManager mgr = context.getSystemService(ContentCaptureManager.class);
+ *  if (mgr != null && mgr.isContentCaptureEnabled()) {
+ *    // ...
+ *  }
+ *  </code>
+ *
+ * <p>App developers usually don't need to explicitly interact with content capture, except when the
+ * app:
+ *
+ * <ul>
+ *   <li>Can define a contextual {@link android.content.LocusId} to identify unique state (such as a
+ *   conversation between 2 chat users).
+ *   <li>Can have multiple view hierarchies with different contextual meaning (for example, a
+ *   browser app with multiple tabs, each representing a different URL).
+ *   <li>Contains custom views (that extend View directly and are not provided by the standard
+ *   Android SDK.
+ *   <li>Contains views that provide their own virtual hierarchy (like a web browser that render the
+ *   HTML elements using a Canvas).
+ * </ul>
+ *
+ * <p>The main integration point with content capture is the {@link ContentCaptureSession}. A "main"
+ * session is automatically created by the Android System when content capture is enabled for the
+ * activity and its used by the standard Android views to notify the content capture service of
+ * events such as views being added, views been removed, and text changed by user input. The session
+ * could have a {@link ContentCaptureContext} to provide more contextual info about it, such as
+ * the locus associated with the view hierarchy (see {@link android.content.LocusId} for more info
+ * about locus). By default, the main session doesn't have a {@code ContentCaptureContext}, but you
+ * can change it after its created. Example:
+ *
+ * <pre><code>
+ * protected void onCreate(Bundle savedInstanceState) {
+ *   // Initialize view structure
+ *   ContentCaptureSession session = rootView.getContentCaptureSession();
+ *   if (session != null) {
+ *     session.setContentCaptureContext(ContentCaptureContext.forLocusId("chat_UserA_UserB"));
+ *   }
+ * }
+ * </code></pre>
+ *
+ * <p>If your activity contains view hierarchies with a different contextual meaning, you should
+ * created child sessions for each view hierarchy root. For example, if your activity is a browser,
+ * you could use the main session for the main URL being rendered, then child sessions for each
+ * {@code IFRAME}:
+ *
+ * <pre><code>
+ * ContentCaptureSession mMainSession;
+ *
+ * protected void onCreate(Bundle savedInstanceState) {
+ *    // Initialize view structure...
+ *    mMainSession = rootView.getContentCaptureSession();
+ *    if (mMainSession != null) {
+ *      mMainSession.setContentCaptureContext(
+ *          ContentCaptureContext.forLocusId("https://example.com"));
+ *    }
+ * }
+ *
+ * private void loadIFrame(View iframeRootView, String url) {
+ *   if (mMainSession != null) {
+ *      ContentCaptureSession iFrameSession = mMainSession.newChild(
+ *          ContentCaptureContext.forLocusId(url));
+ *      }
+ *      iframeRootView.setContentCaptureSession(iFrameSession);
+ *   }
+ *   // Load iframe...
+ * }
+ * </code></pre>
+ *
+ * <p>If your activity has custom views (i.e., views that extend {@link View} directly and provide
+ * just one logical view, not a virtual tree hiearchy) and it provides content that's relevant for
+ * content capture (as of {@link android.os.Build.VERSION_CODES#Q Android Q}, the only relevant
+ * content is text), then your view implementation should:
+ *
+ * <ul>
+ *   <li>Set it as important for content capture.
+ *   <li>Fill {@link ViewStructure} used for content capture.
+ *   <li>Notify the {@link ContentCaptureSession} when the text is changed by user input.
+ * </ul>
+ *
+ * <p>Here's an example of the relevant methods for an {@code EditText}-like view:
+ *
+ * <pre><code>
+ * public class MyEditText extends View {
+ *
+ * public MyEditText(...) {
+ *   if (getImportantForContentCapture() == IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) {
+ *     setImportantForContentCapture(IMPORTANT_FOR_CONTENT_CAPTURE_YES);
+ *   }
+ * }
+ *
+ * public void onProvideContentCaptureStructure(@NonNull ViewStructure structure, int flags) {
+ *   super.onProvideContentCaptureStructure(structure, flags);
+ *
+ *   structure.setText(getText(), getSelectionStart(), getSelectionEnd());
+ *   structure.setHint(getHint());
+ *   structure.setInputType(getInputType());
+ *   // set other properties like setTextIdEntry(), setTextLines(), setTextStyle(),
+ *   // setMinTextEms(), setMaxTextEms(), setMaxTextLength()
+ * }
+ *
+ * private void onTextChanged() {
+ *   if (isLaidOut() && isImportantForContentCapture() && isTextEditable()) {
+ *     ContentCaptureManager mgr = mContext.getSystemService(ContentCaptureManager.class);
+ *     if (cm != null && cm.isContentCaptureEnabled()) {
+ *        ContentCaptureSession session = getContentCaptureSession();
+ *        if (session != null) {
+ *          session.notifyViewTextChanged(getAutofillId(), getText());
+ *        }
+ *   }
+ * }
+ * </code></pre>
+ *
+ * <p>If your view provides its own virtual hierarchy (for example, if it's a browser that draws
+ * the HTML using {@link Canvas} or native libraries in a different render process), then the view
+ * is also responsible to notify the session when the virtual elements appear and disappear - see
+ * {@link View#onProvideContentCaptureStructure(ViewStructure, int)} for more info.
  */
 @SystemService(Context.CONTENT_CAPTURE_MANAGER_SERVICE)
 public final class ContentCaptureManager {
@@ -68,7 +215,7 @@
 
     /**
      * DeviceConfig property used by {@code com.android.server.SystemServer} on start to decide
-     * whether the Content Capture service should be created or not
+     * whether the content capture service should be created or not
      *
      * <p>By default it should *NOT* be set (or set to {@code "default"}, so the decision is based
      * on whether the OEM provides an implementation for the service), but it can be overridden to:
@@ -339,12 +486,12 @@
      * <p>There are many reasons it could be disabled, such as:
      * <ul>
      *   <li>App itself disabled content capture through {@link #setContentCaptureEnabled(boolean)}.
-     *   <li>Service disabled content capture for this specific activity.
-     *   <li>Service disabled content capture for all activities of this package.
-     *   <li>Service disabled content capture globally.
-     *   <li>User disabled content capture globally (through Settings).
-     *   <li>OEM disabled content capture globally.
-     *   <li>Transient errors.
+     *   <li>Intelligence service did not whitelist content capture for this activity's package.
+     *   <li>Intelligence service did not whitelist content capture for this specific activity.
+     *   <li>Intelligence service disabled content capture globally.
+     *   <li>User disabled content capture globally through the Android Settings app.
+     *   <li>Device manufacturer (OEM) disabled content capture globally.
+     *   <li>Transient errors, such as intelligence service package being updated.
      * </ul>
      */
     public boolean isContentCaptureEnabled() {
@@ -362,6 +509,31 @@
     }
 
     /**
+     * Gets the list of conditions for when content capture should be allowed.
+     *
+     * <p>This method is typically used by web browsers so they don't generate unnecessary content
+     * capture events for websites the content capture service is not interested on.
+     *
+     * @return list of conditions, or {@code null} if the service didn't set any restriction
+     * (in which case content capture events should always be generated). If the list is empty,
+     * then it should not generate any event at all.
+     */
+    @Nullable
+    public Set<ContentCaptureCondition> getContentCaptureConditions() {
+        // NOTE: we could cache the conditions on ContentCaptureOptions, but then it would be stick
+        // to the lifetime of the app. OTOH, by dynamically calling the server every time, we allow
+        // the service to fine tune how long-lived apps (like browsers) are whitelisted.
+        if (!isContentCaptureEnabled() && !mOptions.lite) return null;
+
+        final SyncResultReceiver resultReceiver = syncRun(
+                (r) -> mService.getContentCaptureConditions(mContext.getPackageName(), r));
+
+        final ArrayList<ContentCaptureCondition> result = resultReceiver
+                .getParcelableListResult();
+        return toSet(result);
+    }
+
+    /**
      * Called by apps to explicitly enable or disable content capture.
      *
      * <p><b>Note: </b> this call is not persisted accross reboots, so apps should typically call
@@ -378,12 +550,12 @@
     }
 
     /**
-     * Gets whether Content Capture is enabled for the given user.
+     * Gets whether content capture is enabled for the given user.
      *
-     * <p>This method is typically used by the Content Capture Service settings page, so it can
+     * <p>This method is typically used by the content capture service settings page, so it can
      * provide a toggle to enable / disable it.
      *
-     * @throws SecurityException if caller is not the app that owns the Content Capture service
+     * @throws SecurityException if caller is not the app that owns the content capture service
      * associated with the user.
      *
      * @hide
@@ -391,21 +563,14 @@
     @SystemApi
     @TestApi
     public boolean isContentCaptureFeatureEnabled() {
-        final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
-        final int resultCode;
-        try {
-            mService.isContentCaptureFeatureEnabled(resultReceiver);
-            resultCode = resultReceiver.getIntResult();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        final SyncResultReceiver resultReceiver = syncRun(
+                (r) -> mService.isContentCaptureFeatureEnabled(r));
+        final int resultCode = resultReceiver.getIntResult();
         switch (resultCode) {
             case RESULT_CODE_TRUE:
                 return true;
             case RESULT_CODE_FALSE:
                 return false;
-            case RESULT_CODE_SECURITY_EXCEPTION:
-                throw new SecurityException("caller is not user's ContentCapture service");
             default:
                 Log.wtf(TAG, "received invalid result: " + resultCode);
                 return false;
@@ -413,7 +578,7 @@
     }
 
     /**
-     * Called by the app to request the Content Capture service to remove user-data associated with
+     * Called by the app to request the content capture service to remove user-data associated with
      * some context.
      *
      * @param request object specifying what user data should be removed.
@@ -428,6 +593,26 @@
         }
     }
 
+    /**
+     * Runs a sync method in the service, properly handling exceptions.
+     *
+     * @throws SecurityException if caller is not allowed to execute the method.
+     */
+    @NonNull
+    private SyncResultReceiver syncRun(@NonNull MyRunnable r) {
+        final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
+        try {
+            r.run(resultReceiver);
+            final int resultCode = resultReceiver.getIntResult();
+            if (resultCode == RESULT_CODE_SECURITY_EXCEPTION) {
+                throw new SecurityException(resultReceiver.getStringResult());
+            }
+            return resultReceiver;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     /** @hide */
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.println("ContentCaptureManager");
@@ -451,4 +636,8 @@
             }
         }
     }
+
+    private interface MyRunnable {
+        void run(@NonNull SyncResultReceiver receiver) throws RemoteException;
+    }
 }
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index ed1ca2a..7761038 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -38,7 +38,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
-import java.util.UUID;
+import java.util.Random;
 
 /**
  * Session used to notify a system-provided Content Capture service about events associated with
@@ -48,6 +48,11 @@
 
     private static final String TAG = ContentCaptureSession.class.getSimpleName();
 
+    private static final Random sIdGenerator = new Random();
+
+    /** @hide */
+    public static final int NO_SESSION_ID = 0;
+
     /**
      * Initial state, when there is no session.
      *
@@ -186,7 +191,7 @@
 
     /** @hide */
     @Nullable
-    protected final String mId;
+    protected final int mId;
 
     private int mState = UNKNOWN_STATE;
 
@@ -210,13 +215,14 @@
 
     /** @hide */
     protected ContentCaptureSession() {
-        this(UUID.randomUUID().toString());
+        this(getRandomSessionId());
     }
 
     /** @hide */
     @VisibleForTesting
-    public ContentCaptureSession(@NonNull String id) {
-        mId = Preconditions.checkNotNull(id);
+    public ContentCaptureSession(int id) {
+        Preconditions.checkArgument(id != NO_SESSION_ID);
+        mId = id;
     }
 
     // Used by ChildCOntentCaptureSession
@@ -241,15 +247,8 @@
     }
 
     /** @hide */
-    @VisibleForTesting
-    public int getIdAsInt() {
-        // TODO(b/121197119): use sessionId instead of hashcode once it's changed to int
-        return mId.hashCode();
-    }
-
-    /** @hide */
     @NonNull
-    public String getId() {
+    public int getId() {
         return mId;
     }
 
@@ -415,7 +414,7 @@
         // TODO(b/123036895): use a internalNotifyViewsDisappeared that optimizes how the event is
         // parcelized
         for (long id : virtualIds) {
-            internalNotifyViewDisappeared(new AutofillId(hostId, id, getIdAsInt()));
+            internalNotifyViewDisappeared(new AutofillId(hostId, id, mId));
         }
     }
 
@@ -464,7 +463,7 @@
     public @NonNull AutofillId newAutofillId(@NonNull AutofillId hostId, long virtualChildId) {
         Preconditions.checkNotNull(hostId);
         Preconditions.checkArgument(hostId.isNonVirtual(), "hostId cannot be virtual: %s", hostId);
-        return new AutofillId(hostId, virtualChildId, getIdAsInt());
+        return new AutofillId(hostId, virtualChildId, mId);
     }
 
     /**
@@ -480,7 +479,7 @@
     @NonNull
     public final ViewStructure newVirtualViewStructure(@NonNull AutofillId parentId,
             long virtualId) {
-        return new ViewNode.ViewStructureImpl(parentId, virtualId, getIdAsInt());
+        return new ViewNode.ViewStructureImpl(parentId, virtualId, mId);
     }
 
     boolean isContentCaptureEnabled() {
@@ -511,7 +510,7 @@
 
     @Override
     public String toString() {
-        return mId;
+        return Integer.toString(mId);
     }
 
     /** @hide */
@@ -541,4 +540,12 @@
                 return "UNKOWN-" + reason;
         }
     }
+
+    private static int getRandomSessionId() {
+        int id;
+        do {
+            id = sIdGenerator.nextInt();
+        } while (id == NO_SESSION_ID);
+        return id;
+    }
 }
diff --git a/core/java/android/view/contentcapture/ContentCaptureSessionId.java b/core/java/android/view/contentcapture/ContentCaptureSessionId.java
index e7c350a..2d350b2 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSessionId.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSessionId.java
@@ -27,7 +27,7 @@
  */
 public final class ContentCaptureSessionId implements Parcelable {
 
-    private final @NonNull String mValue;
+    private final @NonNull int mValue;
 
     /**
      * Creates a new instance.
@@ -36,14 +36,14 @@
      *
      * @hide
      */
-    public ContentCaptureSessionId(@NonNull String value) {
+    public ContentCaptureSessionId(@NonNull int value) {
         mValue = value;
     }
 
     /**
      * @hide
      */
-    public String getValue() {
+    public int getValue() {
         return mValue;
     }
 
@@ -51,7 +51,7 @@
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = prime * result + ((mValue == null) ? 0 : mValue.hashCode());
+        result = prime * result + mValue;
         return result;
     }
 
@@ -61,11 +61,7 @@
         if (obj == null) return false;
         if (getClass() != obj.getClass()) return false;
         final ContentCaptureSessionId other = (ContentCaptureSessionId) obj;
-        if (mValue == null) {
-            if (other.mValue != null) return false;
-        } else if (!mValue.equals(other.mValue)) {
-            return false;
-        }
+        if (mValue != other.mValue) return false;
         return true;
     }
 
@@ -77,9 +73,10 @@
      */
     @Override
     public String toString() {
-        return mValue;
+        return Integer.toString(mValue);
     }
 
+
     /** @hide */
     // TODO(b/111276913): dump to proto as well
     public void dump(PrintWriter pw) {
@@ -93,16 +90,16 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeString(mValue);
+        parcel.writeInt(mValue);
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<ContentCaptureSessionId> CREATOR =
+    public static final @NonNull Parcelable.Creator<ContentCaptureSessionId> CREATOR =
             new Parcelable.Creator<ContentCaptureSessionId>() {
 
         @Override
         @NonNull
         public ContentCaptureSessionId createFromParcel(Parcel parcel) {
-            return new ContentCaptureSessionId(parcel.readString());
+            return new ContentCaptureSessionId(parcel.readInt());
         }
 
         @Override
diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
index 15fbaa2..7335073 100644
--- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl
+++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
@@ -42,13 +42,13 @@
      *     {@link IContentCaptureContext#flags}).
      */
     void startSession(IBinder activityToken, in ComponentName componentName,
-                      String sessionId, int flags, in IResultReceiver result);
+                      int sessionId, int flags, in IResultReceiver result);
 
     /**
      * Marks the end of a session for the calling user identified by
      * the corresponding {@code startSession}'s {@code sessionId}.
      */
-    void finishSession(String sessionId);
+    void finishSession(int sessionId);
 
     /**
      * Returns the content capture service's component name (if enabled and
@@ -72,4 +72,9 @@
      * Returns a ComponentName with the name of custom service activity, if defined.
      */
     void getServiceSettingsActivity(in IResultReceiver result);
+
+    /**
+     * Returns a list with the ContentCaptureConditions for the package (or null if not defined).
+     */
+    void getContentCaptureConditions(String packageName, in IResultReceiver result);
 }
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 790b8f9..784cf9c 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -318,7 +318,7 @@
         if (!mEvents.isEmpty() && eventType == TYPE_VIEW_DISAPPEARED) {
             final ContentCaptureEvent lastEvent = mEvents.get(mEvents.size() - 1);
             if (lastEvent.getType() == TYPE_VIEW_DISAPPEARED
-                    && event.getSessionId().equals(lastEvent.getSessionId())) {
+                    && event.getSessionId() == lastEvent.getSessionId()) {
                 if (sVerbose) {
                     Log.v(TAG, "Buffering TYPE_VIEW_DISAPPEARED events for session "
                             + lastEvent.getSessionId());
@@ -581,37 +581,35 @@
     // TODO(b/122454205): refactor "notifyXXXX" methods below to a common "Buffer" object that is
     // shared between ActivityContentCaptureSession and ChildContentCaptureSession objects. Such
     // change should also get get rid of the "internalNotifyXXXX" methods above
-    void notifyChildSessionStarted(@NonNull String parentSessionId,
-            @NonNull String childSessionId, @NonNull ContentCaptureContext clientContext) {
+    void notifyChildSessionStarted(int parentSessionId, int childSessionId,
+            @NonNull ContentCaptureContext clientContext) {
         sendEvent(new ContentCaptureEvent(childSessionId, TYPE_SESSION_STARTED)
                 .setParentSessionId(parentSessionId).setClientContext(clientContext),
                 FORCE_FLUSH);
     }
 
-    void notifyChildSessionFinished(@NonNull String parentSessionId,
-            @NonNull String childSessionId) {
+    void notifyChildSessionFinished(int parentSessionId, int childSessionId) {
         sendEvent(new ContentCaptureEvent(childSessionId, TYPE_SESSION_FINISHED)
                 .setParentSessionId(parentSessionId), FORCE_FLUSH);
     }
 
-    void notifyViewAppeared(@NonNull String sessionId, @NonNull ViewStructureImpl node) {
+    void notifyViewAppeared(int sessionId, @NonNull ViewStructureImpl node) {
         sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_APPEARED)
                 .setViewNode(node.mNode));
     }
 
     /** Public because is also used by ViewRootImpl */
-    public void notifyViewDisappeared(@NonNull String sessionId, @NonNull AutofillId id) {
+    public void notifyViewDisappeared(int sessionId, @NonNull AutofillId id) {
         sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_DISAPPEARED).setAutofillId(id));
     }
 
-    void notifyViewTextChanged(@NonNull String sessionId, @NonNull AutofillId id,
-            @Nullable CharSequence text) {
+    void notifyViewTextChanged(int sessionId, @NonNull AutofillId id, @Nullable CharSequence text) {
         sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_TEXT_CHANGED).setAutofillId(id)
                 .setText(text));
     }
 
     /** Public because is also used by ViewRootImpl */
-    public void notifyViewTreeEvent(@NonNull String sessionId, boolean started) {
+    public void notifyViewTreeEvent(int sessionId, boolean started) {
         final int type = started ? TYPE_VIEW_TREE_APPEARING : TYPE_VIEW_TREE_APPEARED;
         sendEvent(new ContentCaptureEvent(sessionId, type), FORCE_FLUSH);
     }
@@ -622,8 +620,7 @@
         sendEvent(new ContentCaptureEvent(mId, type), FORCE_FLUSH);
     }
 
-    void notifyContextUpdated(@NonNull String sessionId,
-            @Nullable ContentCaptureContext context) {
+    void notifyContextUpdated(int sessionId, @Nullable ContentCaptureContext context) {
         sendEvent(new ContentCaptureEvent(sessionId, TYPE_CONTEXT_UPDATED)
                 .setClientContext(context));
     }
diff --git a/core/java/android/view/inspector/PropertyReader.java b/core/java/android/view/inspector/PropertyReader.java
index b5020ce..5be0e3f 100644
--- a/core/java/android/view/inspector/PropertyReader.java
+++ b/core/java/android/view/inspector/PropertyReader.java
@@ -133,10 +133,11 @@
     void readColor(int id, @ColorInt int value);
 
     /**
-     * Read a color packed into a {@link ColorLong} as a property.
+     * Read a color packed into a {@code ColorLong} as a property.
      *
      * @param id Identifier of the property from a {@link PropertyMapper}
-     * @param value Value of the property
+     * @param value Value of the property packed as a {@code ColorLong}. See the
+     *              {@link Color} class for details of the packing.
      * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
      */
     void readColor(int id, @ColorLong long value);
diff --git a/core/java/android/view/textclassifier/ConfigParser.java b/core/java/android/view/textclassifier/ConfigParser.java
index 8e0bdf9..b475412 100644
--- a/core/java/android/view/textclassifier/ConfigParser.java
+++ b/core/java/android/view/textclassifier/ConfigParser.java
@@ -33,6 +33,10 @@
 
     private final KeyValueListParser mParser;
 
+    // TODO: Re-enable DeviceConfig when it has reasonable performance or just delete the
+    // option of using DeviceConfig entirely.
+    static final boolean ENABLE_DEVICE_CONFIG = false;
+
     public ConfigParser(@Nullable String textClassifierConstants) {
         final KeyValueListParser parser = new KeyValueListParser(',');
         try {
@@ -48,39 +52,55 @@
      * Reads a boolean flag.
      */
     public boolean getBoolean(String key, boolean defaultValue) {
-        return DeviceConfig.getBoolean(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                key,
-                mParser.getBoolean(key, defaultValue));
+        if (ENABLE_DEVICE_CONFIG) {
+            return DeviceConfig.getBoolean(
+                    DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+                    key,
+                    mParser.getBoolean(key, defaultValue));
+        } else {
+            return mParser.getBoolean(key, defaultValue);
+        }
     }
 
     /**
      * Reads an integer flag.
      */
     public int getInt(String key, int defaultValue) {
-        return DeviceConfig.getInt(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                key,
-                mParser.getInt(key, defaultValue));
+        if (ENABLE_DEVICE_CONFIG) {
+            return DeviceConfig.getInt(
+                    DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+                    key,
+                    mParser.getInt(key, defaultValue));
+        } else {
+            return mParser.getInt(key, defaultValue);
+        }
     }
 
     /**
      * Reads a float flag.
      */
     public float getFloat(String key, float defaultValue) {
-        return DeviceConfig.getFloat(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                key,
-                mParser.getFloat(key, defaultValue));
+        if (ENABLE_DEVICE_CONFIG) {
+            return DeviceConfig.getFloat(
+                    DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+                    key,
+                    mParser.getFloat(key, defaultValue));
+        } else {
+            return mParser.getFloat(key, defaultValue);
+        }
     }
 
     /**
      * Reads a string flag.
      */
     public String getString(String key, String defaultValue) {
-        return DeviceConfig.getString(
-                DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                key,
-                mParser.getString(key, defaultValue));
+        if (ENABLE_DEVICE_CONFIG) {
+            return DeviceConfig.getString(
+                    DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+                    key,
+                    mParser.getString(key, defaultValue));
+        } else {
+            return mParser.getString(key, defaultValue);
+        }
     }
 }
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 868cbb1..fa898c3 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -197,7 +197,9 @@
             if (mSettingsObserver != null) {
                 getApplicationContext().getContentResolver()
                         .unregisterContentObserver(mSettingsObserver);
-                DeviceConfig.removeOnPropertyChangedListener(mSettingsObserver);
+                if (ConfigParser.ENABLE_DEVICE_CONFIG) {
+                    DeviceConfig.removeOnPropertyChangedListener(mSettingsObserver);
+                }
             }
         } finally {
             super.finalize();
@@ -292,10 +294,12 @@
                     Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_CONSTANTS),
                     false /* notifyForDescendants */,
                     this);
-            DeviceConfig.addOnPropertyChangedListener(
-                    DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
-                    ActivityThread.currentApplication().getMainExecutor(),
-                    this);
+            if (ConfigParser.ENABLE_DEVICE_CONFIG) {
+                DeviceConfig.addOnPropertyChangedListener(
+                        DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+                        ActivityThread.currentApplication().getMainExecutor(),
+                        this);
+            }
         }
 
         @Override
diff --git a/core/java/android/view/textclassifier/intent/ClassificationIntentFactory.java b/core/java/android/view/textclassifier/intent/ClassificationIntentFactory.java
index b034846..22e374f2 100644
--- a/core/java/android/view/textclassifier/intent/ClassificationIntentFactory.java
+++ b/core/java/android/view/textclassifier/intent/ClassificationIntentFactory.java
@@ -48,6 +48,7 @@
                 context.getString(com.android.internal.R.string.translate),
                 /* titleWithEntity */ null,
                 context.getString(com.android.internal.R.string.translate_desc),
+                /* descriptionWithAppName */ null,
                 new Intent(Intent.ACTION_TRANSLATE)
                         // TODO: Probably better to introduce a "translate" scheme instead of
                         // using EXTRA_TEXT.
diff --git a/core/java/android/view/textclassifier/intent/LabeledIntent.java b/core/java/android/view/textclassifier/intent/LabeledIntent.java
index 11d64f1..b4bc8d3 100644
--- a/core/java/android/view/textclassifier/intent/LabeledIntent.java
+++ b/core/java/android/view/textclassifier/intent/LabeledIntent.java
@@ -56,6 +56,8 @@
     @Nullable
     public final String titleWithEntity;
     public final String description;
+    @Nullable
+    public final String descriptionWithAppName;
     // Do not update this intent.
     public final Intent intent;
     public final int requestCode;
@@ -75,6 +77,7 @@
             @Nullable String titleWithoutEntity,
             @Nullable String titleWithEntity,
             String description,
+            @Nullable String descriptionWithAppName,
             Intent intent,
             int requestCode) {
         if (TextUtils.isEmpty(titleWithEntity) && TextUtils.isEmpty(titleWithoutEntity)) {
@@ -84,6 +87,7 @@
         this.titleWithoutEntity = titleWithoutEntity;
         this.titleWithEntity = titleWithEntity;
         this.description = Preconditions.checkNotNull(description);
+        this.descriptionWithAppName = descriptionWithAppName;
         this.intent = Preconditions.checkNotNull(intent);
         this.requestCode = requestCode;
     }
@@ -141,11 +145,39 @@
             Log.w(TAG, "Custom titleChooser return null, fallback to the default titleChooser");
             title = DEFAULT_TITLE_CHOOSER.chooseTitle(this, resolveInfo);
         }
-        final RemoteAction action = new RemoteAction(icon, title, description, pendingIntent);
+        final RemoteAction action =
+                new RemoteAction(icon, title, resolveDescription(resolveInfo, pm), pendingIntent);
         action.setShouldShowIcon(shouldShowIcon);
         return new Result(resolvedIntent, action);
     }
 
+    private String resolveDescription(ResolveInfo resolveInfo, PackageManager packageManager) {
+        if (!TextUtils.isEmpty(descriptionWithAppName)) {
+            // Example string format of descriptionWithAppName: "Use %1$s to open map".
+            String applicationName = getApplicationName(resolveInfo, packageManager);
+            if (!TextUtils.isEmpty(applicationName)) {
+                return String.format(descriptionWithAppName, applicationName);
+            }
+        }
+        return description;
+    }
+
+    @Nullable
+    private String getApplicationName(
+            ResolveInfo resolveInfo, PackageManager packageManager) {
+        if (resolveInfo.activityInfo == null) {
+            return null;
+        }
+        if ("android".equals(resolveInfo.activityInfo.packageName)) {
+            return null;
+        }
+        if (resolveInfo.activityInfo.applicationInfo == null) {
+            return null;
+        }
+        return (String) packageManager.getApplicationLabel(
+                resolveInfo.activityInfo.applicationInfo);
+    }
+
     private Bundle getFromTextClassifierExtra(@Nullable Bundle textLanguagesBundle) {
         if (textLanguagesBundle != null) {
             final Bundle bundle = new Bundle();
diff --git a/core/java/android/view/textclassifier/intent/LegacyClassificationIntentFactory.java b/core/java/android/view/textclassifier/intent/LegacyClassificationIntentFactory.java
index 7916791..8d60ad8 100644
--- a/core/java/android/view/textclassifier/intent/LegacyClassificationIntentFactory.java
+++ b/core/java/android/view/textclassifier/intent/LegacyClassificationIntentFactory.java
@@ -46,6 +46,7 @@
  * Creates intents based on the classification type.
  * @hide
  */
+// TODO: Consider to support {@code descriptionWithAppName}.
 public final class LegacyClassificationIntentFactory implements ClassificationIntentFactory {
 
     private static final String TAG = "LegacyClassificationIntentFactory";
@@ -108,6 +109,7 @@
                 context.getString(com.android.internal.R.string.email),
                 /* titleWithEntity */ null,
                 context.getString(com.android.internal.R.string.email_desc),
+                /* descriptionWithAppName */ null,
                 new Intent(Intent.ACTION_SENDTO)
                         .setData(Uri.parse(String.format("mailto:%s", text))),
                 LabeledIntent.DEFAULT_REQUEST_CODE));
@@ -115,6 +117,7 @@
                 context.getString(com.android.internal.R.string.add_contact),
                 /* titleWithEntity */ null,
                 context.getString(com.android.internal.R.string.add_contact_desc),
+                /* descriptionWithAppName */ null,
                 new Intent(Intent.ACTION_INSERT_OR_EDIT)
                         .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE)
                         .putExtra(ContactsContract.Intents.Insert.EMAIL, text),
@@ -133,6 +136,7 @@
                     context.getString(com.android.internal.R.string.dial),
                     /* titleWithEntity */ null,
                     context.getString(com.android.internal.R.string.dial_desc),
+                    /* descriptionWithAppName */ null,
                     new Intent(Intent.ACTION_DIAL).setData(
                             Uri.parse(String.format("tel:%s", text))),
                     LabeledIntent.DEFAULT_REQUEST_CODE));
@@ -141,6 +145,7 @@
                 context.getString(com.android.internal.R.string.add_contact),
                 /* titleWithEntity */ null,
                 context.getString(com.android.internal.R.string.add_contact_desc),
+                /* descriptionWithAppName */ null,
                 new Intent(Intent.ACTION_INSERT_OR_EDIT)
                         .setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE)
                         .putExtra(ContactsContract.Intents.Insert.PHONE, text),
@@ -150,6 +155,7 @@
                     context.getString(com.android.internal.R.string.sms),
                     /* titleWithEntity */ null,
                     context.getString(com.android.internal.R.string.sms_desc),
+                    /* descriptionWithAppName */ null,
                     new Intent(Intent.ACTION_SENDTO)
                             .setData(Uri.parse(String.format("smsto:%s", text))),
                     LabeledIntent.DEFAULT_REQUEST_CODE));
@@ -166,6 +172,7 @@
                     context.getString(com.android.internal.R.string.map),
                     /* titleWithEntity */ null,
                     context.getString(com.android.internal.R.string.map_desc),
+                    /* descriptionWithAppName */ null,
                     new Intent(Intent.ACTION_VIEW)
                             .setData(Uri.parse(String.format("geo:0,0?q=%s", encText))),
                     LabeledIntent.DEFAULT_REQUEST_CODE));
@@ -185,6 +192,7 @@
                 context.getString(com.android.internal.R.string.browse),
                 /* titleWithEntity */ null,
                 context.getString(com.android.internal.R.string.browse_desc),
+                /* descriptionWithAppName */ null,
                 new Intent(Intent.ACTION_VIEW)
                         .setDataAndNormalize(Uri.parse(text))
                         .putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()),
@@ -216,6 +224,7 @@
                 context.getString(com.android.internal.R.string.view_flight),
                 /* titleWithEntity */ null,
                 context.getString(com.android.internal.R.string.view_flight_desc),
+                /* descriptionWithAppName */ null,
                 new Intent(Intent.ACTION_WEB_SEARCH)
                         .putExtra(SearchManager.QUERY, text),
                 text.hashCode()));
@@ -231,6 +240,7 @@
                 context.getString(com.android.internal.R.string.view_calendar),
                 /* titleWithEntity */ null,
                 context.getString(com.android.internal.R.string.view_calendar_desc),
+                /* descriptionWithAppName */ null,
                 new Intent(Intent.ACTION_VIEW).setData(builder.build()),
                 LabeledIntent.DEFAULT_REQUEST_CODE);
     }
@@ -243,6 +253,7 @@
                 context.getString(com.android.internal.R.string.add_calendar_event),
                 /* titleWithEntity */ null,
                 context.getString(com.android.internal.R.string.add_calendar_event_desc),
+                /* descriptionWithAppName */ null,
                 new Intent(Intent.ACTION_INSERT)
                         .setData(CalendarContract.Events.CONTENT_URI)
                         .putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, isAllDay)
@@ -260,6 +271,7 @@
                 context.getString(com.android.internal.R.string.define),
                 /* titleWithEntity */ null,
                 context.getString(com.android.internal.R.string.define_desc),
+                /* descriptionWithAppName */ null,
                 new Intent(Intent.ACTION_DEFINE)
                         .putExtra(Intent.EXTRA_TEXT, text),
                 text.hashCode()));
diff --git a/core/java/android/view/textclassifier/intent/TemplateIntentFactory.java b/core/java/android/view/textclassifier/intent/TemplateIntentFactory.java
index 59cd7ab..7a39569 100644
--- a/core/java/android/view/textclassifier/intent/TemplateIntentFactory.java
+++ b/core/java/android/view/textclassifier/intent/TemplateIntentFactory.java
@@ -61,6 +61,7 @@
                             remoteActionTemplate.titleWithoutEntity,
                             remoteActionTemplate.titleWithEntity,
                             remoteActionTemplate.description,
+                            remoteActionTemplate.descriptionWithAppName,
                             createIntent(remoteActionTemplate),
                             remoteActionTemplate.requestCode == null
                                     ? LabeledIntent.DEFAULT_REQUEST_CODE
diff --git a/core/java/android/webkit/IWebViewUpdateService.aidl b/core/java/android/webkit/IWebViewUpdateService.aidl
index 10cfea1..1da0500 100644
--- a/core/java/android/webkit/IWebViewUpdateService.aidl
+++ b/core/java/android/webkit/IWebViewUpdateService.aidl
@@ -71,18 +71,6 @@
     PackageInfo getCurrentWebViewPackage();
 
     /**
-     * Used by Settings to determine whether a certain package can be enabled/disabled by the user -
-     * the package should not be modifiable in this way if it is a fallback package.
-     */
-    @UnsupportedAppUsage
-    boolean isFallbackPackage(String packageName);
-
-    /**
-     * Enable or disable the WebView package fallback mechanism.
-     */
-    void enableFallbackLogic(boolean enable);
-
-    /**
      * Used by Settings to determine whether multiprocess is enabled.
      */
     boolean isMultiProcessEnabled();
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 4413585..678a252 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -321,45 +321,6 @@
         }
     }
 
-    /**
-     * If the ApplicationInfo provided is for a stub WebView, fix up the object to include the
-     * required values from the donor package. If the ApplicationInfo is for a full WebView,
-     * leave it alone. Throws MissingWebViewPackageException if the donor is missing.
-     */
-    private static void fixupStubApplicationInfo(ApplicationInfo ai, PackageManager pm)
-            throws MissingWebViewPackageException {
-        String donorPackageName = null;
-        if (ai.metaData != null) {
-            donorPackageName = ai.metaData.getString("com.android.webview.WebViewDonorPackage");
-        }
-        if (donorPackageName != null) {
-            PackageInfo donorPackage;
-            try {
-                donorPackage = pm.getPackageInfo(
-                        donorPackageName,
-                        PackageManager.GET_SHARED_LIBRARY_FILES
-                        | PackageManager.MATCH_DEBUG_TRIAGED_MISSING
-                        | PackageManager.MATCH_UNINSTALLED_PACKAGES
-                        | PackageManager.MATCH_FACTORY_ONLY);
-            } catch (PackageManager.NameNotFoundException e) {
-                throw new MissingWebViewPackageException("Failed to find donor package: " +
-                                                         donorPackageName);
-            }
-            ApplicationInfo donorInfo = donorPackage.applicationInfo;
-
-            // Replace the stub's code locations with the donor's.
-            ai.sourceDir = donorInfo.sourceDir;
-            ai.splitSourceDirs = donorInfo.splitSourceDirs;
-            ai.nativeLibraryDir = donorInfo.nativeLibraryDir;
-            ai.secondaryNativeLibraryDir = donorInfo.secondaryNativeLibraryDir;
-
-            // Copy the donor's primary and secondary ABIs, since the stub doesn't have native code
-            // and so they are unset.
-            ai.primaryCpuAbi = donorInfo.primaryCpuAbi;
-            ai.secondaryCpuAbi = donorInfo.secondaryCpuAbi;
-        }
-    }
-
     @UnsupportedAppUsage
     private static Context getWebViewContextAndSetProvider() throws MissingWebViewPackageException {
         Application initialApplication = AppGlobals.getInitialApplication();
@@ -411,7 +372,6 @@
             verifyPackageInfo(response.packageInfo, newPackageInfo);
 
             ApplicationInfo ai = newPackageInfo.applicationInfo;
-            fixupStubApplicationInfo(ai, pm);
 
             Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW,
                     "initialApplication.createApplicationContext");
@@ -494,18 +454,14 @@
      */
     public static int onWebViewProviderChanged(PackageInfo packageInfo) {
         int startedRelroProcesses = 0;
-        ApplicationInfo originalAppInfo = new ApplicationInfo(packageInfo.applicationInfo);
         try {
-            fixupStubApplicationInfo(packageInfo.applicationInfo,
-                                     AppGlobals.getInitialApplication().getPackageManager());
-
             startedRelroProcesses = WebViewLibraryLoader.prepareNativeLibraries(packageInfo);
         } catch (Throwable t) {
             // Log and discard errors at this stage as we must not crash the system server.
             Log.e(LOGTAG, "error preparing webview native library", t);
         }
 
-        WebViewZygote.onWebViewProviderChanged(packageInfo, originalAppInfo);
+        WebViewZygote.onWebViewProviderChanged(packageInfo);
 
         return startedRelroProcesses;
     }
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index 09aa066..62f54b9 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -16,8 +16,6 @@
 
 package android.webkit;
 
-import android.app.LoadedApk;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.os.AsyncTask;
 import android.os.Build;
@@ -29,10 +27,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
 /** @hide */
 public class WebViewZygote {
     private static final String LOGTAG = "WebViewZygote";
@@ -56,13 +50,6 @@
     private static PackageInfo sPackage;
 
     /**
-     * Original ApplicationInfo for the selected WebView package before stub fixup. This is set from
-     * #onWebViewProviderChanged().
-     */
-    @GuardedBy("sLock")
-    private static ApplicationInfo sPackageOriginalAppInfo;
-
-    /**
      * Flag for whether multi-process WebView is enabled. If this is {@code false}, the zygote
      * will not be started.
      */
@@ -110,11 +97,9 @@
         }
     }
 
-    public static void onWebViewProviderChanged(PackageInfo packageInfo,
-                                                ApplicationInfo originalAppInfo) {
+    static void onWebViewProviderChanged(PackageInfo packageInfo) {
         synchronized (sLock) {
             sPackage = packageInfo;
-            sPackageOriginalAppInfo = originalAppInfo;
 
             // If multi-process is not enabled, then do not start the zygote service.
             if (!sMultiprocessEnabled) {
@@ -165,34 +150,7 @@
                     Process.FIRST_ISOLATED_UID,
                     Integer.MAX_VALUE); // TODO(b/123615476) deal with user-id ranges properly
             ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress());
-
-            if (sPackageOriginalAppInfo.sourceDir.equals(sPackage.applicationInfo.sourceDir)) {
-                // No stub WebView is involved here, so we can preload the package the "clean" way
-                // using the ApplicationInfo.
-                sZygote.preloadApp(sPackage.applicationInfo, abi);
-            } else {
-                // Legacy path to support the stub WebView.
-                // Reuse the logic from LoadedApk to determine the correct paths and pass them to
-                // the zygote as strings.
-                final List<String> zipPaths = new ArrayList<>(10);
-                final List<String> libPaths = new ArrayList<>(10);
-                LoadedApk.makePaths(null, false, sPackage.applicationInfo, zipPaths, libPaths);
-                final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
-                final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
-                        TextUtils.join(File.pathSeparator, zipPaths);
-
-                String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo);
-
-                // Use the original ApplicationInfo to determine what the original classpath would
-                // have been to use as a cache key.
-                LoadedApk.makePaths(null, false, sPackageOriginalAppInfo, zipPaths, null);
-                final String cacheKey = (zipPaths.size() == 1) ? zipPaths.get(0) :
-                        TextUtils.join(File.pathSeparator, zipPaths);
-
-                Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
-                sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey,
-                                             Build.SUPPORTED_ABIS[0]);
-            }
+            sZygote.preloadApp(sPackage.applicationInfo, abi);
         } catch (Exception e) {
             Log.e(LOGTAG, "Error connecting to webview zygote", e);
             stopZygoteLocked();
diff --git a/core/java/android/widget/TEST_MAPPING b/core/java/android/widget/TEST_MAPPING
index ee378ff..99a6cdc 100644
--- a/core/java/android/widget/TEST_MAPPING
+++ b/core/java/android/widget/TEST_MAPPING
@@ -1,12 +1,7 @@
 {
-  "presubmit": [
+  "imports": [
     {
-      "name": "CtsWidgetTestCases",
-      "options": [
-        {
-          "instrumentation-arg": "size:=small"
-        }
-      ]
+      "path": "cts/tests/tests/widget"
     }
   ]
 }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a5a1a80c..a961783 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10081,7 +10081,7 @@
     }
 
     /**
-     * Return true iff there is a selection inside this text view.
+     * Return true iff there is a selection of nonzero length inside this text view.
      */
     public boolean hasSelection() {
         final int selectionStart = getSelectionStart();
diff --git a/core/java/com/android/internal/app/AbstractResolverComparator.java b/core/java/com/android/internal/app/AbstractResolverComparator.java
index 3576b6b..e091aac 100644
--- a/core/java/com/android/internal/app/AbstractResolverComparator.java
+++ b/core/java/com/android/internal/app/AbstractResolverComparator.java
@@ -1,7 +1,15 @@
 package com.android.internal.app;
 
+import android.app.usage.UsageStatsManager;
 import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.util.Log;
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
+import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 
@@ -10,20 +18,102 @@
  */
 abstract class AbstractResolverComparator implements Comparator<ResolvedComponentInfo> {
 
+    private static final int NUM_OF_TOP_ANNOTATIONS_TO_USE = 3;
+
     protected AfterCompute mAfterCompute;
+    protected final PackageManager mPm;
+    protected final UsageStatsManager mUsm;
+    protected String[] mAnnotations;
+    protected String mContentType;
+
+    // True if the current share is a link.
+    private final boolean mHttp;
+    // can be null if mHttp == false or current user has no default browser package
+    private final String mDefaultBrowserPackageName;
+
+    AbstractResolverComparator(Context context, Intent intent) {
+        String scheme = intent.getScheme();
+        mHttp = "http".equals(scheme) || "https".equals(scheme);
+        mContentType = intent.getType();
+        getContentAnnotations(intent);
+
+        mPm = context.getPackageManager();
+        mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
+        mDefaultBrowserPackageName = mHttp
+                ? mPm.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId())
+                : null;
+    }
+
+    // get annotations of content from intent.
+    private void getContentAnnotations(Intent intent) {
+        ArrayList<String> annotations = intent.getStringArrayListExtra(
+                Intent.EXTRA_CONTENT_ANNOTATIONS);
+        if (annotations != null) {
+            int size = annotations.size();
+            if (size > NUM_OF_TOP_ANNOTATIONS_TO_USE) {
+                size = NUM_OF_TOP_ANNOTATIONS_TO_USE;
+            }
+            mAnnotations = new String[size];
+            for (int i = 0; i < size; i++) {
+                mAnnotations[i] = annotations.get(i);
+            }
+        }
+    }
 
     /**
      * Callback to be called when {@link #compute(List)} finishes. This signals to stop waiting.
      */
-    public interface AfterCompute {
+    interface AfterCompute {
 
-        public void afterCompute();
+        void afterCompute();
     }
 
-    public void setCallBack(AfterCompute afterCompute) {
+    void setCallBack(AfterCompute afterCompute) {
         mAfterCompute = afterCompute;
     }
 
+    @Override
+    public final int compare(ResolvedComponentInfo lhsp, ResolvedComponentInfo rhsp) {
+        final ResolveInfo lhs = lhsp.getResolveInfoAt(0);
+        final ResolveInfo rhs = rhsp.getResolveInfoAt(0);
+
+        // We want to put the one targeted to another user at the end of the dialog.
+        if (lhs.targetUserId != UserHandle.USER_CURRENT) {
+            return rhs.targetUserId != UserHandle.USER_CURRENT ? 0 : 1;
+        }
+        if (rhs.targetUserId != UserHandle.USER_CURRENT) {
+            return -1;
+        }
+
+        if (mHttp) {
+            // Special case: we want filters that match URI paths/schemes to be
+            // ordered before others.  This is for the case when opening URIs,
+            // to make native apps go above browsers - except for 1 even more special case
+            // which is the default browser, as we want that to go above them all.
+            if (isDefaultBrowser(lhs)) {
+                return -1;
+            }
+
+            if (isDefaultBrowser(rhs)) {
+                return 1;
+            }
+            final boolean lhsSpecific = ResolverActivity.isSpecificUriMatch(lhs.match);
+            final boolean rhsSpecific = ResolverActivity.isSpecificUriMatch(rhs.match);
+            if (lhsSpecific != rhsSpecific) {
+                return lhsSpecific ? -1 : 1;
+            }
+        }
+        return compare(lhs, rhs);
+    }
+
+    /**
+     * Delegated to when used as a {@link Comparator<ResolvedComponentInfo>} if there is not a
+     * special case. The {@link ResolveInfo ResolveInfos} are the first {@link ResolveInfo} in
+     * {@link ResolvedComponentInfo#getResolveInfoAt(int)} from the parameters of {@link
+     * #compare(ResolvedComponentInfo, ResolvedComponentInfo)}
+     */
+    abstract int compare(ResolveInfo lhs, ResolveInfo rhs);
+
     /**
      * Computes features for each target. This will be called before calls to {@link
      * #getScore(ComponentName)} or {@link #compare(Object, Object)}, in order to prepare the
@@ -31,19 +121,22 @@
      * ComponentName}, so the implementation will have to be prepared to identify a {@link
      * ResolvedComponentInfo} by {@link ComponentName}.
      */
-    public abstract void compute(List<ResolvedComponentInfo> targets);
+    abstract void compute(List<ResolvedComponentInfo> targets);
 
     /**
      * Returns the score that was calculated for the corresponding {@link ResolvedComponentInfo}
      * when {@link #compute(List)} was called before this.
      */
-    public abstract float getScore(ComponentName name);
+    abstract float getScore(ComponentName name);
 
     /**
      * Reports to UsageStats what was chosen.
      */
-    // TODO(b/129014961) Move implemetation here and make final.
-    public abstract void updateChooserCounts(String packageName, int userId, String action);
+    final void updateChooserCounts(String packageName, int userId, String action) {
+        if (mUsm != null) {
+            mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action);
+        }
+    }
 
     /**
      * Updates the model used to rank the componentNames.
@@ -53,11 +146,25 @@
      *
      * @param componentName the component that the user clicked
      */
-    public void updateModel(ComponentName componentName) {
+    void updateModel(ComponentName componentName) {
     }
 
     /**
      * Called when the {@link ResolverActivity} is destroyed.
      */
-    public abstract void destroy();
+    abstract void destroy();
+
+    private boolean isDefaultBrowser(ResolveInfo ri) {
+        // It makes sense to prefer the default browser
+        // only if the targeted user is the current user
+        if (ri.targetUserId != UserHandle.USER_CURRENT) {
+            return false;
+        }
+
+        if (ri.activityInfo.packageName != null
+                    && ri.activityInfo.packageName.equals(mDefaultBrowserPackageName)) {
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 4f5678a..a1d0cdc 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -24,7 +24,6 @@
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.annotation.IntDef;
-import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.prediction.AppPredictionContext;
@@ -163,6 +162,8 @@
      */
     private static final int NO_DIRECT_SHARE_ANIM_IN_MILLIS = 200;
 
+    private static final float DIRECT_SHARE_EXPANSION_RATE = 0.7f;
+
     // TODO(b/121287224): Re-evaluate this limit
     private static final int SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
 
@@ -186,7 +187,10 @@
     private Drawable mChooserRowLayer;
     private int mChooserRowServiceSpacing;
 
+    /** {@link ChooserActivity#getBaseScore} */
     private static final float CALLER_TARGET_SCORE_BOOST = 900.f;
+    /** {@link ChooserActivity#getBaseScore} */
+    private static final float SHORTCUT_TARGET_SCORE_BOOST = 10.f;
     private static final String TARGET_DETAILS_FRAGMENT_TAG = "targetDetailsFragment";
 
     private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>();
@@ -195,6 +199,11 @@
     private static final int CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT = 2;
     private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT = 3;
     private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 4;
+    private static final int LIST_VIEW_UPDATE_MESSAGE = 5;
+
+    private static final int LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS = 250;
+
+    private boolean mListViewDataChanged = false;
 
     @Retention(SOURCE)
     @IntDef({CONTENT_PREVIEW_FILE, CONTENT_PREVIEW_IMAGE, CONTENT_PREVIEW_TEXT})
@@ -211,10 +220,13 @@
     private final Handler mChooserHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
+            if (mChooserListAdapter == null || isDestroyed()) {
+                return;
+            }
+
             switch (msg.what) {
                 case CHOOSER_TARGET_SERVICE_RESULT:
                     if (DEBUG) Log.d(TAG, "CHOOSER_TARGET_SERVICE_RESULT");
-                    if (isDestroyed()) break;
                     final ServiceResultInfo sri = (ServiceResultInfo) msg.obj;
                     if (!mServiceConnections.contains(sri.connection)) {
                         Log.w(TAG, "ChooserTargetServiceConnection " + sri.connection
@@ -224,7 +236,7 @@
                     }
                     if (sri.resultTargets != null) {
                         mChooserListAdapter.addServiceResults(sri.originalTarget,
-                                sri.resultTargets);
+                                sri.resultTargets, false);
                     }
                     unbindService(sri.connection);
                     sri.connection.destroy();
@@ -238,21 +250,26 @@
                     if (DEBUG) {
                         Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
                     }
-                    if (mChooserListAdapter == null || isDestroyed()) {
-                        break;
-                    }
+
                     unbindRemainingServices();
                     sendVoiceChoicesIfNeeded();
                     mChooserListAdapter.completeServiceTargetLoading();
                     break;
 
+                case LIST_VIEW_UPDATE_MESSAGE:
+                    if (DEBUG) {
+                        Log.d(TAG, "LIST_VIEW_UPDATE_MESSAGE; ");
+                    }
+
+                    mChooserListAdapter.refreshListView();
+                    break;
+
                 case SHORTCUT_MANAGER_SHARE_TARGET_RESULT:
                     if (DEBUG) Log.d(TAG, "SHORTCUT_MANAGER_SHARE_TARGET_RESULT");
-                    if (isDestroyed()) break;
                     final ServiceResultInfo resultInfo = (ServiceResultInfo) msg.obj;
                     if (resultInfo.resultTargets != null) {
                         mChooserListAdapter.addServiceResults(resultInfo.originalTarget,
-                                resultInfo.resultTargets);
+                                resultInfo.resultTargets, true);
                     }
                     break;
 
@@ -435,9 +452,13 @@
         mChooserRowServiceSpacing = getResources()
                                         .getDimensionPixelSize(R.dimen.chooser_service_spacing);
 
-        // expand/shrink direct share 4 -> 8 viewgroup
-        if (mResolverDrawerLayout != null && isSendAction(target)) {
-            mResolverDrawerLayout.setOnScrollChangeListener(this::handleScroll);
+        if (mResolverDrawerLayout != null) {
+            mResolverDrawerLayout.addOnLayoutChangeListener(this::handleLayoutChange);
+
+            // expand/shrink direct share 4 -> 8 viewgroup
+            if (isSendAction(target)) {
+                mResolverDrawerLayout.setOnScrollChangeListener(this::handleScroll);
+            }
         }
 
         if (DEBUG) {
@@ -823,6 +844,7 @@
             mRefinementResultReceiver = null;
         }
         unbindRemainingServices();
+        mChooserHandler.removeMessages(LIST_VIEW_UPDATE_MESSAGE);
         mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
         mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
         if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
@@ -875,21 +897,13 @@
         final ListView listView = adapterView instanceof ListView ? (ListView) adapterView : null;
         mChooserListAdapter = (ChooserListAdapter) adapter;
         if (mCallerChooserTargets != null && mCallerChooserTargets.length > 0) {
-            mChooserListAdapter.addServiceResults(null, Lists.newArrayList(mCallerChooserTargets));
+            mChooserListAdapter.addServiceResults(null, Lists.newArrayList(mCallerChooserTargets),
+                    false);
         }
         mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter);
-        mChooserRowAdapter.registerDataSetObserver(new OffsetDataSetObserver(adapterView));
         if (listView != null) {
             listView.setItemsCanFocus(true);
-            listView.addOnLayoutChangeListener(
-                    (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
-                        if (mChooserRowAdapter.calculateMaxTargetsPerRow(right - left)) {
-                            adapterView.setAdapter(mChooserRowAdapter);
-                        }
-                    });
         }
-
-        adapterView.setAdapter(mChooserRowAdapter);
     }
 
     @Override
@@ -928,8 +942,6 @@
         if (isSendAction(in)) {
             in.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-
-            in.fixUris(getUserId());
         }
     }
 
@@ -1197,7 +1209,7 @@
                 null,
                 // The ranking score for this target (0.0-1.0); the system will omit items with low
                 // scores when there are too many Direct Share items.
-                0.5f,
+                1.0f,
                 // The name of the component to be launched if this target is chosen.
                 shareShortcut.getTargetComponent().clone(),
                 // The extra values here will be merged into the Intent when this target is chosen.
@@ -1386,15 +1398,6 @@
             }
             return false;
         }
-
-        @Override
-        public float getScore(DisplayResolveInfo target) {
-            if (target == null) {
-                return CALLER_TARGET_SCORE_BOOST;
-            }
-
-            return super.getScore(target);
-        }
     }
 
     @Override
@@ -1483,7 +1486,7 @@
         }
 
         public float getModifiedScore() {
-            return 0.1f;
+            return -0.1f;
         }
 
         public ChooserTarget getChooserTarget() {
@@ -1597,7 +1600,7 @@
             if (info == null) return null;
 
             // Now fetch app icon and raster with no badging even in work profile
-            Bitmap appIcon = (new ActivityInfoPresentationGetter(info)).getIconBitmap();
+            Bitmap appIcon = makePresentationGetter(info).getIconBitmap();
 
             // Raster target drawable with appIcon as a badge
             SimpleIconFactory sif = SimpleIconFactory.obtain(ChooserActivity.this);
@@ -1728,6 +1731,66 @@
         }
     }
 
+    /*
+     * Need to dynamically adjust how many icons can fit per row before we add them,
+     * which also means setting the correct offset to initially show the content
+     * preview area + 2 rows of targets
+     */
+    private void handleLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
+            int oldTop, int oldRight, int oldBottom) {
+        if (mChooserRowAdapter == null || mAdapterView == null) {
+            return;
+        }
+
+        if (mChooserRowAdapter.calculateMaxTargetsPerRow(right - left)
+                || mAdapterView.getAdapter() == null) {
+            mAdapterView.setAdapter(mChooserRowAdapter);
+
+            getMainThreadHandler().post(() -> {
+                if (mResolverDrawerLayout == null || mChooserRowAdapter == null) {
+                    return;
+                }
+
+                int offset = 0;
+                int rowsToShow = mChooserRowAdapter.getContentPreviewRowCount()
+                        + mChooserRowAdapter.getServiceTargetRowCount()
+                        + mChooserRowAdapter.getCallerTargetRowCount();
+
+                // then this is most likely not a SEND_* action, so check
+                // the app target count
+                if (rowsToShow == 0) {
+                    rowsToShow = mChooserRowAdapter.getCount();
+                }
+
+                // still zero? then use a default height and leave, which
+                // can happen when there are no targets to show
+                if (rowsToShow == 0) {
+                    offset = getResources().getDimensionPixelSize(
+                            R.dimen.chooser_max_collapsed_height);
+                    mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
+                    return;
+                }
+
+                int lastHeight = 0;
+                rowsToShow = Math.max(3, rowsToShow);
+                for (int i = 0; i < Math.min(rowsToShow, mAdapterView.getChildCount()); i++) {
+                    lastHeight = mAdapterView.getChildAt(i).getHeight();
+                    offset += lastHeight;
+                }
+
+                if (lastHeight != 0 && isSendAction(getTargetIntent())) {
+                    // make sure to leave room for direct share 4->8 expansion
+                    int expansionArea =
+                            (int) (mResolverDrawerLayout.getUncollapsibleHeight()
+                                    / DIRECT_SHARE_EXPANSION_RATE);
+                    offset = Math.min(offset, bottom - top - lastHeight - expansionArea);
+                }
+
+                mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
+            });
+        }
+    }
+
     public class ChooserListAdapter extends ResolveListAdapter {
         public static final int TARGET_BAD = -1;
         public static final int TARGET_CALLER = 0;
@@ -1745,8 +1808,6 @@
         private final List<TargetInfo> mCallerTargets = new ArrayList<>();
         private boolean mShowServiceTargets;
 
-        private float mLateFee = 1.f;
-
         private boolean mTargetsNeedPruning = false;
 
         private final BaseChooserTargetComparator mBaseTargetComparator
@@ -1808,12 +1869,30 @@
                         ri.noResourceId = true;
                         ri.icon = 0;
                     }
+                    ResolveInfoPresentationGetter getter = makePresentationGetter(ri);
                     mCallerTargets.add(new DisplayResolveInfo(ii, ri,
-                            ri.loadLabel(pm), null, ii));
+                            getter.getLabel(), getter.getSubLabel(), ii));
                 }
             }
         }
 
+        @Override
+        public void notifyDataSetChanged() {
+            if (!mListViewDataChanged) {
+                mChooserHandler.sendEmptyMessageDelayed(LIST_VIEW_UPDATE_MESSAGE,
+                        LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+                mListViewDataChanged = true;
+            }
+        }
+
+        private void refreshListView() {
+            if (mListViewDataChanged) {
+                super.notifyDataSetChanged();
+            }
+            mListViewDataChanged = false;
+        }
+
+
         private void createPlaceHolders() {
             mServiceTargets.clear();
             for (int i = 0; i < MAX_SERVICE_TARGETS; i++) {
@@ -1822,12 +1901,6 @@
         }
 
         @Override
-        public boolean showsExtendedInfo(TargetInfo info) {
-            // We have badges so we don't need this text shown.
-            return false;
-        }
-
-        @Override
         public View onCreateView(ViewGroup parent) {
             return mInflater.inflate(
                     com.android.internal.R.layout.resolve_grid_item, parent, false);
@@ -1841,7 +1914,7 @@
             }
 
             if (mServiceTargets != null) {
-                if (getDisplayInfoCount() == 0) {
+                if (getDisplayResolveInfoCount() == 0) {
                     // b/109676071: When packages change, onListRebuilt() is called before
                     // ResolverActivity.mDisplayList is re-populated; pruning now would cause the
                     // list to disappear briefly, so instead we detect this case (the
@@ -1854,12 +1927,14 @@
                 if (DEBUG) {
                     Log.d(TAG, "querying direct share targets from ShortcutManager");
                 }
+
                 queryDirectShareTargets(this);
             }
             if (USE_CHOOSER_TARGET_SERVICE_FOR_DIRECT_TARGETS) {
                 if (DEBUG) {
                     Log.d(TAG, "List built querying services");
                 }
+
                 queryTargetServices(this);
             }
         }
@@ -1955,16 +2030,25 @@
             offset += callerTargetCount;
 
             return filtered ? super.getItem(position - offset)
-                    : getDisplayInfoAt(position - offset);
+                    : getDisplayResolveInfo(position - offset);
         }
 
-        public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets) {
+        /**
+         * Evaluate targets for inclusion in the direct share area. May not be included
+         * if score is too low.
+         */
+        public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets,
+                boolean isShortcutResult) {
             if (DEBUG) {
                 Log.d(TAG, "addServiceResults " + origTarget + ", " + targets.size()
                         + " targets");
             }
 
-            if (mTargetsNeedPruning && targets.size() > 0) {
+            if (targets.size() == 0) {
+                return;
+            }
+
+            if (mTargetsNeedPruning) {
                 // First proper update since we got an onListRebuilt() with (transient) 0 items.
                 // Clear out the target list and rebuild.
                 createPlaceHolders();
@@ -1973,39 +2057,64 @@
                 // Add back any app-supplied direct share targets that may have been
                 // wiped by this clear
                 if (mCallerChooserTargets != null) {
-                    addServiceResults(null, Lists.newArrayList(mCallerChooserTargets));
+                    addServiceResults(null, Lists.newArrayList(mCallerChooserTargets), false);
                 }
             }
 
-            final float parentScore = getScore(origTarget);
+            final float baseScore = getBaseScore(origTarget, isShortcutResult);
             Collections.sort(targets, mBaseTargetComparator);
             float lastScore = 0;
+            boolean shouldNotify = false;
             for (int i = 0, N = Math.min(targets.size(), MAX_TARGETS_PER_SERVICE); i < N; i++) {
                 final ChooserTarget target = targets.get(i);
                 float targetScore = target.getScore();
-                targetScore *= parentScore;
-                targetScore *= mLateFee;
+                targetScore *= baseScore;
                 if (i > 0 && targetScore >= lastScore) {
                     // Apply a decay so that the top app can't crowd out everything else.
                     // This incents ChooserTargetServices to define what's truly better.
                     targetScore = lastScore * 0.95f;
                 }
-                insertServiceTarget(new SelectableTargetInfo(origTarget, target, targetScore));
+                shouldNotify |= insertServiceTarget(
+                        new SelectableTargetInfo(origTarget, target, targetScore));
 
                 if (DEBUG) {
                     Log.d(TAG, " => " + target.toString() + " score=" + targetScore
                             + " base=" + target.getScore()
                             + " lastScore=" + lastScore
-                            + " parentScore=" + parentScore
-                            + " lateFee=" + mLateFee);
+                            + " baseScore=" + baseScore);
                 }
 
                 lastScore = targetScore;
             }
 
-            mLateFee *= 0.95f;
+            if (shouldNotify) {
+                notifyDataSetChanged();
+            }
+        }
 
-            notifyDataSetChanged();
+        /**
+          * Use the scoring system along with artificial boosts to create up to 3 distinct buckets:
+          * <ol>
+          *   <li>App-supplied targets
+          *   <li>Prediction manager targets or Shortcut API targets
+          *   <li>Legacy direct share targets
+          * </ol>
+          */
+        private float getBaseScore(DisplayResolveInfo target, boolean isShortcutResult) {
+            if (target == null) {
+                return CALLER_TARGET_SCORE_BOOST;
+            }
+
+            if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
+                return SHORTCUT_TARGET_SCORE_BOOST;
+            }
+
+            float score = super.getScore(target);
+            if (isShortcutResult) {
+                return score * SHORTCUT_TARGET_SCORE_BOOST;
+            }
+
+            return score;
         }
 
         /**
@@ -2021,25 +2130,32 @@
             notifyDataSetChanged();
         }
 
-        private void insertServiceTarget(ChooserTargetInfo chooserTargetInfo) {
+        private boolean insertServiceTarget(ChooserTargetInfo chooserTargetInfo) {
             // Avoid inserting any potentially late results
             if (mServiceTargets.size() == 1
                     && mServiceTargets.get(0) instanceof EmptyTargetInfo) {
-                return;
+                return false;
             }
 
             final float newScore = chooserTargetInfo.getModifiedScore();
-            for (int i = 0, N = mServiceTargets.size(); i < N; i++) {
+            int currentSize = mServiceTargets.size();
+            for (int i = 0; i < Math.min(currentSize, MAX_SERVICE_TARGETS); i++) {
                 final ChooserTargetInfo serviceTarget = mServiceTargets.get(i);
                 if (serviceTarget == null) {
                     mServiceTargets.set(i, chooserTargetInfo);
-                    return;
+                    return true;
                 } else if (newScore > serviceTarget.getModifiedScore()) {
                     mServiceTargets.add(i, chooserTargetInfo);
-                    return;
+                    return true;
                 }
             }
-            mServiceTargets.add(chooserTargetInfo);
+
+            if (currentSize < MAX_SERVICE_TARGETS) {
+                mServiceTargets.add(chooserTargetInfo);
+                return true;
+            }
+
+            return false;
         }
     }
 
@@ -2244,8 +2360,10 @@
             final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
             int columnCount = holder.getColumnCount();
 
+            final boolean isDirectShare = holder instanceof DirectShareViewHolder;
+
             for (int i = 0; i < columnCount; i++) {
-                final View v = mChooserListAdapter.createView(holder.getRow(i));
+                final View v = mChooserListAdapter.createView(holder.getRowByIndex(i));
                 final int column = i;
                 v.setOnClickListener(new OnClickListener() {
                     @Override
@@ -2264,27 +2382,31 @@
                 });
                 ViewGroup row = holder.addView(i, v);
 
-                // Force height to be a given so we don't have visual disruption during scaling.
-                LayoutParams lp = v.getLayoutParams();
-                v.measure(spec, spec);
-                if (lp == null) {
-                    lp = new LayoutParams(LayoutParams.MATCH_PARENT, v.getMeasuredHeight());
-                    row.setLayoutParams(lp);
-                } else {
-                    lp.height = v.getMeasuredHeight();
+                // Force Direct Share to be 2 lines and auto-wrap to second line via hoz scroll =
+                // false. TextView#setHorizontallyScrolling must be reset after #setLines. Must be
+                // done before measuring.
+                if (isDirectShare) {
+                    final ViewHolder vh = (ViewHolder) v.getTag();
+                    vh.text.setLines(2);
+                    vh.text.setHorizontallyScrolling(false);
+                    vh.text2.setVisibility(View.GONE);
                 }
+
+                // Force height to be a given so we don't have visual disruption during scaling.
+                v.measure(spec, spec);
+                setViewHeight(v, v.getMeasuredHeight());
             }
 
             final ViewGroup viewGroup = holder.getViewGroup();
 
-            // Pre-measure so we can scale later.
+            // Pre-measure and fix height so we can scale later.
             holder.measure();
-            LayoutParams lp = viewGroup.getLayoutParams();
-            if (lp == null) {
-                lp = new LayoutParams(LayoutParams.MATCH_PARENT, holder.getMeasuredRowHeight());
-                viewGroup.setLayoutParams(lp);
-            } else {
-                lp.height = holder.getMeasuredRowHeight();
+            setViewHeight(viewGroup, holder.getMeasuredRowHeight());
+
+            if (isDirectShare) {
+                DirectShareViewHolder dsvh = (DirectShareViewHolder) holder;
+                setViewHeight(dsvh.getRow(0), holder.getMeasuredRowHeight());
+                setViewHeight(dsvh.getRow(1), holder.getMeasuredRowHeight());
             }
 
             viewGroup.setTag(holder);
@@ -2292,6 +2414,16 @@
             return holder;
         }
 
+        private void setViewHeight(View view, int heightPx) {
+            LayoutParams lp = view.getLayoutParams();
+            if (lp == null) {
+                lp = new LayoutParams(LayoutParams.MATCH_PARENT, heightPx);
+                view.setLayoutParams(lp);
+            } else {
+                lp.height = heightPx;
+            }
+        }
+
         RowViewHolder createViewHolder(int viewType, ViewGroup parent) {
             if (viewType == VIEW_TYPE_DIRECT_SHARE) {
                 ViewGroup parentGroup = (ViewGroup) mLayoutInflater.inflate(
@@ -2329,7 +2461,7 @@
 
             if (startType != lastStartType || rowPosition == getContentPreviewRowCount()) {
                 row.setBackground(mChooserRowLayer);
-                setVertPadding(row, mChooserRowServiceSpacing, 0);
+                setVertPadding(row, 0, 0);
             } else {
                 row.setBackground(null);
                 setVertPadding(row, 0, 0);
@@ -2426,7 +2558,9 @@
 
         abstract ViewGroup getViewGroup();
 
-        abstract ViewGroup getRow(int index);
+        abstract ViewGroup getRowByIndex(int index);
+
+        abstract ViewGroup getRow(int rowNumber);
 
         abstract void setViewVisibility(int i, int visibility);
 
@@ -2475,10 +2609,15 @@
             return mRow;
         }
 
-        public ViewGroup getRow(int index) {
+        public ViewGroup getRowByIndex(int index) {
             return mRow;
         }
 
+        public ViewGroup getRow(int rowNumber) {
+            if (rowNumber == 0) return mRow;
+            return null;
+        }
+
         public ViewGroup addView(int index, View v) {
             mRow.addView(v);
             mCells[index] = v;
@@ -2517,7 +2656,7 @@
         }
 
         public ViewGroup addView(int index, View v) {
-            ViewGroup row = getRow(index);
+            ViewGroup row = getRowByIndex(index);
             row.addView(v);
             mCells[index] = v;
 
@@ -2532,16 +2671,19 @@
             return mParent;
         }
 
-        public ViewGroup getRow(int index) {
+        public ViewGroup getRowByIndex(int index) {
             return mRows.get(index / mCellCountPerRow);
         }
 
+        public ViewGroup getRow(int rowNumber) {
+            return mRows.get(rowNumber);
+        }
+
         public void measure() {
             final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
             getRow(0).measure(spec, spec);
             getRow(1).measure(spec, spec);
 
-            // uses ChooserActiivty state variables to track height
             mDirectShareMinHeight = getRow(0).getMeasuredHeight();
             mDirectShareCurrHeight = mDirectShareCurrHeight > 0
                                          ? mDirectShareCurrHeight : mDirectShareMinHeight;
@@ -2574,18 +2716,18 @@
         }
 
         public void handleScroll(AbsListView view, int y, int oldy, int maxTargetsPerRow) {
-            // only expand if we have more than 4 targets, and delay that decision until
-            // they start to scroll
             if (mHideDirectShareExpansion) {
                 return;
             }
 
+            // only expand if we have more than maxTargetsPerRow, and delay that decision
+            // until they start to scroll
             if (mChooserListAdapter.getSelectableServiceTargetCount() <= maxTargetsPerRow) {
                 mHideDirectShareExpansion = true;
                 return;
             }
 
-            int yDiff = (int) ((oldy - y) * 0.7f);
+            int yDiff = (int) ((oldy - y) * DIRECT_SHARE_EXPANSION_RATE);
 
             int prevHeight = mDirectShareCurrHeight;
             mDirectShareCurrHeight = Math.min(mDirectShareCurrHeight + yDiff,
@@ -2593,27 +2735,31 @@
             mDirectShareCurrHeight = Math.max(mDirectShareCurrHeight, mDirectShareMinHeight);
             yDiff = mDirectShareCurrHeight - prevHeight;
 
-            if (view == null || view.getChildCount() == 0) {
+            if (view == null || view.getChildCount() == 0 || yDiff == 0) {
                 return;
             }
 
-            int index = mChooserRowAdapter.getContentPreviewRowCount();
+            // locate the item to expand, and offset the rows below that one
+            boolean foundExpansion = false;
+            for (int i = 0; i < view.getChildCount(); i++) {
+                View child = view.getChildAt(i);
 
-            ViewGroup expansionGroup = (ViewGroup) view.getChildAt(index);
-            int widthSpec = MeasureSpec.makeMeasureSpec(expansionGroup.getWidth(),
-                    MeasureSpec.EXACTLY);
-            int heightSpec = MeasureSpec.makeMeasureSpec(mDirectShareCurrHeight,
-                    MeasureSpec.EXACTLY);
-            expansionGroup.measure(widthSpec, heightSpec);
-            expansionGroup.getLayoutParams().height = expansionGroup.getMeasuredHeight();
-            expansionGroup.layout(expansionGroup.getLeft(), expansionGroup.getTop(),
-                    expansionGroup.getRight(),
-                    expansionGroup.getTop() + expansionGroup.getMeasuredHeight());
+                if (foundExpansion) {
+                    child.offsetTopAndBottom(yDiff);
+                } else {
+                    if (child.getTag() != null && child.getTag() instanceof DirectShareViewHolder) {
+                        int widthSpec = MeasureSpec.makeMeasureSpec(child.getWidth(),
+                                MeasureSpec.EXACTLY);
+                        int heightSpec = MeasureSpec.makeMeasureSpec(mDirectShareCurrHeight,
+                                MeasureSpec.EXACTLY);
+                        child.measure(widthSpec, heightSpec);
+                        child.getLayoutParams().height = child.getMeasuredHeight();
+                        child.layout(child.getLeft(), child.getTop(), child.getRight(),
+                                child.getTop() + child.getMeasuredHeight());
 
-            // reposition list items
-            int items = view.getChildCount();
-            for (int i = index + 1; i < items; i++) {
-                view.getChildAt(i).offsetTopAndBottom(yDiff);
+                        foundExpansion = true;
+                    }
+                }
             }
         }
     }
@@ -2771,47 +2917,6 @@
         }
     }
 
-    class OffsetDataSetObserver extends DataSetObserver {
-        private final AbsListView mListView;
-        private int mCachedViewType = -1;
-        private View mCachedView;
-
-        public OffsetDataSetObserver(AbsListView listView) {
-            mListView = listView;
-        }
-
-        @Override
-        public void onChanged() {
-            if (mResolverDrawerLayout == null) {
-                return;
-            }
-
-            final int chooserTargetRows = mChooserRowAdapter.getServiceTargetRowCount();
-            int offset = 0;
-            for (int i = 0; i < chooserTargetRows; i++) {
-                final int pos = mChooserRowAdapter.getContentPreviewRowCount() + i;
-                final int vt = mChooserRowAdapter.getItemViewType(pos);
-                if (vt != mCachedViewType) {
-                    mCachedView = null;
-                }
-                final View v = mChooserRowAdapter.getView(pos, mCachedView, mListView);
-                int height = ((RowViewHolder) (v.getTag())).getMeasuredRowHeight();
-
-                offset += (int) (height);
-
-                if (vt >= 0) {
-                    mCachedViewType = vt;
-                    mCachedView = v;
-                } else {
-                    mCachedViewType = -1;
-                }
-            }
-
-            mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
-        }
-    }
-
-
     /**
      * Used internally to round image corners while obeying view padding.
      */
diff --git a/core/java/com/android/internal/app/DumpHeapActivity.java b/core/java/com/android/internal/app/DumpHeapActivity.java
index 0ce501e..e04e870 100644
--- a/core/java/com/android/internal/app/DumpHeapActivity.java
+++ b/core/java/com/android/internal/app/DumpHeapActivity.java
@@ -37,6 +37,10 @@
     public static final String KEY_PROCESS = "process";
     /** The size limit the process reached */
     public static final String KEY_SIZE = "size";
+    /** Whether the user initiated the dump or not. */
+    public static final String KEY_IS_USER_INITIATED = "is_user_initiated";
+    /** Whether the process is a system process (eg: Android System) or not. */
+    public static final String KEY_IS_SYSTEM_PROCESS = "is_system_process";
     /** Optional name of package to directly launch */
     public static final String KEY_DIRECT_LAUNCH = "direct_launch";
 
@@ -59,6 +63,8 @@
 
         mProcess = getIntent().getStringExtra(KEY_PROCESS);
         mSize = getIntent().getLongExtra(KEY_SIZE, 0);
+        final boolean isUserInitiated = getIntent().getBooleanExtra(KEY_IS_USER_INITIATED, false);
+        final boolean isSystemProcess = getIntent().getBooleanExtra(KEY_IS_SYSTEM_PROCESS, false);
 
         String directLaunch = getIntent().getStringExtra(KEY_DIRECT_LAUNCH);
         if (directLaunch != null) {
@@ -81,11 +87,19 @@
             }
         }
 
+        final int messageId;
+        if (isUserInitiated) {
+            messageId = com.android.internal.R.string.dump_heap_ready_text;
+        } else if (isSystemProcess) {
+            messageId = com.android.internal.R.string.dump_heap_system_text;
+        } else {
+            messageId = com.android.internal.R.string.dump_heap_text;
+        }
         AlertDialog.Builder b = new AlertDialog.Builder(this,
                 android.R.style.Theme_Material_Light_Dialog_Alert);
         b.setTitle(com.android.internal.R.string.dump_heap_title);
-        b.setMessage(getString(com.android.internal.R.string.dump_heap_text,
-                mProcess, DebugUtils.sizeValueToString(mSize, null)));
+        b.setMessage(getString(
+                messageId, mProcess, DebugUtils.sizeValueToString(mSize, null)));
         b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
             @Override
             public void onClick(DialogInterface dialog, int which) {
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 1c90182..72dbbf3 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -26,8 +26,9 @@
 import com.android.internal.app.IAppOpsNotedCallback;
 
 interface IAppOpsService {
-    // These first methods are also called by native code, so must
+    // These methods are also called by native code, so must
     // be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsService.h
+    // and not be reordered
     int checkOperation(int code, int uid, String packageName);
     int noteOperation(int code, int uid, String packageName);
     int startOperation(IBinder token, int code, int uid, String packageName,
@@ -38,6 +39,10 @@
     void stopWatchingMode(IAppOpsCallback callback);
     IBinder getToken(IBinder clientToken);
     int permissionToOpCode(String permission);
+    int checkAudioOperation(int code, int usage, int uid, String packageName);
+    // End of methods also called by native code.
+    // Any new method exposed to native must be added after the last one, do not reorder
+
     int noteProxyOperation(int code, int proxyUid, String proxyPackageName,
                 int callingUid, String callingPackageName);
 
@@ -62,7 +67,6 @@
     void setMode(int code, int uid, String packageName, int mode);
     @UnsupportedAppUsage
     void resetAllModes(int reqUserId, String reqPackageName);
-    int checkAudioOperation(int code, int usage, int uid, String packageName);
     void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages);
 
     void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle);
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 3811fe4..a5f055f 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -115,6 +115,7 @@
                 // At this point, innerIntent is not null. Otherwise, canForward would have returned
                 // false.
                 innerIntent.prepareToLeaveUser(callingUserId);
+                innerIntent.fixUris(callingUserId);
             } else {
                 newIntent.prepareToLeaveUser(callingUserId);
             }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 84a1bed..f671a75 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -83,7 +83,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
@@ -499,33 +498,41 @@
 
 
     /**
-     * Loads the icon for the provided ApplicationInfo. Defaults to using the application icon over
-     * any IntentFilter or Activity icon to increase user understanding, with an exception for
-     * applications that hold the right permission. Always attempts to use icon resources over
-     * PackageManager loading mechanisms so badging can be done by iconloader.
+     * Loads the icon and label for the provided ApplicationInfo. Defaults to using the application
+     * icon and label over any IntentFilter or Activity icon to increase user understanding, with an
+     * exception for applications that hold the right permission. Always attempts to use available
+     * resources over PackageManager loading mechanisms so badging can be done by iconloader. Uses
+     * Strings to strip creative formatting.
      */
-    private abstract class TargetPresentationGetter {
-        @Nullable abstract Drawable getIconSubstitute();
-        @Nullable abstract String getAppSubLabel();
+    private abstract static class TargetPresentationGetter {
+        @Nullable abstract Drawable getIconSubstituteInternal();
+        @Nullable abstract String getAppSubLabelInternal();
 
-        private final ApplicationInfo mAi;
+        private Context mCtx;
+        private final int mIconDpi;
         private final boolean mHasSubstitutePermission;
+        private final ApplicationInfo mAi;
 
-        TargetPresentationGetter(ApplicationInfo ai) {
+        protected PackageManager mPm;
+
+        TargetPresentationGetter(Context ctx, int iconDpi, ApplicationInfo ai) {
+            mCtx = ctx;
+            mPm = ctx.getPackageManager();
             mAi = ai;
+            mIconDpi = iconDpi;
             mHasSubstitutePermission = PackageManager.PERMISSION_GRANTED == mPm.checkPermission(
                     android.Manifest.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON,
                     mAi.packageName);
         }
 
-        Drawable getIcon() {
-            return new BitmapDrawable(getResources(), getIconBitmap());
+        public Drawable getIcon() {
+            return new BitmapDrawable(mCtx.getResources(), getIconBitmap());
         }
 
-        Bitmap getIconBitmap() {
+        public Bitmap getIconBitmap() {
             Drawable dr = null;
             if (mHasSubstitutePermission) {
-                dr = getIconSubstitute();
+                dr = getIconSubstituteInternal();
             }
 
             if (dr == null) {
@@ -542,18 +549,18 @@
                 dr = mAi.loadIcon(mPm);
             }
 
-            SimpleIconFactory sif = SimpleIconFactory.obtain(ResolverActivity.this);
+            SimpleIconFactory sif = SimpleIconFactory.obtain(mCtx);
             Bitmap icon = sif.createUserBadgedIconBitmap(dr, Process.myUserHandle());
             sif.recycle();
 
             return icon;
         }
 
-        String getLabel() {
+        public String getLabel() {
             String label = null;
             // Apps with the substitute permission will always show the sublabel as their label
             if (mHasSubstitutePermission) {
-                label = getAppSubLabel();
+                label = getAppSubLabelInternal();
             }
 
             if (label == null) {
@@ -563,10 +570,14 @@
             return label;
         }
 
-        String getSubLabel() {
+        public String getSubLabel() {
             // Apps with the substitute permission will never have a sublabel
             if (mHasSubstitutePermission) return null;
-            return getAppSubLabel();
+            return getAppSubLabelInternal();
+        }
+
+        protected String loadLabelFromResource(Resources res, int resId) {
+            return res.getString(resId);
         }
 
         @Nullable
@@ -576,17 +587,19 @@
 
     }
 
-    protected class ResolveInfoPresentationGetter extends TargetPresentationGetter {
-
+    /**
+     * Loads the icon and label for the provided ResolveInfo.
+     */
+    @VisibleForTesting
+    public static class ResolveInfoPresentationGetter extends ActivityInfoPresentationGetter {
         private final ResolveInfo mRi;
-
-        ResolveInfoPresentationGetter(ResolveInfo ri) {
-            super(ri.activityInfo.applicationInfo);
+        public ResolveInfoPresentationGetter(Context ctx, int iconDpi, ResolveInfo ri) {
+            super(ctx, iconDpi, ri.activityInfo);
             mRi = ri;
         }
 
         @Override
-        Drawable getIconSubstitute() {
+        Drawable getIconSubstituteInternal() {
             Drawable dr = null;
             try {
                 // Do not use ResolveInfo#getIconResource() as it defaults to the app
@@ -599,24 +612,38 @@
                         + "couldn't find resources for package", e);
             }
 
+            // Fall back to ActivityInfo if no icon is found via ResolveInfo
+            if (dr == null) dr = super.getIconSubstituteInternal();
+
             return dr;
         }
 
         @Override
-        String getAppSubLabel() {
+        String getAppSubLabelInternal() {
+            // Will default to app name if no intent filter or activity label set, make sure to
+            // check if subLabel matches label before final display
             return (String) mRi.loadLabel(mPm);
         }
     }
 
-    protected class ActivityInfoPresentationGetter extends TargetPresentationGetter {
+    ResolveInfoPresentationGetter makePresentationGetter(ResolveInfo ri) {
+        return new ResolveInfoPresentationGetter(this, mIconDpi, ri);
+    }
+
+    /**
+     * Loads the icon and label for the provided ActivityInfo.
+     */
+    @VisibleForTesting
+    public static class ActivityInfoPresentationGetter extends TargetPresentationGetter {
         private final ActivityInfo mActivityInfo;
-        protected ActivityInfoPresentationGetter(ActivityInfo activityInfo) {
-            super(activityInfo.applicationInfo);
+        public ActivityInfoPresentationGetter(Context ctx, int iconDpi,
+                ActivityInfo activityInfo) {
+            super(ctx, iconDpi, activityInfo.applicationInfo);
             mActivityInfo = activityInfo;
         }
 
         @Override
-        Drawable getIconSubstitute() {
+        Drawable getIconSubstituteInternal() {
             Drawable dr = null;
             try {
                 // Do not use ActivityInfo#getIconResource() as it defaults to the app
@@ -634,13 +661,19 @@
         }
 
         @Override
-        String getAppSubLabel() {
+        String getAppSubLabelInternal() {
+            // Will default to app name if no activity label set, make sure to check if subLabel
+            // matches label before final display
             return (String) mActivityInfo.loadLabel(mPm);
         }
     }
 
+    protected ActivityInfoPresentationGetter makePresentationGetter(ActivityInfo ai) {
+        return new ActivityInfoPresentationGetter(this, mIconDpi, ai);
+    }
+
     Drawable loadIconForResolveInfo(ResolveInfo ri) {
-        return (new ResolveInfoPresentationGetter(ri)).getIcon();
+        return makePresentationGetter(ri).getIcon();
     }
 
     @Override
@@ -1201,7 +1234,7 @@
         final ImageView iconView = findViewById(R.id.icon);
         final DisplayResolveInfo iconInfo = mAdapter.getFilteredItem();
         if (iconView != null && iconInfo != null) {
-            new LoadIconIntoViewTask(iconInfo, iconView).execute();
+            new LoadIconTask(iconInfo, iconView).execute();
         }
     }
 
@@ -1713,34 +1746,13 @@
                     }
                 }
 
-                // Check for applications with same name and use application name or
-                // package name if necessary
-                ResolvedComponentInfo rci0 = sortedComponents.get(0);
-                ResolveInfo r0 = rci0.getResolveInfoAt(0);
-                int start = 0;
-                CharSequence r0Label = r0.loadLabel(mPm);
-                mHasExtendedInfo = false;
-                for (int i = 1; i < N; i++) {
-                    if (r0Label == null) {
-                        r0Label = r0.activityInfo.packageName;
+                for (ResolvedComponentInfo rci : sortedComponents) {
+                    final ResolveInfo ri = rci.getResolveInfoAt(0);
+                    if (ri != null) {
+                        ResolveInfoPresentationGetter pg = makePresentationGetter(ri);
+                        addResolveInfoWithAlternates(rci, pg.getSubLabel(), pg.getLabel());
                     }
-                    ResolvedComponentInfo rci = sortedComponents.get(i);
-                    ResolveInfo ri = rci.getResolveInfoAt(0);
-                    CharSequence riLabel = ri.loadLabel(mPm);
-                    if (riLabel == null) {
-                        riLabel = ri.activityInfo.packageName;
-                    }
-                    if (riLabel.equals(r0Label)) {
-                        continue;
-                    }
-                    processGroup(sortedComponents, start, (i - 1), rci0, r0Label);
-                    rci0 = rci;
-                    r0 = ri;
-                    r0Label = riLabel;
-                    start = i;
                 }
-                // Process last group
-                processGroup(sortedComponents, start, (N - 1), rci0, r0Label);
             }
 
             postListReadyRunnable();
@@ -1782,55 +1794,6 @@
             return mFilterLastUsed;
         }
 
-        private void processGroup(List<ResolvedComponentInfo> rList, int start, int end,
-                ResolvedComponentInfo ro, CharSequence roLabel) {
-            // Process labels from start to i
-            int num = end - start+1;
-            if (num == 1) {
-                // No duplicate labels. Use label for entry at start
-                addResolveInfoWithAlternates(ro, null, roLabel);
-            } else {
-                mHasExtendedInfo = true;
-                boolean usePkg = false;
-                final ApplicationInfo ai = ro.getResolveInfoAt(0).activityInfo.applicationInfo;
-                final CharSequence startApp = ai.loadLabel(mPm);
-                if (startApp == null) {
-                    usePkg = true;
-                }
-                if (!usePkg) {
-                    // Use HashSet to track duplicates
-                    HashSet<CharSequence> duplicates =
-                        new HashSet<CharSequence>();
-                    duplicates.add(startApp);
-                    for (int j = start+1; j <= end ; j++) {
-                        ResolveInfo jRi = rList.get(j).getResolveInfoAt(0);
-                        CharSequence jApp = jRi.activityInfo.applicationInfo.loadLabel(mPm);
-                        if ( (jApp == null) || (duplicates.contains(jApp))) {
-                            usePkg = true;
-                            break;
-                        } else {
-                            duplicates.add(jApp);
-                        }
-                    }
-                    // Clear HashSet for later use
-                    duplicates.clear();
-                }
-                for (int k = start; k <= end; k++) {
-                    final ResolvedComponentInfo rci = rList.get(k);
-                    final ResolveInfo add = rci.getResolveInfoAt(0);
-                    final CharSequence extraInfo;
-                    if (usePkg) {
-                        // Use package name for all entries from start to end-1
-                        extraInfo = add.activityInfo.packageName;
-                    } else {
-                        // Use application name for all entries from start to end-1
-                        extraInfo = add.activityInfo.applicationInfo.loadLabel(mPm);
-                    }
-                    addResolveInfoWithAlternates(rci, extraInfo, roLabel);
-                }
-            }
-        }
-
         private void addResolveInfoWithAlternates(ResolvedComponentInfo rci,
                 CharSequence extraInfo, CharSequence roLabel) {
             final int count = rci.getCount();
@@ -1912,14 +1875,6 @@
             return mDisplayList.size();
         }
 
-        public int getDisplayInfoCount() {
-            return mDisplayList.size();
-        }
-
-        public DisplayResolveInfo getDisplayInfoAt(int index) {
-            return mDisplayList.get(index);
-        }
-
         @Nullable
         public TargetInfo getItem(int position) {
             if (mFilterLastUsed && mLastChosenPosition >= 0 && position >= mLastChosenPosition) {
@@ -1979,36 +1934,38 @@
                     com.android.internal.R.layout.resolve_list_item, parent, false);
         }
 
-        public boolean showsExtendedInfo(TargetInfo info) {
-            return !TextUtils.isEmpty(info.getExtendedInfo());
-        }
-
         public final void bindView(int position, View view) {
             onBindView(view, getItem(position));
         }
 
-        private void onBindView(View view, TargetInfo info) {
+        protected void onBindView(View view, TargetInfo info) {
             final ViewHolder holder = (ViewHolder) view.getTag();
             if (info == null) {
                 holder.icon.setImageDrawable(
                         getDrawable(R.drawable.resolver_icon_placeholder));
                 return;
             }
+
             final CharSequence label = info.getDisplayLabel();
             if (!TextUtils.equals(holder.text.getText(), label)) {
                 holder.text.setText(info.getDisplayLabel());
             }
-            if (showsExtendedInfo(info)) {
-                holder.text2.setVisibility(View.VISIBLE);
-                holder.text2.setText(info.getExtendedInfo());
-            } else {
-                holder.text2.setVisibility(View.GONE);
+
+            // Always show a subLabel for visual consistency across list items. Show an empty
+            // subLabel if the subLabel is the same as the label
+            CharSequence subLabel = info.getExtendedInfo();
+            if (TextUtils.equals(label, subLabel)) subLabel = null;
+
+            if (!TextUtils.equals(holder.text2.getText(), subLabel)) {
+                holder.text2.setText(subLabel);
             }
+
             if (info instanceof DisplayResolveInfo
                     && !((DisplayResolveInfo) info).hasDisplayIcon()) {
-                new LoadAdapterIconTask((DisplayResolveInfo) info).execute();
+                new LoadIconTask((DisplayResolveInfo) info, holder.icon).execute();
+            } else {
+                holder.icon.setImageDrawable(info.getDisplayIcon());
             }
-            holder.icon.setImageDrawable(info.getDisplayIcon());
         }
     }
 
@@ -2127,13 +2084,15 @@
 
     }
 
-    abstract class LoadIconTask extends AsyncTask<Void, Void, Drawable> {
+    class LoadIconTask extends AsyncTask<Void, Void, Drawable> {
         protected final DisplayResolveInfo mDisplayResolveInfo;
         private final ResolveInfo mResolveInfo;
+        private final ImageView mTargetView;
 
-        public LoadIconTask(DisplayResolveInfo dri) {
+        LoadIconTask(DisplayResolveInfo dri, ImageView target) {
             mDisplayResolveInfo = dri;
             mResolveInfo = dri.getResolveInfo();
+            mTargetView = target;
         }
 
         @Override
@@ -2143,37 +2102,12 @@
 
         @Override
         protected void onPostExecute(Drawable d) {
-            mDisplayResolveInfo.setDisplayIcon(d);
-        }
-    }
-
-    class LoadAdapterIconTask extends LoadIconTask {
-        public LoadAdapterIconTask(DisplayResolveInfo dri) {
-            super(dri);
-        }
-
-        @Override
-        protected void onPostExecute(Drawable d) {
-            super.onPostExecute(d);
             if (mProfileView != null && mAdapter.getOtherProfile() == mDisplayResolveInfo) {
                 bindProfileView();
+            } else {
+                mDisplayResolveInfo.setDisplayIcon(d);
+                mTargetView.setImageDrawable(d);
             }
-            mAdapter.notifyDataSetChanged();
-        }
-    }
-
-    class LoadIconIntoViewTask extends LoadIconTask {
-        private final ImageView mTargetView;
-
-        public LoadIconIntoViewTask(DisplayResolveInfo dri, ImageView target) {
-            super(dri);
-            mTargetView = target;
-        }
-
-        @Override
-        protected void onPostExecute(Drawable d) {
-            super.onPostExecute(d);
-            mTargetView.setImageDrawable(d);
         }
     }
 
diff --git a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
index a88a80f..9bf4f01 100644
--- a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
@@ -60,8 +60,6 @@
 
     private static final boolean DEBUG = false;
 
-    private static final int NUM_OF_TOP_ANNOTATIONS_TO_USE = 3;
-
     // One week
     private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 7;
 
@@ -80,11 +78,6 @@
     private static final int WATCHDOG_TIMEOUT_MILLIS = 500;
 
     private final Collator mCollator;
-    private final boolean mHttp;
-    // can be null if mHttp == false or current user has no default browser package
-    private final String mDefaultBrowserPackageName;
-    private final PackageManager mPm;
-    private final UsageStatsManager mUsm;
     private final Map<String, UsageStats> mStats;
     private final long mCurrentTime;
     private final long mSinceTime;
@@ -92,8 +85,6 @@
     private final String mReferrerPackage;
     private final Object mLock = new Object();
     private ArrayList<ResolverTarget> mTargets;
-    private String mContentType;
-    private String[] mAnnotations;
     private String mAction;
     private ComponentName mResolvedRankerName;
     private ComponentName mRankerServiceName;
@@ -155,43 +146,17 @@
 
     public ResolverRankerServiceResolverComparator(Context context, Intent intent,
                 String referrerPackage, AfterCompute afterCompute) {
+        super(context, intent);
         mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
-        String scheme = intent.getScheme();
-        mHttp = "http".equals(scheme) || "https".equals(scheme);
         mReferrerPackage = referrerPackage;
         mAfterCompute = afterCompute;
         mContext = context;
 
-        mPm = context.getPackageManager();
-        mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
-
         mCurrentTime = System.currentTimeMillis();
         mSinceTime = mCurrentTime - USAGE_STATS_PERIOD;
         mStats = mUsm.queryAndAggregateUsageStats(mSinceTime, mCurrentTime);
-        mContentType = intent.getType();
-        getContentAnnotations(intent);
         mAction = intent.getAction();
         mRankerServiceName = new ComponentName(mContext, this.getClass());
-
-        mDefaultBrowserPackageName = mHttp
-                ? mPm.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId())
-                : null;
-    }
-
-    // get annotations of content from intent.
-    private void getContentAnnotations(Intent intent) {
-        ArrayList<String> annotations = intent.getStringArrayListExtra(
-                Intent.EXTRA_CONTENT_ANNOTATIONS);
-        if (annotations != null) {
-            int size = annotations.size();
-            if (size > NUM_OF_TOP_ANNOTATIONS_TO_USE) {
-                size = NUM_OF_TOP_ANNOTATIONS_TO_USE;
-            }
-            mAnnotations = new String[size];
-            for (int i = 0; i < size; i++) {
-                mAnnotations[i] = annotations.get(i);
-            }
-        }
     }
 
     // compute features for each target according to usage stats of targets.
@@ -286,36 +251,7 @@
     }
 
     @Override
-    public int compare(ResolvedComponentInfo lhsp, ResolvedComponentInfo rhsp) {
-        final ResolveInfo lhs = lhsp.getResolveInfoAt(0);
-        final ResolveInfo rhs = rhsp.getResolveInfoAt(0);
-
-        // We want to put the one targeted to another user at the end of the dialog.
-        if (lhs.targetUserId != UserHandle.USER_CURRENT) {
-            return rhs.targetUserId != UserHandle.USER_CURRENT ? 0 : 1;
-        }
-        if (rhs.targetUserId != UserHandle.USER_CURRENT) {
-            return -1;
-        }
-
-        if (mHttp) {
-            // Special case: we want filters that match URI paths/schemes to be
-            // ordered before others.  This is for the case when opening URIs,
-            // to make native apps go above browsers - except for 1 even more special case
-            // which is the default browser, as we want that to go above them all.
-            if (isDefaultBrowser(lhs)) {
-                return -1;
-            }
-            if (isDefaultBrowser(rhs)) {
-                return 1;
-            }
-            final boolean lhsSpecific = ResolverActivity.isSpecificUriMatch(lhs.match);
-            final boolean rhsSpecific = ResolverActivity.isSpecificUriMatch(rhs.match);
-            if (lhsSpecific != rhsSpecific) {
-                return lhsSpecific ? -1 : 1;
-            }
-        }
-
+    public int compare(ResolveInfo lhs, ResolveInfo rhs) {
         if (mStats != null) {
             final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
                     lhs.activityInfo.packageName, lhs.activityInfo.name));
@@ -349,13 +285,6 @@
         return 0;
     }
 
-    @Override
-    public void updateChooserCounts(String packageName, int userId, String action) {
-        if (mUsm != null) {
-            mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action);
-        }
-    }
-
     // update ranking model when the connection to it is valid.
     @Override
     public void updateModel(ComponentName componentName) {
@@ -407,20 +336,6 @@
         }
     }
 
-    private boolean isDefaultBrowser(ResolveInfo ri) {
-        // It makes sense to prefer the default browser
-        // only if the targeted user is the current user
-        if (ri.targetUserId != UserHandle.USER_CURRENT) {
-            return false;
-        }
-
-        if (ri.activityInfo.packageName != null
-                && ri.activityInfo.packageName.equals(mDefaultBrowserPackageName)) {
-            return true;
-        }
-        return false;
-    }
-
     // records metrics for evaluation.
     private void logMetrics(int selectedPos) {
         if (mRankerServiceName != null) {
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index 0e4897f..b26efc0 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -79,6 +79,7 @@
         STATE_TOP,                      // ActivityManager.PROCESS_STATE_TOP
         STATE_IMPORTANT_FOREGROUND,     // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
         STATE_IMPORTANT_FOREGROUND,     // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
+        STATE_IMPORTANT_FOREGROUND,     // ActivityManager.PROCESS_STATE_BOUND_TOP
         STATE_IMPORTANT_FOREGROUND,     // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
         STATE_IMPORTANT_FOREGROUND,     // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
         STATE_IMPORTANT_BACKGROUND,     // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
diff --git a/core/java/com/android/internal/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java
index 9d85a03..b9aab21 100644
--- a/core/java/com/android/internal/colorextraction/types/Tonal.java
+++ b/core/java/com/android/internal/colorextraction/types/Tonal.java
@@ -109,42 +109,20 @@
         final int mainColorsSize = mainColors.size();
         final int hints = inWallpaperColors.getColorHints();
         final boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
-        final boolean generatedFromBitmap = (hints & WallpaperColors.HINT_FROM_BITMAP) != 0;
 
         if (mainColorsSize == 0) {
             return false;
         }
 
-        // Decide what's the best color to use.
-        // We have 2 options:
-        // • Just pick the primary color
-        // • Filter out blacklisted colors. This is useful when palette is generated
-        //   automatically from a bitmap.
-        Color bestColor = null;
-        final float[] hsl = new float[3];
-        for (int i = 0; i < mainColorsSize; i++) {
-            final Color color = mainColors.get(i);
-            final int colorValue = color.toArgb();
-            ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue),
-                    Color.blue(colorValue), hsl);
-
-            // Stop when we find a color that meets our criteria
-            if (!generatedFromBitmap) {
-                bestColor = color;
-                break;
-            }
-        }
-
-        // Fail if not found
-        if (bestColor == null) {
-            return false;
-        }
+        // Pick the primary color as the best color to use.
+        final Color bestColor = mainColors.get(0);
 
         // Tonal is not really a sort, it takes a color from the extracted
         // palette and finds a best fit amongst a collection of pre-defined
         // palettes. The best fit is tweaked to be closer to the source color
         // and replaces the original palette.
         int colorValue = bestColor.toArgb();
+        final float[] hsl = new float[3];
         ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue),
                 hsl);
 
diff --git a/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java b/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java
index 37f61bf..206efa9 100644
--- a/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java
@@ -45,9 +45,9 @@
     public AbstractMultiplePendingRequestsRemoteService(@NonNull Context context,
             @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
             @NonNull VultureCallback<S> callback, @NonNull Handler handler,
-            boolean bindInstantServiceAllowed, boolean verbose, int initialCapacity) {
-        super(context, serviceInterface, componentName, userId, callback, handler,
-                bindInstantServiceAllowed, verbose);
+            int bindingFlags, boolean verbose, int initialCapacity) {
+        super(context, serviceInterface, componentName, userId, callback, handler, bindingFlags,
+                verbose);
         mInitialCapacity = initialCapacity;
     }
 
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 0a83fcc..1155854 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -82,7 +82,7 @@
     private final VultureCallback<S> mVultureCallback;
     private final int mUserId;
     private final ServiceConnection mServiceConnection = new RemoteServiceConnection();
-    private final boolean mBindInstantServiceAllowed;
+    private final int mBindingFlags;
     protected I mService;
 
     private boolean mBinding;
@@ -113,7 +113,7 @@
     // NOTE: must be package-protected so this class is not extended outside
     AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
             @NonNull ComponentName componentName, int userId, @NonNull VultureCallback<S> callback,
-            @NonNull Handler handler, boolean bindInstantServiceAllowed, boolean verbose) {
+            @NonNull Handler handler, int bindingFlags, boolean verbose) {
         mContext = context;
         mVultureCallback = callback;
         mVerbose = verbose;
@@ -121,7 +121,7 @@
         mIntent = new Intent(serviceInterface).setComponent(mComponentName);
         mUserId = userId;
         mHandler = new Handler(handler.getLooper());
-        mBindInstantServiceAllowed = bindInstantServiceAllowed;
+        mBindingFlags = bindingFlags;
     }
 
     /**
@@ -264,7 +264,7 @@
             }
         }
         pw.println();
-        pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
+        pw.append(prefix).append("mBindingFlags=").println(mBindingFlags);
         pw.append(prefix).append("idleTimeout=")
             .append(Long.toString(idleTimeout / 1000)).append("s\n");
         pw.append(prefix).append("requestTimeout=");
@@ -407,10 +407,8 @@
         if (mVerbose) Slog.v(mTag, "ensureBound()");
         mBinding = true;
 
-        int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
-        if (mBindInstantServiceAllowed) {
-            flags |= Context.BIND_ALLOW_INSTANT;
-        }
+        final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+                | mBindingFlags;
 
         final boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags,
                 mHandler, new UserHandle(mUserId));
diff --git a/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java b/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java
index a70fc3e..66bee95 100644
--- a/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java
@@ -44,9 +44,9 @@
     public AbstractSinglePendingRequestRemoteService(@NonNull Context context,
             @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
             @NonNull VultureCallback<S> callback, @NonNull Handler handler,
-            boolean bindInstantServiceAllowed, boolean verbose) {
-        super(context, serviceInterface, componentName, userId, callback, handler,
-                bindInstantServiceAllowed, verbose);
+            int bindingFlags, boolean verbose) {
+        super(context, serviceInterface, componentName, userId, callback, handler, bindingFlags,
+                verbose);
     }
 
     @Override // from AbstractRemoteService
diff --git a/core/java/com/android/internal/infra/GlobalWhitelistState.java b/core/java/com/android/internal/infra/GlobalWhitelistState.java
new file mode 100644
index 0000000..dfa59b7
--- /dev/null
+++ b/core/java/com/android/internal/infra/GlobalWhitelistState.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.infra;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.content.ComponentName;
+import android.util.ArraySet;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * Helper class used to manage a {@link WhitelistHelper} per user instance when the main service
+ * cannot hold a lock when external entities (typically {@code ActivityManagerService}) needs to
+ * get whitelist info.
+ *
+ * <p>This class is thread safe.
+ */
+public class GlobalWhitelistState {
+
+    // Uses full-name to avoid collision with service-provided mLock
+    protected final Object mGlobalWhitelistStateLock = new Object();
+
+    @Nullable
+    @GuardedBy("mGlobalWhitelistStateLock")
+    protected SparseArray<WhitelistHelper> mWhitelisterHelpers;
+
+    /**
+     * Sets the whitelist for the given user.
+     */
+    public void setWhitelist(@UserIdInt int userId, @Nullable List<String> packageNames,
+            @Nullable List<ComponentName> components) {
+        synchronized (mGlobalWhitelistStateLock) {
+            if (mWhitelisterHelpers == null) {
+                mWhitelisterHelpers = new SparseArray<>(1);
+            }
+            WhitelistHelper helper = mWhitelisterHelpers.get(userId);
+            if (helper == null) {
+                helper = new WhitelistHelper();
+                mWhitelisterHelpers.put(userId, helper);
+            }
+            helper.setWhitelist(packageNames, components);
+        }
+    }
+
+    /**
+     * Checks if the given package is whitelisted for the given user.
+     */
+    public boolean isWhitelisted(@UserIdInt int userId, @NonNull String packageName) {
+        synchronized (mGlobalWhitelistStateLock) {
+            if (mWhitelisterHelpers == null) return false;
+            final WhitelistHelper helper = mWhitelisterHelpers.get(userId);
+            return helper == null ? false : helper.isWhitelisted(packageName);
+        }
+    }
+
+    /**
+     * Checks if the given component is whitelisted for the given user.
+     */
+    public boolean isWhitelisted(@UserIdInt int userId, @NonNull ComponentName componentName) {
+        synchronized (mGlobalWhitelistStateLock) {
+            if (mWhitelisterHelpers == null) return false;
+            final WhitelistHelper helper = mWhitelisterHelpers.get(userId);
+            return helper == null ? false : helper.isWhitelisted(componentName);
+        }
+    }
+
+    /**
+     * Gets the whitelisted components for the given package and user.
+     */
+    public ArraySet<ComponentName> getWhitelistedComponents(@UserIdInt int userId,
+            @NonNull String packageName) {
+        synchronized (mGlobalWhitelistStateLock) {
+            if (mWhitelisterHelpers == null) return null;
+            final WhitelistHelper helper = mWhitelisterHelpers.get(userId);
+            return helper == null ? null : helper.getWhitelistedComponents(packageName);
+        }
+    }
+
+    /**
+     * Resets the whitelist for the given user.
+     */
+    public void resetWhitelist(@NonNull int userId) {
+        synchronized (mGlobalWhitelistStateLock) {
+            if (mWhitelisterHelpers == null) return;
+            mWhitelisterHelpers.remove(userId);
+            if (mWhitelisterHelpers.size() == 0) {
+                mWhitelisterHelpers = null;
+            }
+        }
+    }
+
+    /**
+     * Dumps it!
+     */
+    public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+        pw.print(prefix); pw.print("State: ");
+        synchronized (mGlobalWhitelistStateLock) {
+            if (mWhitelisterHelpers == null) {
+                pw.println("empty");
+                return;
+            }
+            pw.print(mWhitelisterHelpers.size()); pw.println(" services");
+            final String prefix2 = prefix + "  ";
+            for (int i = 0; i < mWhitelisterHelpers.size(); i++) {
+                final int userId  = mWhitelisterHelpers.keyAt(i);
+                final WhitelistHelper helper = mWhitelisterHelpers.valueAt(i);
+                helper.dump(prefix2, "Whitelist for userId " + userId, pw);
+            }
+        }
+    }
+}
diff --git a/core/java/com/android/internal/infra/WhitelistHelper.java b/core/java/com/android/internal/infra/WhitelistHelper.java
index 183b465..d7753db 100644
--- a/core/java/com/android/internal/infra/WhitelistHelper.java
+++ b/core/java/com/android/internal/infra/WhitelistHelper.java
@@ -31,6 +31,7 @@
 /**
  * Helper class for keeping track of whitelisted packages/activities.
  *
+ * <p><b>NOTE: </b>this class is not thread safe.
  * @hide
  */
 public final class WhitelistHelper {
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReader.java b/core/java/com/android/internal/os/KernelCpuThreadReader.java
index 248e026..d92f725b 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReader.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReader.java
@@ -21,6 +21,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Preconditions;
 
 import java.io.IOException;
@@ -29,18 +30,22 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.function.Predicate;
 
 /**
- * Given a process, will iterate over the child threads of the process, and return the CPU usage
- * statistics for each child thread. The CPU usage statistics contain the amount of time spent in a
- * frequency band.
+ * Iterates over processes, and all threads owned by those processes, and return the CPU usage for
+ * each thread. The CPU usage statistics contain the amount of time spent in a frequency band. CPU
+ * usage is collected using {@link ProcTimeInStateReader}.
+ *
+ * <p>We only collect CPU data for processes and threads that are owned by certain UIDs. These UIDs
+ * are configured via {@link #setUidPredicate}.
  *
  * <p>Frequencies are bucketed together to reduce the amount of data created. This means that we
- * return less frequencies than provided by {@link ProcTimeInStateReader}. The number of
- * frequencies is configurable by {@link #setNumBuckets}. Frequencies are reported as the lowest
- * frequency in that range. Frequencies are spread as evenly as possible across the buckets. The
- * buckets do not cross over the little/big frequencies reported.
+ * return less frequencies than provided by {@link ProcTimeInStateReader}. The number of frequencies
+ * is configurable by {@link #setNumBuckets}. Frequencies are reported as the lowest frequency in
+ * that range. Frequencies are spread as evenly as possible across the buckets. The buckets do not
+ * cross over the little/big frequencies reported.
  *
  * <p>N.B.: In order to bucket across little/big frequencies correctly, we assume that the {@code
  * time_in_state} file contains every little core frequency in ascending order, followed by every
@@ -60,73 +65,42 @@
     private static final String CPU_STATISTICS_FILENAME = "time_in_state";
 
     /**
-     * The name of the file to read process command line invocation from, must be found in
-     * {@code /proc/$PID/}
+     * The name of the file to read process command line invocation from, must be found in {@code
+     * /proc/$PID/}
      */
     private static final String PROCESS_NAME_FILENAME = "cmdline";
 
     /**
-     * The name of the file to read thread name from, must be found in
-     * {@code /proc/$PID/task/$TID}
+     * The name of the file to read thread name from, must be found in {@code /proc/$PID/task/$TID}
      */
     private static final String THREAD_NAME_FILENAME = "comm";
 
-    /**
-     * Glob pattern for the process directory names under {@code proc}
-     */
+    /** Glob pattern for the process directory names under {@code proc} */
     private static final String PROCESS_DIRECTORY_FILTER = "[0-9]*";
 
-    /**
-     * Default process name when the name can't be read
-     */
+    /** Default process name when the name can't be read */
     private static final String DEFAULT_PROCESS_NAME = "unknown_process";
 
-    /**
-     * Default thread name when the name can't be read
-     */
+    /** Default thread name when the name can't be read */
     private static final String DEFAULT_THREAD_NAME = "unknown_thread";
 
-    /**
-     * Default mount location of the {@code proc} filesystem
-     */
+    /** Default mount location of the {@code proc} filesystem */
     private static final Path DEFAULT_PROC_PATH = Paths.get("/proc");
 
-    /**
-     * The initial {@code time_in_state} file for {@link ProcTimeInStateReader}
-     */
+    /** The initial {@code time_in_state} file for {@link ProcTimeInStateReader} */
     private static final Path DEFAULT_INITIAL_TIME_IN_STATE_PATH =
             DEFAULT_PROC_PATH.resolve("self/time_in_state");
 
-    /**
-     * Value returned when there was an error getting an integer ID value (e.g. PID, UID)
-     */
+    /** Value returned when there was an error getting an integer ID value (e.g. PID, UID) */
     private static final int ID_ERROR = -1;
 
     /**
-     * Thread ID used when reporting CPU used by other threads
-     */
-    private static final int OTHER_THREADS_ID = -1;
-
-    /**
-     * Thread name used when reporting CPU used by other threads
-     */
-    private static final String OTHER_THREADS_NAME = "__OTHER_THREADS";
-
-    /**
      * When checking whether to report data for a thread, we check the UID of the thread's owner
      * against this predicate
      */
     private Predicate<Integer> mUidPredicate;
 
-    /**
-     * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it
-     * will not be reported
-     */
-    private int mMinimumTotalCpuUsageMillis;
-
-    /**
-     * Where the proc filesystem is mounted
-     */
+    /** Where the proc filesystem is mounted */
     private final Path mProcPath;
 
     /**
@@ -135,14 +109,10 @@
      */
     private int[] mFrequenciesKhz;
 
-    /**
-     * Used to read and parse {@code time_in_state} files
-     */
+    /** Used to read and parse {@code time_in_state} files */
     private final ProcTimeInStateReader mProcTimeInStateReader;
 
-    /**
-     * Used to sort frequencies and usage times into buckets
-     */
+    /** Used to sort frequencies and usage times into buckets */
     private FrequencyBucketCreator mFrequencyBucketCreator;
 
     private final Injector mInjector;
@@ -150,21 +120,19 @@
     /**
      * Create with a path where `proc` is mounted. Used primarily for testing
      *
-     * @param procPath               where `proc` is mounted (to find, see {@code mount | grep
-     *                               ^proc})
+     * @param procPath where `proc` is mounted (to find, see {@code mount | grep ^proc})
      * @param initialTimeInStatePath where the initial {@code time_in_state} file exists to define
-     *                               format
+     *     format
      */
     @VisibleForTesting
     public KernelCpuThreadReader(
             int numBuckets,
             Predicate<Integer> uidPredicate,
-            int minimumTotalCpuUsageMillis,
             Path procPath,
             Path initialTimeInStatePath,
-            Injector injector) throws IOException {
+            Injector injector)
+            throws IOException {
         mUidPredicate = uidPredicate;
-        mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
         mProcPath = procPath;
         mProcTimeInStateReader = new ProcTimeInStateReader(initialTimeInStatePath);
         mInjector = injector;
@@ -177,13 +145,11 @@
      * @return the reader, null if an exception was thrown during creation
      */
     @Nullable
-    public static KernelCpuThreadReader create(
-            int numBuckets, Predicate<Integer> uidPredicate, int minimumTotalCpuUsageMillis) {
+    public static KernelCpuThreadReader create(int numBuckets, Predicate<Integer> uidPredicate) {
         try {
             return new KernelCpuThreadReader(
                     numBuckets,
                     uidPredicate,
-                    minimumTotalCpuUsageMillis,
                     DEFAULT_PROC_PATH,
                     DEFAULT_INITIAL_TIME_IN_STATE_PATH,
                     new Injector());
@@ -205,7 +171,7 @@
      * #setUidPredicate}.
      */
     @Nullable
-    public ArrayList<ProcessCpuUsage> getProcessCpuUsageByUids() {
+    public ArrayList<ProcessCpuUsage> getProcessCpuUsage() {
         if (DEBUG) {
             Slog.d(TAG, "Reading CPU thread usages for processes owned by UIDs");
         }
@@ -213,7 +179,7 @@
         final ArrayList<ProcessCpuUsage> processCpuUsages = new ArrayList<>();
 
         try (DirectoryStream<Path> processPaths =
-                     Files.newDirectoryStream(mProcPath, PROCESS_DIRECTORY_FILTER)) {
+                Files.newDirectoryStream(mProcPath, PROCESS_DIRECTORY_FILTER)) {
             for (Path processPath : processPaths) {
                 final int processId = getProcessId(processPath);
                 final int uid = mInjector.getUidForPid(processId);
@@ -231,7 +197,7 @@
                 }
             }
         } catch (IOException e) {
-            Slog.w("Failed to iterate over process paths", e);
+            Slog.w(TAG, "Failed to iterate over process paths", e);
             return null;
         }
 
@@ -248,33 +214,58 @@
     }
 
     /**
-     * Read all of the CPU usage statistics for each child thread of the current process
-     *
-     * @return process CPU usage containing usage of all child threads
+     * Get the CPU frequencies that correspond to the times reported in {@link
+     * ThreadCpuUsage#usageTimesMillis}
      */
     @Nullable
-    public ProcessCpuUsage getCurrentProcessCpuUsage() {
-        return getProcessCpuUsage(mProcPath.resolve("self"), mInjector.myPid(), mInjector.myUid());
+    public int[] getCpuFrequenciesKhz() {
+        return mFrequenciesKhz;
+    }
+
+    /** Set the number of frequency buckets to use */
+    void setNumBuckets(int numBuckets) {
+        if (numBuckets < 1) {
+            Slog.w(TAG, "Number of buckets must be at least 1, but was " + numBuckets);
+            return;
+        }
+        // If `numBuckets` hasn't changed since the last set, do nothing
+        if (mFrequenciesKhz != null && mFrequenciesKhz.length == numBuckets) {
+            return;
+        }
+        mFrequencyBucketCreator =
+                new FrequencyBucketCreator(mProcTimeInStateReader.getFrequenciesKhz(), numBuckets);
+        mFrequenciesKhz =
+                mFrequencyBucketCreator.bucketFrequencies(
+                        mProcTimeInStateReader.getFrequenciesKhz());
+    }
+
+    /** Set the UID predicate for {@link #getProcessCpuUsage} */
+    void setUidPredicate(Predicate<Integer> uidPredicate) {
+        mUidPredicate = uidPredicate;
     }
 
     /**
      * Read all of the CPU usage statistics for each child thread of a process
      *
      * @param processPath the {@code /proc} path of the thread
-     * @param processId   the ID of the process
-     * @param uid         the ID of the user who owns the process
+     * @param processId the ID of the process
+     * @param uid the ID of the user who owns the process
      * @return process CPU usage containing usage of all child threads. Null if the process exited
-     * and its {@code proc} directory was removed while collecting information
+     *     and its {@code proc} directory was removed while collecting information
      */
     @Nullable
     private ProcessCpuUsage getProcessCpuUsage(Path processPath, int processId, int uid) {
         if (DEBUG) {
-            Slog.d(TAG, "Reading CPU thread usages with directory " + processPath
-                    + " process ID " + processId
-                    + " and user ID " + uid);
+            Slog.d(
+                    TAG,
+                    "Reading CPU thread usages with directory "
+                            + processPath
+                            + " process ID "
+                            + processId
+                            + " and user ID "
+                            + uid);
         }
 
-        int[] filteredThreadsCpuUsage = null;
         final Path allThreadsPath = processPath.resolve("task");
         final ArrayList<ThreadCpuUsage> threadCpuUsages = new ArrayList<>();
         try (DirectoryStream<Path> threadPaths = Files.newDirectoryStream(allThreadsPath)) {
@@ -283,14 +274,6 @@
                 if (threadCpuUsage == null) {
                     continue;
                 }
-                if (mMinimumTotalCpuUsageMillis > totalCpuUsage(threadCpuUsage.usageTimesMillis)) {
-                    if (filteredThreadsCpuUsage == null) {
-                        filteredThreadsCpuUsage = new int[mFrequenciesKhz.length];
-                    }
-                    filteredThreadsCpuUsage =
-                            sumCpuUsage(filteredThreadsCpuUsage, threadCpuUsage.usageTimesMillis);
-                    continue;
-                }
                 threadCpuUsages.add(threadCpuUsage);
             }
         } catch (IOException e) {
@@ -302,67 +285,10 @@
         if (threadCpuUsages.isEmpty()) {
             return null;
         }
-
-        // Add the filtered out thread CPU usage under an "other threads" ThreadCpuUsage
-        if (filteredThreadsCpuUsage != null) {
-            threadCpuUsages.add(new ThreadCpuUsage(
-                    OTHER_THREADS_ID, OTHER_THREADS_NAME, filteredThreadsCpuUsage));
-        }
-
         if (DEBUG) {
             Slog.d(TAG, "Read CPU usage of " + threadCpuUsages.size() + " threads");
         }
-        return new ProcessCpuUsage(
-                processId,
-                getProcessName(processPath),
-                uid,
-                threadCpuUsages);
-    }
-
-    /**
-     * Set the number of frequency buckets to use
-     */
-    void setNumBuckets(int numBuckets) {
-        if (numBuckets < 1) {
-            Slog.w(TAG, "Number of buckets must be at least 1, but was " + numBuckets);
-            return;
-        }
-        // If `numBuckets` hasn't changed since the last set, do nothing
-        if (mFrequenciesKhz != null && mFrequenciesKhz.length == numBuckets) {
-            return;
-        }
-        mFrequencyBucketCreator = new FrequencyBucketCreator(
-                mProcTimeInStateReader.getFrequenciesKhz(), numBuckets);
-        mFrequenciesKhz = mFrequencyBucketCreator.getBucketMinFrequencies(
-                mProcTimeInStateReader.getFrequenciesKhz());
-    }
-
-    /**
-     * Set the UID predicate for {@link #getProcessCpuUsageByUids}
-     */
-    void setUidPredicate(Predicate<Integer> uidPredicate) {
-        mUidPredicate = uidPredicate;
-    }
-
-    /**
-     * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it
-     * will not be reported
-     */
-    void setMinimumTotalCpuUsageMillis(int minimumTotalCpuUsageMillis) {
-        if (minimumTotalCpuUsageMillis < 0) {
-            Slog.w(TAG, "Negative minimumTotalCpuUsageMillis: " + minimumTotalCpuUsageMillis);
-            return;
-        }
-        mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
-    }
-
-    /**
-     * Get the CPU frequencies that correspond to the times reported in
-     * {@link ThreadCpuUsage#usageTimesMillis}
-     */
-    @Nullable
-    public int[] getCpuFrequenciesKhz() {
-        return mFrequenciesKhz;
+        return new ProcessCpuUsage(processId, getProcessName(processPath), uid, threadCpuUsages);
     }
 
     /**
@@ -370,7 +296,7 @@
      *
      * @param threadDirectory the {@code /proc} directory of the thread
      * @return thread CPU usage. Null if the thread exited and its {@code proc} directory was
-     * removed while collecting information
+     *     removed while collecting information
      */
     @Nullable
     private ThreadCpuUsage getThreadCpuUsage(Path threadDirectory) {
@@ -393,32 +319,26 @@
         if (cpuUsagesLong == null) {
             return null;
         }
-        int[] cpuUsages = mFrequencyBucketCreator.getBucketedValues(cpuUsagesLong);
+        int[] cpuUsages = mFrequencyBucketCreator.bucketValues(cpuUsagesLong);
 
         return new ThreadCpuUsage(threadId, threadName, cpuUsages);
     }
 
-    /**
-     * Get the command used to start a process
-     */
+    /** Get the command used to start a process */
     private String getProcessName(Path processPath) {
         final Path processNamePath = processPath.resolve(PROCESS_NAME_FILENAME);
 
-        final String processName =
-                ProcStatsUtil.readSingleLineProcFile(processNamePath.toString());
+        final String processName = ProcStatsUtil.readSingleLineProcFile(processNamePath.toString());
         if (processName != null) {
             return processName;
         }
         return DEFAULT_PROCESS_NAME;
     }
 
-    /**
-     * Get the name of a thread, given the {@code /proc} path of the thread
-     */
+    /** Get the name of a thread, given the {@code /proc} path of the thread */
     private String getThreadName(Path threadPath) {
         final Path threadNamePath = threadPath.resolve(THREAD_NAME_FILENAME);
-        final String threadName =
-                ProcStatsUtil.readNullSeparatedFile(threadNamePath.toString());
+        final String threadName = ProcStatsUtil.readNullSeparatedFile(threadNamePath.toString());
         if (threadName == null) {
             return DEFAULT_THREAD_NAME;
         }
@@ -442,114 +362,45 @@
     }
 
     /**
-     * Get the sum of all CPU usage across all frequencies
-     */
-    private static int totalCpuUsage(int[] cpuUsage) {
-        int total = 0;
-        for (int i = 0; i < cpuUsage.length; i++) {
-            total += cpuUsage[i];
-        }
-        return total;
-    }
-
-    /**
-     * Add two CPU frequency usages together
-     */
-    private static int[] sumCpuUsage(int[] a, int[] b) {
-        int[] summed = new int[a.length];
-        for (int i = 0; i < a.length; i++) {
-            summed[i] = a[i] + b[i];
-        }
-        return summed;
-    }
-
-    /**
-     * Puts frequencies and usage times into buckets
+     * Quantizes a list of N frequencies into a list of M frequencies (where M<=N)
+     *
+     * <p>In order to reduce data sent from the device, we discard precise frequency information for
+     * an approximation. This is done by putting groups of adjacent frequencies into the same
+     * bucket, and then reporting that bucket under the minimum frequency in that bucket.
+     *
+     * <p>Many devices have multiple core clusters. We do not want to report frequencies from
+     * different clusters under the same bucket, so some complication arises.
+     *
+     * <p>Buckets are allocated evenly across all core clusters, i.e. they all have the same number
+     * of buckets regardless of how many frequencies they contain. This is done to reduce code
+     * complexity, and in practice the number of frequencies doesn't vary too much between core
+     * clusters.
+     *
+     * <p>If the number of buckets is not a factor of the number of frequencies, the remainder of
+     * the frequencies are placed into the last bucket.
+     *
+     * <p>It is possible to have less buckets than asked for, so any calling code can't assume that
+     * initializing with N buckets will use return N values. This happens in two scenarios:
+     *
+     * <ul>
+     *   <li>There are less frequencies available than buckets asked for.
+     *   <li>There are less frequencies in a core cluster than buckets allocated to that core
+     *       cluster.
+     * </ul>
      */
     @VisibleForTesting
     public static class FrequencyBucketCreator {
-        private final int mNumBuckets;
         private final int mNumFrequencies;
-        private final int mBigFrequenciesStartIndex;
-        private final int mLittleNumBuckets;
-        private final int mBigNumBuckets;
-        private final int mLittleBucketSize;
-        private final int mBigBucketSize;
+        private final int mNumBuckets;
+        private final int[] mBucketStartIndices;
 
-        /**
-         * Buckets based of a list of frequencies
-         *
-         * @param frequencies the frequencies to base buckets off
-         * @param numBuckets  how many buckets to create
-         */
         @VisibleForTesting
-        public FrequencyBucketCreator(long[] frequencies, int numBuckets) {
-            Preconditions.checkArgument(numBuckets > 0);
-
+        public FrequencyBucketCreator(long[] frequencies, int targetNumBuckets) {
             mNumFrequencies = frequencies.length;
-            mBigFrequenciesStartIndex = getBigFrequenciesStartIndex(frequencies);
-
-            final int littleNumBuckets;
-            final int bigNumBuckets;
-            if (mBigFrequenciesStartIndex < frequencies.length) {
-                littleNumBuckets = numBuckets / 2;
-                bigNumBuckets = numBuckets - littleNumBuckets;
-            } else {
-                // If we've got no big frequencies, set all buckets to little frequencies
-                littleNumBuckets = numBuckets;
-                bigNumBuckets = 0;
-            }
-
-            // Ensure that we don't have more buckets than frequencies
-            mLittleNumBuckets = Math.min(littleNumBuckets, mBigFrequenciesStartIndex);
-            mBigNumBuckets = Math.min(
-                    bigNumBuckets, frequencies.length - mBigFrequenciesStartIndex);
-            mNumBuckets = mLittleNumBuckets + mBigNumBuckets;
-
-            // Set the size of each little and big bucket. If they have no buckets, the size is zero
-            mLittleBucketSize = mLittleNumBuckets == 0 ? 0 :
-                    mBigFrequenciesStartIndex / mLittleNumBuckets;
-            mBigBucketSize = mBigNumBuckets == 0 ? 0 :
-                    (frequencies.length - mBigFrequenciesStartIndex) / mBigNumBuckets;
-        }
-
-        /**
-         * Find the index where frequencies change from little core to big core
-         */
-        @VisibleForTesting
-        public static int getBigFrequenciesStartIndex(long[] frequenciesKhz) {
-            for (int i = 0; i < frequenciesKhz.length - 1; i++) {
-                if (frequenciesKhz[i] > frequenciesKhz[i + 1]) {
-                    return i + 1;
-                }
-            }
-
-            return frequenciesKhz.length;
-        }
-
-        /**
-         * Get the minimum frequency in each bucket
-         */
-        @VisibleForTesting
-        public int[] getBucketMinFrequencies(long[] frequenciesKhz) {
-            Preconditions.checkArgument(frequenciesKhz.length == mNumFrequencies);
-            // If there's only one bucket, we bucket everything together so the first bucket is the
-            // min frequency
-            if (mNumBuckets == 1) {
-                return new int[]{(int) frequenciesKhz[0]};
-            }
-
-            final int[] bucketMinFrequencies = new int[mNumBuckets];
-            // Initialize little buckets min frequencies
-            for (int i = 0; i < mLittleNumBuckets; i++) {
-                bucketMinFrequencies[i] = (int) frequenciesKhz[i * mLittleBucketSize];
-            }
-            // Initialize big buckets min frequencies
-            for (int i = 0; i < mBigNumBuckets; i++) {
-                final int frequencyIndex = mBigFrequenciesStartIndex + i * mBigBucketSize;
-                bucketMinFrequencies[mLittleNumBuckets + i] = (int) frequenciesKhz[frequencyIndex];
-            }
-            return bucketMinFrequencies;
+            int[] clusterStartIndices = getClusterStartIndices(frequencies);
+            mBucketStartIndices =
+                    getBucketStartIndices(clusterStartIndices, targetNumBuckets, mNumFrequencies);
+            mNumBuckets = mBucketStartIndices.length;
         }
 
         /**
@@ -561,44 +412,117 @@
          * @return the bucketed usage times
          */
         @VisibleForTesting
-        public int[] getBucketedValues(long[] values) {
+        public int[] bucketValues(long[] values) {
             Preconditions.checkArgument(values.length == mNumFrequencies);
-            final int[] bucketed = new int[mNumBuckets];
-
-            // If there's only one bucket, add all frequencies in
-            if (mNumBuckets == 1) {
-                for (int i = 0; i < values.length; i++) {
-                    bucketed[0] += values[i];
+            int[] buckets = new int[mNumBuckets];
+            for (int bucketIdx = 0; bucketIdx < mNumBuckets; bucketIdx++) {
+                final int bucketStartIdx = getLowerBound(bucketIdx, mBucketStartIndices);
+                final int bucketEndIdx =
+                        getUpperBound(bucketIdx, mBucketStartIndices, values.length);
+                for (int valuesIdx = bucketStartIdx; valuesIdx < bucketEndIdx; valuesIdx++) {
+                    buckets[bucketIdx] += values[valuesIdx];
                 }
-                return bucketed;
+            }
+            return buckets;
+        }
+
+        /** Get the minimum frequency in each bucket */
+        @VisibleForTesting
+        public int[] bucketFrequencies(long[] frequencies) {
+            Preconditions.checkArgument(frequencies.length == mNumFrequencies);
+            int[] buckets = new int[mNumBuckets];
+            for (int i = 0; i < buckets.length; i++) {
+                buckets[i] = (int) frequencies[mBucketStartIndices[i]];
+            }
+            return buckets;
+        }
+
+        /**
+         * Get the index in frequencies where each core cluster starts
+         *
+         * <p>The frequencies for each cluster are given in ascending order, appended to each other.
+         * This means that every time there is a decrease in frequencies (instead of increase) a new
+         * cluster has started.
+         */
+        private static int[] getClusterStartIndices(long[] frequencies) {
+            ArrayList<Integer> indices = new ArrayList<>();
+            indices.add(0);
+            for (int i = 0; i < frequencies.length - 1; i++) {
+                if (frequencies[i] >= frequencies[i + 1]) {
+                    indices.add(i + 1);
+                }
+            }
+            return ArrayUtils.convertToIntArray(indices);
+        }
+
+        /** Get the index in frequencies where each bucket starts */
+        private static int[] getBucketStartIndices(
+                int[] clusterStartIndices, int targetNumBuckets, int numFrequencies) {
+            int numClusters = clusterStartIndices.length;
+
+            // If we haven't got enough buckets for every cluster, we instead have one bucket per
+            // cluster, with the last bucket containing the remaining clusters
+            if (numClusters > targetNumBuckets) {
+                return Arrays.copyOfRange(clusterStartIndices, 0, targetNumBuckets);
             }
 
-            // Initialize the little buckets
-            for (int i = 0; i < mBigFrequenciesStartIndex; i++) {
-                final int bucketIndex = Math.min(i / mLittleBucketSize, mLittleNumBuckets - 1);
-                bucketed[bucketIndex] += values[i];
+            ArrayList<Integer> bucketStartIndices = new ArrayList<>();
+            for (int clusterIdx = 0; clusterIdx < numClusters; clusterIdx++) {
+                final int clusterStartIdx = getLowerBound(clusterIdx, clusterStartIndices);
+                final int clusterEndIdx =
+                        getUpperBound(clusterIdx, clusterStartIndices, numFrequencies);
+
+                final int numBucketsInCluster;
+                if (clusterIdx != numClusters - 1) {
+                    numBucketsInCluster = targetNumBuckets / numClusters;
+                } else {
+                    // If we're in the last cluster, the bucket will contain the remainder of the
+                    // frequencies
+                    int previousBucketsInCluster = targetNumBuckets / numClusters;
+                    numBucketsInCluster =
+                            targetNumBuckets - (previousBucketsInCluster * (numClusters - 1));
+                }
+
+                final int numFrequenciesInCluster = clusterEndIdx - clusterStartIdx;
+                // If there are less frequencies than buckets in a cluster, we have one bucket per
+                // frequency, and do not use the remaining buckets
+                final int numFrequenciesInBucket =
+                        Math.max(1, numFrequenciesInCluster / numBucketsInCluster);
+                for (int bucketIdx = 0; bucketIdx < numBucketsInCluster; bucketIdx++) {
+                    int bucketStartIdx = clusterStartIdx + bucketIdx * numFrequenciesInBucket;
+                    // If we've gone over the end index, ignore the rest of the buckets for this
+                    // cluster
+                    if (bucketStartIdx >= clusterEndIdx) {
+                        break;
+                    }
+                    bucketStartIndices.add(bucketStartIdx);
+                }
             }
-            // Initialize the big buckets
-            for (int i = mBigFrequenciesStartIndex; i < values.length; i++) {
-                final int bucketIndex = Math.min(
-                        mLittleNumBuckets + (i - mBigFrequenciesStartIndex) / mBigBucketSize,
-                        mNumBuckets - 1);
-                bucketed[bucketIndex] += values[i];
+            return ArrayUtils.convertToIntArray(bucketStartIndices);
+        }
+
+        private static int getLowerBound(int index, int[] startIndices) {
+            return startIndices[index];
+        }
+
+        private static int getUpperBound(int index, int[] startIndices, int max) {
+            if (index != startIndices.length - 1) {
+                return startIndices[index + 1];
+            } else {
+                return max;
             }
-            return bucketed;
         }
     }
 
-    /**
-     * CPU usage of a process
-     */
+    /** CPU usage of a process */
     public static class ProcessCpuUsage {
         public final int processId;
         public final String processName;
         public final int uid;
-        public final ArrayList<ThreadCpuUsage> threadCpuUsages;
+        public ArrayList<ThreadCpuUsage> threadCpuUsages;
 
-        ProcessCpuUsage(
+        @VisibleForTesting
+        public ProcessCpuUsage(
                 int processId,
                 String processName,
                 int uid,
@@ -610,46 +534,24 @@
         }
     }
 
-    /**
-     * CPU usage of a thread
-     */
+    /** CPU usage of a thread */
     public static class ThreadCpuUsage {
         public final int threadId;
         public final String threadName;
-        public final int[] usageTimesMillis;
+        public int[] usageTimesMillis;
 
-        ThreadCpuUsage(
-                int threadId,
-                String threadName,
-                int[] usageTimesMillis) {
+        @VisibleForTesting
+        public ThreadCpuUsage(int threadId, String threadName, int[] usageTimesMillis) {
             this.threadId = threadId;
             this.threadName = threadName;
             this.usageTimesMillis = usageTimesMillis;
         }
     }
 
-    /**
-     * Used to inject static methods from {@link Process}
-     */
+    /** Used to inject static methods from {@link Process} */
     @VisibleForTesting
     public static class Injector {
-        /**
-         * Get the PID of the current process
-         */
-        public int myPid() {
-            return Process.myPid();
-        }
-
-        /**
-         * Get the UID that owns the current process
-         */
-        public int myUid() {
-            return Process.myUid();
-        }
-
-        /**
-         * Get the UID for the process with ID {@code pid}
-         */
+        /** Get the UID for the process with ID {@code pid} */
         public int getUidForPid(int pid) {
             return Process.getUidForPid(pid);
         }
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java b/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java
new file mode 100644
index 0000000..ffdc33c
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelCpuThreadReaderDiff.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.annotation.Nullable;
+import android.util.ArrayMap;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Delegates per-thread CPU collection to {@link KernelCpuThreadReader}, and calculates the
+ * difference between CPU usage at each call of {@link #getProcessCpuUsageDiffed()}.
+ *
+ * <p>Some notes on the diff calculation:
+ *
+ * <ul>
+ *   <li>The diffing is done between each call of {@link #getProcessCpuUsageDiffed()}, i.e. call N
+ *       of this method will return CPU used by threads between call N-1 and N.
+ *   <li>The first call of {@link #getProcessCpuUsageDiffed()} will return no processes ("first
+ *       call" is the first call in the lifetime of a {@link KernelCpuThreadReaderDiff} object).
+ *   <li>If a thread does not exist at call N, but does exist at call N+1, the diff will assume that
+ *       the CPU usage at call N was zero. Thus, the diff reported will be equivalent to the value
+ *       returned by {@link KernelCpuThreadReader#getProcessCpuUsage()} at call N+1.
+ *   <li>If an error occurs in {@link KernelCpuThreadReader} at call N, we will return no
+ *       information for CPU usage between call N-1 and N (as we don't know the start value) and
+ *       between N and N+1 (as we don't know the end value). Assuming all other calls are
+ *       successful, the next call to return data will be N+2, for the period between N+1 and N+2.
+ *   <li>If an error occurs in this class (but not in {@link KernelCpuThreadReader}) at call N, the
+ *       data will only be dropped for call N, as we can still use the CPU data for the surrounding
+ *       calls.
+ * </ul>
+ *
+ * <p>Additionally to diffing, this class also contains logic for thresholding reported threads. A
+ * thread will not be reported unless its total CPU usage is at least equal to the value set in
+ * {@link #setMinimumTotalCpuUsageMillis}. Filtered thread CPU usage is summed and reported under
+ * one "other threads" thread. This reduces the cardinality of the {@link
+ * #getProcessCpuUsageDiffed()} result.
+ *
+ * <p>Thresholding is done in this class, instead of {@link KernelCpuThreadReader}, and instead of
+ * WestWorld, because the thresholding should be done after diffing, not before. This is because of
+ * two issues with thresholding before diffing:
+ *
+ * <ul>
+ *   <li>We would threshold less and less threads as thread uptime increases.
+ *   <li>We would encounter errors as the filtered threads become unfiltered, as the "other threads"
+ *       result could have negative diffs, and the newly unfiltered threads would have incorrect
+ *       diffs that include CPU usage from when they were filtered.
+ * </ul>
+ *
+ * @hide Only for use within the system server
+ */
+@SuppressWarnings("ForLoopReplaceableByForEach")
+public class KernelCpuThreadReaderDiff {
+    private static final String TAG = "KernelCpuThreadReaderDiff";
+
+    /** Thread ID used when reporting CPU used by other threads */
+    private static final int OTHER_THREADS_ID = -1;
+
+    /** Thread name used when reporting CPU used by other threads */
+    private static final String OTHER_THREADS_NAME = "__OTHER_THREADS";
+
+    private final KernelCpuThreadReader mReader;
+
+    /**
+     * CPU usage from the previous call of {@link #getProcessCpuUsageDiffed()}. Null if there was no
+     * previous call, or if the previous call failed
+     *
+     * <p>Maps the thread's identifier to the per-frequency CPU usage for that thread. The
+     * identifier contains the minimal amount of information to identify a thread (see {@link
+     * ThreadKey} for more information), thus reducing memory consumption.
+     */
+    @Nullable private Map<ThreadKey, int[]> mPreviousCpuUsage;
+
+    /**
+     * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it
+     * will not be reported
+     */
+    private int mMinimumTotalCpuUsageMillis;
+
+    @VisibleForTesting
+    public KernelCpuThreadReaderDiff(KernelCpuThreadReader reader, int minimumTotalCpuUsageMillis) {
+        mReader = reader;
+        mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
+        mPreviousCpuUsage = null;
+    }
+
+    /**
+     * Returns the difference in CPU usage since the last time this method was called.
+     *
+     * @see KernelCpuThreadReader#getProcessCpuUsage()
+     */
+    @Nullable
+    public ArrayList<KernelCpuThreadReader.ProcessCpuUsage> getProcessCpuUsageDiffed() {
+        Map<ThreadKey, int[]> newCpuUsage = null;
+        try {
+            // Get the thread CPU usage and index them by ThreadKey
+            final ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
+                    mReader.getProcessCpuUsage();
+            newCpuUsage = createCpuUsageMap(processCpuUsages);
+            // If there is no previous CPU usage, return nothing
+            if (mPreviousCpuUsage == null) {
+                return null;
+            }
+
+            // Do diffing and thresholding for each process
+            for (int i = 0; i < processCpuUsages.size(); i++) {
+                KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
+                changeToDiffs(mPreviousCpuUsage, processCpuUsage);
+                applyThresholding(processCpuUsage);
+            }
+            return processCpuUsages;
+        } finally {
+            // Always update the previous CPU usage. If we haven't got an update, it will be set to
+            // null, so the next call knows there no previous values
+            mPreviousCpuUsage = newCpuUsage;
+        }
+    }
+
+    /** @see KernelCpuThreadReader#getCpuFrequenciesKhz() */
+    @Nullable
+    public int[] getCpuFrequenciesKhz() {
+        return mReader.getCpuFrequenciesKhz();
+    }
+
+    /**
+     * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it
+     * will not be reported
+     */
+    void setMinimumTotalCpuUsageMillis(int minimumTotalCpuUsageMillis) {
+        if (minimumTotalCpuUsageMillis < 0) {
+            Slog.w(TAG, "Negative minimumTotalCpuUsageMillis: " + minimumTotalCpuUsageMillis);
+            return;
+        }
+        mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
+    }
+
+    /**
+     * Create a map of a thread's identifier to a thread's CPU usage. Used for fast indexing when
+     * calculating diffs
+     */
+    private static Map<ThreadKey, int[]> createCpuUsageMap(
+            List<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages) {
+        final Map<ThreadKey, int[]> cpuUsageMap = new ArrayMap<>();
+        for (int i = 0; i < processCpuUsages.size(); i++) {
+            KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
+            for (int j = 0; j < processCpuUsage.threadCpuUsages.size(); j++) {
+                KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage =
+                        processCpuUsage.threadCpuUsages.get(j);
+                cpuUsageMap.put(
+                        new ThreadKey(
+                                processCpuUsage.processId,
+                                threadCpuUsage.threadId,
+                                processCpuUsage.processName,
+                                threadCpuUsage.threadName),
+                        threadCpuUsage.usageTimesMillis);
+            }
+        }
+        return cpuUsageMap;
+    }
+
+    /**
+     * Calculate the difference in per-frequency CPU usage for all threads in a process
+     *
+     * @param previousCpuUsage CPU usage from the last call, the base of the diff
+     * @param processCpuUsage CPU usage from the current call, this value is modified to contain the
+     *     diffed values
+     */
+    private static void changeToDiffs(
+            Map<ThreadKey, int[]> previousCpuUsage,
+            KernelCpuThreadReader.ProcessCpuUsage processCpuUsage) {
+        for (int i = 0; i < processCpuUsage.threadCpuUsages.size(); i++) {
+            KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage =
+                    processCpuUsage.threadCpuUsages.get(i);
+            final ThreadKey key =
+                    new ThreadKey(
+                            processCpuUsage.processId,
+                            threadCpuUsage.threadId,
+                            processCpuUsage.processName,
+                            threadCpuUsage.threadName);
+            int[] previous = previousCpuUsage.get(key);
+            if (previous == null) {
+                // If there's no previous CPU usage, assume that it's zero
+                previous = new int[threadCpuUsage.usageTimesMillis.length];
+            }
+            threadCpuUsage.usageTimesMillis =
+                    cpuTimeDiff(threadCpuUsage.usageTimesMillis, previous);
+        }
+    }
+
+    /**
+     * Filter out any threads with less than {@link #mMinimumTotalCpuUsageMillis} total CPU usage
+     *
+     * <p>The sum of the CPU usage of filtered threads is added under a single thread, labeled with
+     * {@link #OTHER_THREADS_ID} and {@link #OTHER_THREADS_NAME}.
+     *
+     * @param processCpuUsage CPU usage to apply thresholding to, this value is modified to change
+     *     the threads it contains
+     */
+    private void applyThresholding(KernelCpuThreadReader.ProcessCpuUsage processCpuUsage) {
+        int[] filteredThreadsCpuUsage = null;
+        final ArrayList<KernelCpuThreadReader.ThreadCpuUsage> thresholded = new ArrayList<>();
+        for (int i = 0; i < processCpuUsage.threadCpuUsages.size(); i++) {
+            KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage =
+                    processCpuUsage.threadCpuUsages.get(i);
+            if (mMinimumTotalCpuUsageMillis > totalCpuUsage(threadCpuUsage.usageTimesMillis)) {
+                if (filteredThreadsCpuUsage == null) {
+                    filteredThreadsCpuUsage = new int[threadCpuUsage.usageTimesMillis.length];
+                }
+                addToCpuUsage(filteredThreadsCpuUsage, threadCpuUsage.usageTimesMillis);
+                continue;
+            }
+            thresholded.add(threadCpuUsage);
+        }
+        if (filteredThreadsCpuUsage != null) {
+            thresholded.add(
+                    new KernelCpuThreadReader.ThreadCpuUsage(
+                            OTHER_THREADS_ID, OTHER_THREADS_NAME, filteredThreadsCpuUsage));
+        }
+        processCpuUsage.threadCpuUsages = thresholded;
+    }
+
+    /** Get the sum of all CPU usage across all frequencies */
+    private static int totalCpuUsage(int[] cpuUsage) {
+        int total = 0;
+        for (int i = 0; i < cpuUsage.length; i++) {
+            total += cpuUsage[i];
+        }
+        return total;
+    }
+
+    /** Add two CPU frequency usages together */
+    private static void addToCpuUsage(int[] a, int[] b) {
+        for (int i = 0; i < a.length; i++) {
+            a[i] += b[i];
+        }
+    }
+
+    /** Subtract two CPU frequency usages from each other */
+    private static int[] cpuTimeDiff(int[] a, int[] b) {
+        int[] difference = new int[a.length];
+        for (int i = 0; i < a.length; i++) {
+            difference[i] = a[i] - b[i];
+        }
+        return difference;
+    }
+
+    /**
+     * Identifies a thread
+     *
+     * <p>Only stores the minimum amount of information to identify a thread. This includes the
+     * PID/TID, but as both are recycled as processes/threads end and begin, we also store the hash
+     * of the name of the process/thread.
+     */
+    private static class ThreadKey {
+        private final int mProcessId;
+        private final int mThreadId;
+        private final int mProcessNameHash;
+        private final int mThreadNameHash;
+
+        ThreadKey(int processId, int threadId, String processName, String threadName) {
+            this.mProcessId = processId;
+            this.mThreadId = threadId;
+            // Only store the hash to reduce memory consumption
+            this.mProcessNameHash = Objects.hash(processName);
+            this.mThreadNameHash = Objects.hash(threadName);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mProcessId, mThreadId, mProcessNameHash, mThreadNameHash);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof ThreadKey)) {
+                return false;
+            }
+            ThreadKey other = (ThreadKey) obj;
+            return mProcessId == other.mProcessId
+                    && mThreadId == other.mThreadId
+                    && mProcessNameHash == other.mProcessNameHash
+                    && mThreadNameHash == other.mThreadNameHash;
+        }
+    }
+}
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
index b8dfe0d..f8c0d9e 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
@@ -47,55 +47,55 @@
 public class KernelCpuThreadReaderSettingsObserver extends ContentObserver {
     private static final String TAG = "KernelCpuThreadReaderSettingsObserver";
 
-    /**
-     * The number of frequency buckets to report
-     */
+    /** The number of frequency buckets to report */
     private static final String NUM_BUCKETS_SETTINGS_KEY = "num_buckets";
+
     private static final int NUM_BUCKETS_DEFAULT = 8;
 
-    /**
-     * List of UIDs to report data for
-     */
+    /** List of UIDs to report data for */
     private static final String COLLECTED_UIDS_SETTINGS_KEY = "collected_uids";
+
     private static final String COLLECTED_UIDS_DEFAULT = "0-0;1000-1000";
 
-    /**
-     * Minimum total CPU usage to report
-     */
+    /** Minimum total CPU usage to report */
     private static final String MINIMUM_TOTAL_CPU_USAGE_MILLIS_SETTINGS_KEY =
             "minimum_total_cpu_usage_millis";
+
     private static final int MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT = 10000;
 
     private final Context mContext;
 
-    @Nullable
-    private final KernelCpuThreadReader mKernelCpuThreadReader;
+    @Nullable private final KernelCpuThreadReader mKernelCpuThreadReader;
+
+    @Nullable private final KernelCpuThreadReaderDiff mKernelCpuThreadReaderDiff;
 
     /**
-     * @return returns a created {@link KernelCpuThreadReader} that will be modified by any
-     * change in settings, returns null if creation failed
+     * @return returns a created {@link KernelCpuThreadReader} that will be modified by any change
+     *     in settings, returns null if creation failed
      */
     @Nullable
-    public static KernelCpuThreadReader getSettingsModifiedReader(Context context) {
+    public static KernelCpuThreadReaderDiff getSettingsModifiedReader(Context context) {
         // Create the observer
         KernelCpuThreadReaderSettingsObserver settingsObserver =
                 new KernelCpuThreadReaderSettingsObserver(context);
         // Register the observer to listen for setting changes
-        Uri settingsUri =
-                Settings.Global.getUriFor(Settings.Global.KERNEL_CPU_THREAD_READER);
-        context.getContentResolver().registerContentObserver(
-                settingsUri, false, settingsObserver, UserHandle.USER_SYSTEM);
+        Uri settingsUri = Settings.Global.getUriFor(Settings.Global.KERNEL_CPU_THREAD_READER);
+        context.getContentResolver()
+                .registerContentObserver(
+                        settingsUri, false, settingsObserver, UserHandle.USER_SYSTEM);
         // Return the observer's reader
-        return settingsObserver.mKernelCpuThreadReader;
+        return settingsObserver.mKernelCpuThreadReaderDiff;
     }
 
     private KernelCpuThreadReaderSettingsObserver(Context context) {
         super(BackgroundThread.getHandler());
         mContext = context;
-        mKernelCpuThreadReader = KernelCpuThreadReader.create(
-                NUM_BUCKETS_DEFAULT,
-                UidPredicate.fromString(COLLECTED_UIDS_DEFAULT),
-                MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT);
+        mKernelCpuThreadReader =
+                KernelCpuThreadReader.create(
+                        NUM_BUCKETS_DEFAULT, UidPredicate.fromString(COLLECTED_UIDS_DEFAULT));
+        mKernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(
+                        mKernelCpuThreadReader, MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT);
     }
 
     @Override
@@ -103,9 +103,7 @@
         updateReader();
     }
 
-    /**
-     * Update the reader with new settings
-     */
+    /** Update the reader with new settings */
     private void updateReader() {
         if (mKernelCpuThreadReader == null) {
             return;
@@ -113,8 +111,10 @@
 
         final KeyValueListParser parser = new KeyValueListParser(',');
         try {
-            parser.setString(Settings.Global.getString(
-                    mContext.getContentResolver(), Settings.Global.KERNEL_CPU_THREAD_READER));
+            parser.setString(
+                    Settings.Global.getString(
+                            mContext.getContentResolver(),
+                            Settings.Global.KERNEL_CPU_THREAD_READER));
         } catch (IllegalArgumentException e) {
             Slog.e(TAG, "Bad settings", e);
             return;
@@ -122,8 +122,9 @@
 
         final UidPredicate uidPredicate;
         try {
-            uidPredicate = UidPredicate.fromString(
-                    parser.getString(COLLECTED_UIDS_SETTINGS_KEY, COLLECTED_UIDS_DEFAULT));
+            uidPredicate =
+                    UidPredicate.fromString(
+                            parser.getString(COLLECTED_UIDS_SETTINGS_KEY, COLLECTED_UIDS_DEFAULT));
         } catch (NumberFormatException e) {
             Slog.w(TAG, "Failed to get UID predicate", e);
             return;
@@ -132,14 +133,13 @@
         mKernelCpuThreadReader.setNumBuckets(
                 parser.getInt(NUM_BUCKETS_SETTINGS_KEY, NUM_BUCKETS_DEFAULT));
         mKernelCpuThreadReader.setUidPredicate(uidPredicate);
-        mKernelCpuThreadReader.setMinimumTotalCpuUsageMillis(parser.getInt(
-                MINIMUM_TOTAL_CPU_USAGE_MILLIS_SETTINGS_KEY,
-                MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT));
+        mKernelCpuThreadReaderDiff.setMinimumTotalCpuUsageMillis(
+                parser.getInt(
+                        MINIMUM_TOTAL_CPU_USAGE_MILLIS_SETTINGS_KEY,
+                        MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT));
     }
 
-    /**
-     * Check whether a UID belongs to a set of UIDs
-     */
+    /** Check whether a UID belongs to a set of UIDs */
     @VisibleForTesting
     public static class UidPredicate implements Predicate<Integer> {
         private static final Pattern UID_RANGE_PATTERN = Pattern.compile("([0-9]+)-([0-9]+)");
@@ -150,14 +150,14 @@
          * Create a UID predicate from a string representing a list of UID ranges
          *
          * <p>UID ranges are a pair of integers separated by a '-'. If you want to specify a single
-         * UID (e.g. UID 1000), you can use {@code 1000-1000}. Lists of ranges are separated by
-         * a single ';'. For example, this would be a valid string representation: {@code
+         * UID (e.g. UID 1000), you can use {@code 1000-1000}. Lists of ranges are separated by a
+         * single ';'. For example, this would be a valid string representation: {@code
          * "1000-1999;2003-2003;2004-2004;2050-2060"}.
          *
          * <p>We do not use ',' to delimit as it is already used in separating different setting
          * arguments.
          *
-         * @throws NumberFormatException    if the input string is incorrectly formatted
+         * @throws NumberFormatException if the input string is incorrectly formatted
          * @throws IllegalArgumentException if an UID range has a lower end than start
          */
         @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -169,9 +169,10 @@
                     throw new NumberFormatException(
                             "Failed to recognize as number range: " + uidSpecifier);
                 }
-                acceptedUidRanges.add(Range.create(
-                        Integer.parseInt(uidRangeMatcher.group(1)),
-                        Integer.parseInt(uidRangeMatcher.group(2))));
+                acceptedUidRanges.add(
+                        Range.create(
+                                Integer.parseInt(uidRangeMatcher.group(1)),
+                                Integer.parseInt(uidRangeMatcher.group(2))));
             }
             return new UidPredicate(acceptedUidRanges);
         }
@@ -181,6 +182,7 @@
         }
 
         @Override
+        @SuppressWarnings("ForLoopReplaceableByForEach")
         public boolean test(Integer uid) {
             for (int i = 0; i < mAcceptedUidRanges.size(); i++) {
                 if (mAcceptedUidRanges.get(i).contains(uid)) {
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 524a5cc..b0855f4 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -59,6 +59,8 @@
     // ------ ro.fw.* ------------ //
     public static final boolean FW_SYSTEM_USER_SPLIT =
             SystemProperties.getBoolean("ro.fw.system_user_split", false);
+    public static final boolean MULTIUSER_HEADLESS_SYSTEM_USER =
+            SystemProperties.getBoolean("ro.fw.multiuser.headless_system_user", false);
 
     // ------ ro.crypto.* -------- //
     public static final CryptoProperties.state_values CRYPTO_STATE =
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 992ddd8..8ca0bd1 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -24,6 +24,7 @@
 import android.net.Credentials;
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
+import android.os.Build;
 import android.os.FactoryTest;
 import android.os.IVold;
 import android.os.Process;
@@ -236,7 +237,7 @@
     public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
             int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
             int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
-            String packageName, String[] packagesForUID, String sandboxId) {
+            String packageName, String[] packagesForUID, String sandboxId, int targetSdkVersion) {
         ZygoteHooks.preFork();
         // Resets nice priority for zygote process.
         resetNicePriority();
@@ -246,6 +247,7 @@
                 packagesForUID, sandboxId);
         // Enable tracing as soon as possible for the child process.
         if (pid == 0) {
+            Zygote.disableExecuteOnly(targetSdkVersion);
             Trace.setTracingEnabled(true, runtimeFlags);
 
             // Note that this event ends at the end of handleChildProc,
@@ -514,6 +516,7 @@
     private static Runnable usapMain(LocalServerSocket usapPoolSocket,
                                      FileDescriptor writePipe) {
         final int pid = Process.myPid();
+        Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32");
 
         LocalSocket sessionSocket = null;
         DataOutputStream usapOutputStream = null;
@@ -599,6 +602,8 @@
                            args.mInstructionSet, args.mAppDataDir, args.mPackageName,
                            args.mPackagesForUid, args.mSandboxId);
 
+        disableExecuteOnly(args.mTargetSdkVersion);
+
         if (args.mNiceName != null) {
             Process.setArgV0(args.mNiceName);
         }
@@ -650,6 +655,17 @@
     }
 
     /**
+     * Mark execute-only segments of libraries read+execute for apps with targetSdkVersion<Q.
+     */
+    protected static void disableExecuteOnly(int targetSdkVersion) {
+        if ((targetSdkVersion < Build.VERSION_CODES.Q) && !nativeDisableExecuteOnly()) {
+            Log.e("Zygote", "Failed to set libraries to read+execute.");
+        }
+    }
+
+    private static native boolean nativeDisableExecuteOnly();
+
+    /**
      * @return  Raw file descriptors for the read-end of USAP reporting pipes.
      */
     protected static int[] getUsapPipeFDs() {
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 922c721..dd6fb72 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -268,7 +268,7 @@
                 parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                 parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                 parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mPackageName,
-                parsedArgs.mPackagesForUid, parsedArgs.mSandboxId);
+                parsedArgs.mPackagesForUid, parsedArgs.mSandboxId, parsedArgs.mTargetSdkVersion);
 
         try {
             if (pid == 0) {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index dd18060..7cca7b7 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -22,6 +22,8 @@
 import android.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.app.ApplicationLoaders;
+import android.content.pm.SharedLibraryInfo;
 import android.os.Build;
 import android.os.Environment;
 import android.os.IInstalld;
@@ -138,6 +140,9 @@
         bootTimingsTraceLog.traceBegin("PreloadClasses");
         preloadClasses();
         bootTimingsTraceLog.traceEnd(); // PreloadClasses
+        bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");
+        cacheNonBootClasspathClassLoaders();
+        bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
         bootTimingsTraceLog.traceBegin("PreloadResources");
         preloadResources();
         bootTimingsTraceLog.traceEnd(); // PreloadResources
@@ -344,6 +349,32 @@
     }
 
     /**
+     * Load in things which are used by many apps but which cannot be put in the boot
+     * classpath.
+     */
+    private static void cacheNonBootClasspathClassLoaders() {
+        // These libraries used to be part of the bootclasspath, but had to be removed.
+        // Old system applications still get them for backwards compatibility reasons,
+        // so they are cached here in order to preserve performance characteristics.
+        SharedLibraryInfo hidlBase = new SharedLibraryInfo(
+                "/system/framework/android.hidl.base-V1.0-java.jar", null /*packageName*/,
+                null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
+                null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/);
+        SharedLibraryInfo hidlManager = new SharedLibraryInfo(
+                "/system/framework/android.hidl.manager-V1.0-java.jar", null /*packageName*/,
+                null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
+                null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/);
+        hidlManager.addDependency(hidlBase);
+
+        ApplicationLoaders.getDefault().createAndCacheNonBootclasspathSystemClassLoaders(
+                new SharedLibraryInfo[]{
+                    // ordered dependencies first
+                    hidlBase,
+                    hidlManager,
+                });
+    }
+
+    /**
      * Load in commonly used resources, so they can be shared across processes.
      *
      * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index ca5db94..625814d 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1143,7 +1143,6 @@
         // If we didn't request fullscreen layout, but we still got it because of the
         // mForceWindowDrawsStatusBarBackground flag, also consume top inset.
         boolean consumingStatusBar = (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0
-                && (sysUiVisibility & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
                 && (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0
                 && (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0
                 && mForceWindowDrawsStatusBarBackground
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 3303374..e8691fa 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -527,6 +527,13 @@
         return (array != null) ? array.clone() : null;
     }
 
+    /**
+     * Clones an array or returns null if the array is null.
+     */
+    public static @Nullable <T> T[] cloneOrNull(@Nullable T[] array) {
+        return (array != null) ? array.clone() : null;
+    }
+
     public static @Nullable <T> ArraySet<T> cloneOrNull(@Nullable ArraySet<T> array) {
         return (array != null) ? new ArraySet<T>(array) : null;
     }
diff --git a/core/java/com/android/internal/util/SyncResultReceiver.java b/core/java/com/android/internal/util/SyncResultReceiver.java
index 60af511..00e9101 100644
--- a/core/java/com/android/internal/util/SyncResultReceiver.java
+++ b/core/java/com/android/internal/util/SyncResultReceiver.java
@@ -19,10 +19,10 @@
 import android.annotation.Nullable;
 import android.os.Bundle;
 import android.os.Parcelable;
-import android.os.RemoteException;
 
 import com.android.internal.os.IResultReceiver;
 
+import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -97,6 +97,15 @@
     }
 
     /**
+     * Gets the result from an operation that returns a {@code Parcelable} list.
+     */
+    @Nullable
+    public <P extends Parcelable> ArrayList<P> getParcelableListResult() throws TimeoutException {
+        waitResult();
+        return mBundle == null ? null : mBundle.getParcelableArrayList(EXTRA);
+    }
+
+    /**
      * Gets the optional result from an operation that returns an extra {@code int} (besides the
      * result code).
      *
@@ -150,6 +159,17 @@
     }
 
     /**
+     * Creates a bundle for a {@code Parcelable} list so it can be retrieved by
+     * {@link #getParcelableResult()}.
+     */
+    @NonNull
+    public static Bundle bundleFor(@Nullable ArrayList<? extends Parcelable> value) {
+        final Bundle bundle = new Bundle();
+        bundle.putParcelableArrayList(EXTRA, value);
+        return bundle;
+    }
+
+    /**
      * Creates a bundle for an {@code int} value so it can be retrieved by
      * {@link #getParcelableResult()} - typically used to return an extra {@code int} (as the 1st
      * is returned as the result code).
@@ -162,7 +182,7 @@
     }
 
     /** @hide */
-    public static final class TimeoutException extends RemoteException {
+    public static final class TimeoutException extends RuntimeException {
         private TimeoutException(String msg) {
             super(msg);
         }
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 9722fcb..a160b57 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -868,6 +868,13 @@
         setMeasuredDimension(sourceWidth, heightSize);
     }
 
+    /**
+      * @return The space reserved by views with 'alwaysShow=true'
+      */
+    public int getUncollapsibleHeight() {
+        return mUncollapsibleHeight;
+    }
+
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         final int width = getWidth();
diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index 621d5a6..dc4f09a 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -307,6 +307,9 @@
         if (tag.equals(TAG_TOMBSTONE) && fileContents.contains(">>> system_server <<<")) {
             addTextToDropBox(db, "system_server_native_crash", text, filename, maxSize);
         }
+        if (tag.equals(TAG_TOMBSTONE)) {
+            StatsLog.write(StatsLog.TOMB_STONE_OCCURRED);
+        }
         addTextToDropBox(db, tag, text, filename, maxSize);
     }
 
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 561dcad..9fc79cb 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -1150,16 +1150,6 @@
                 XmlUtils.skipCurrentTag(parser);
             }
         }
-        // If the storage model feature flag is disabled, we need to fiddle
-        // around with permission definitions to return us to pre-Q behavior.
-        // STOPSHIP(b/112545973): remove once feature enabled by default
-        if (!StorageManager.hasIsolatedStorage()) {
-            if (newPermissions.contains(android.Manifest.permission.READ_MEDIA_AUDIO) ||
-                    newPermissions.contains(android.Manifest.permission.READ_MEDIA_VIDEO) ||
-                    newPermissions.contains(android.Manifest.permission.READ_MEDIA_IMAGES)) {
-                return;
-            }
-        }
         if (!newPermissions.isEmpty()) {
             mSplitPermissions.add(new SplitPermissionInfo(splitPerm, newPermissions, targetSdk));
         }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 664f7f4..000c044 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -303,6 +303,7 @@
         "libnativewindow",
         "libhwui",
         "libdl",
+        "libdl_android",
         "libstatslog",
         "server_configurable_flags",
     ],
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index e0b7629..a4e3709 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -39,7 +39,6 @@
 static jfieldID gBitmap_nativePtr;
 static jmethodID gBitmap_constructorMethodID;
 static jmethodID gBitmap_reinitMethodID;
-static jmethodID gBitmap_getAllocationByteCountMethodID;
 
 namespace android {
 
@@ -193,11 +192,6 @@
             info.width(), info.height(), isPremultiplied);
 }
 
-int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap)
-{
-    return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID);
-}
-
 jobject createBitmap(JNIEnv* env, Bitmap* bitmap,
         int bitmapCreateFlags, jbyteArray ninePatchChunk, jobject ninePatchInsets,
         int density) {
@@ -236,8 +230,7 @@
     return localBitmap->bitmap();
 }
 
-Bitmap& toBitmap(JNIEnv* env, jlong bitmapHandle) {
-    SkASSERT(env);
+Bitmap& toBitmap(jlong bitmapHandle) {
     LocalScopedBitmap localBitmap(bitmapHandle);
     return localBitmap->bitmap();
 }
@@ -1227,7 +1220,6 @@
     gBitmap_nativePtr = GetFieldIDOrDie(env, gBitmap_class, "mNativePtr", "J");
     gBitmap_constructorMethodID = GetMethodIDOrDie(env, gBitmap_class, "<init>", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V");
     gBitmap_reinitMethodID = GetMethodIDOrDie(env, gBitmap_class, "reinit", "(IIZ)V");
-    gBitmap_getAllocationByteCountMethodID = GetMethodIDOrDie(env, gBitmap_class, "getAllocationByteCount", "()I");
     return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods,
                                          NELEM(gBitmapMethods));
 }
diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h
index 06877915..6934d26 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -41,7 +41,7 @@
 void toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap);
 
 Bitmap& toBitmap(JNIEnv* env, jobject bitmap);
-Bitmap& toBitmap(JNIEnv* env, jlong bitmapHandle);
+Bitmap& toBitmap(jlong bitmapHandle);
 
 // NDK access
 void imageInfo(JNIEnv* env, jobject bitmap, AndroidBitmapInfo* info);
@@ -56,8 +56,6 @@
 void reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info,
         bool isPremultiplied);
 
-int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap);
-
 } // namespace bitmap
 
 } // namespace android
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 47b1548..3f05c3b 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -180,7 +180,8 @@
 }
 
 static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream,
-                        jobject padding, jobject options, jlong colorSpaceHandle) {
+                        jobject padding, jobject options, jlong inBitmapHandle,
+                        jlong colorSpaceHandle) {
     // Set default values for the options parameters.
     int sampleSize = 1;
     bool onlyDecodeSize = false;
@@ -323,14 +324,14 @@
 
     android::Bitmap* reuseBitmap = nullptr;
     unsigned int existingBufferSize = 0;
-    if (javaBitmap != NULL) {
-        reuseBitmap = &bitmap::toBitmap(env, javaBitmap);
+    if (javaBitmap != nullptr) {
+        reuseBitmap = &bitmap::toBitmap(inBitmapHandle);
         if (reuseBitmap->isImmutable()) {
             ALOGW("Unable to reuse an immutable bitmap as an image decoder target.");
-            javaBitmap = NULL;
+            javaBitmap = nullptr;
             reuseBitmap = nullptr;
         } else {
-            existingBufferSize = bitmap::getBitmapAllocationByteCount(env, javaBitmap);
+            existingBufferSize = reuseBitmap->getAllocationByteCount();
         }
     }
 
@@ -513,7 +514,7 @@
 }
 
 static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
-        jobject padding, jobject options, jlong colorSpaceHandle) {
+        jobject padding, jobject options, jlong inBitmapHandle, jlong colorSpaceHandle) {
 
     jobject bitmap = NULL;
     std::unique_ptr<SkStream> stream(CreateJavaInputStreamAdaptor(env, is, storage));
@@ -522,13 +523,14 @@
         std::unique_ptr<SkStreamRewindable> bufferedStream(
                 SkFrontBufferedStream::Make(std::move(stream), SkCodec::MinBufferedBytesNeeded()));
         SkASSERT(bufferedStream.get() != NULL);
-        bitmap = doDecode(env, std::move(bufferedStream), padding, options, colorSpaceHandle);
+        bitmap = doDecode(env, std::move(bufferedStream), padding, options, inBitmapHandle,
+                          colorSpaceHandle);
     }
     return bitmap;
 }
 
 static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fileDescriptor,
-        jobject padding, jobject bitmapFactoryOptions, jlong colorSpaceHandle) {
+        jobject padding, jobject bitmapFactoryOptions, jlong inBitmapHandle, jlong colorSpaceHandle) {
 
     NPE_CHECK_RETURN_ZERO(env, fileDescriptor);
 
@@ -565,7 +567,7 @@
     if (::lseek(descriptor, 0, SEEK_CUR) == 0) {
         assert(isSeekable(dupDescriptor));
         return doDecode(env, std::move(fileStream), padding, bitmapFactoryOptions,
-                colorSpaceHandle);
+                        inBitmapHandle, colorSpaceHandle);
     }
 
     // Use a buffered stream. Although an SkFILEStream can be rewound, this
@@ -574,25 +576,26 @@
     std::unique_ptr<SkStreamRewindable> stream(SkFrontBufferedStream::Make(std::move(fileStream),
             SkCodec::MinBufferedBytesNeeded()));
 
-    return doDecode(env, std::move(stream), padding, bitmapFactoryOptions, colorSpaceHandle);
+    return doDecode(env, std::move(stream), padding, bitmapFactoryOptions, inBitmapHandle,
+                    colorSpaceHandle);
 }
 
 static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jlong native_asset,
-        jobject padding, jobject options, jlong colorSpaceHandle) {
+        jobject padding, jobject options, jlong inBitmapHandle, jlong colorSpaceHandle) {
 
     Asset* asset = reinterpret_cast<Asset*>(native_asset);
     // since we know we'll be done with the asset when we return, we can
     // just use a simple wrapper
     return doDecode(env, skstd::make_unique<AssetStreamAdaptor>(asset), padding, options,
-            colorSpaceHandle);
+                    inBitmapHandle, colorSpaceHandle);
 }
 
 static jobject nativeDecodeByteArray(JNIEnv* env, jobject, jbyteArray byteArray,
-        jint offset, jint length, jobject options, jlong colorSpaceHandle) {
+        jint offset, jint length, jobject options, jlong inBitmapHandle, jlong colorSpaceHandle) {
 
     AutoJavaByteArray ar(env, byteArray);
     return doDecode(env, skstd::make_unique<SkMemoryStream>(ar.ptr() + offset, length, false),
-                    nullptr, options, colorSpaceHandle);
+                    nullptr, options, inBitmapHandle, colorSpaceHandle);
 }
 
 static jboolean nativeIsSeekable(JNIEnv* env, jobject, jobject fileDescriptor) {
@@ -604,22 +607,22 @@
 
 static const JNINativeMethod gMethods[] = {
     {   "nativeDecodeStream",
-        "(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;J)Landroid/graphics/Bitmap;",
+        "(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;JJ)Landroid/graphics/Bitmap;",
         (void*)nativeDecodeStream
     },
 
     {   "nativeDecodeFileDescriptor",
-        "(Ljava/io/FileDescriptor;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;J)Landroid/graphics/Bitmap;",
+        "(Ljava/io/FileDescriptor;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;JJ)Landroid/graphics/Bitmap;",
         (void*)nativeDecodeFileDescriptor
     },
 
     {   "nativeDecodeAsset",
-        "(JLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;J)Landroid/graphics/Bitmap;",
+        "(JLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;JJ)Landroid/graphics/Bitmap;",
         (void*)nativeDecodeAsset
     },
 
     {   "nativeDecodeByteArray",
-        "([BIILandroid/graphics/BitmapFactory$Options;J)Landroid/graphics/Bitmap;",
+        "([BIILandroid/graphics/BitmapFactory$Options;JJ)Landroid/graphics/Bitmap;",
         (void*)nativeDecodeByteArray
     },
 
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index 9c07e2d..6ffa72a 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -125,13 +125,14 @@
  * reportSizeToVM not supported
  */
 static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, jint inputX,
-        jint inputY, jint inputWidth, jint inputHeight, jobject options, jlong colorSpaceHandle) {
+        jint inputY, jint inputWidth, jint inputHeight, jobject options, jlong inBitmapHandle,
+        jlong colorSpaceHandle) {
 
     // Set default options.
     int sampleSize = 1;
     SkColorType colorType = kN32_SkColorType;
     bool requireUnpremul = false;
-    jobject javaBitmap = NULL;
+    jobject javaBitmap = nullptr;
     bool isHardware = false;
     sk_sp<SkColorSpace> colorSpace = GraphicsJNI::getNativeColorSpace(colorSpaceHandle);
     // Update the default options with any options supplied by the client.
@@ -158,11 +159,11 @@
     android::Bitmap* recycledBitmap = nullptr;
     size_t recycledBytes = 0;
     if (javaBitmap) {
-        recycledBitmap = &bitmap::toBitmap(env, javaBitmap);
+        recycledBitmap = &bitmap::toBitmap(inBitmapHandle);
         if (recycledBitmap->isImmutable()) {
             ALOGW("Warning: Reusing an immutable bitmap as an image decoder target.");
         }
-        recycledBytes = bitmap::getBitmapAllocationByteCount(env, javaBitmap);
+        recycledBytes = recycledBitmap->getAllocationByteCount();
     }
 
     SkBitmapRegionDecoder* brd = reinterpret_cast<SkBitmapRegionDecoder*>(brdHandle);
@@ -258,7 +259,7 @@
 
 static const JNINativeMethod gBitmapRegionDecoderMethods[] = {
     {   "nativeDecodeRegion",
-        "(JIIIILandroid/graphics/BitmapFactory$Options;J)Landroid/graphics/Bitmap;",
+        "(JIIIILandroid/graphics/BitmapFactory$Options;JJ)Landroid/graphics/Bitmap;",
         (void*)nativeDecodeRegion},
 
     {   "nativeGetHeight", "(J)I", (void*)nativeGetHeight},
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index bb291e7..15f9516 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -84,13 +84,13 @@
         delete[] patch;
     }
 
-    static jlong getTransparentRegion(JNIEnv* env, jobject, jobject jbitmap,
+    static jlong getTransparentRegion(JNIEnv* env, jobject, jlong bitmapPtr,
             jlong chunkHandle, jobject dstRect) {
         Res_png_9patch* chunk = reinterpret_cast<Res_png_9patch*>(chunkHandle);
         SkASSERT(chunk);
 
         SkBitmap bitmap;
-        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+        bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
         SkRect dst;
         GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
 
@@ -156,7 +156,7 @@
     { "validateNinePatchChunk", "([B)J",
             (void*) SkNinePatchGlue::validateNinePatchChunk },
     { "nativeFinalize", "(J)V", (void*) SkNinePatchGlue::finalize },
-    { "nativeGetTransparentRegion", "(Landroid/graphics/Bitmap;JLandroid/graphics/Rect;)J",
+    { "nativeGetTransparentRegion", "(JJLandroid/graphics/Rect;)J",
             (void*) SkNinePatchGlue::getTransparentRegion }
 };
 
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 298f7f8..44d2cac 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -62,14 +62,14 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
-static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jobject jbitmap,
+static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
         jint tileModeX, jint tileModeY) {
     const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
     sk_sp<SkImage> image;
-    if (jbitmap) {
+    if (bitmapHandle) {
         // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
         // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
-        image = android::bitmap::toBitmap(env, jbitmap).makeImage();
+        image = android::bitmap::toBitmap(bitmapHandle).makeImage();
     }
 
     if (!image.get()) {
@@ -222,7 +222,7 @@
 };
 
 static const JNINativeMethod gBitmapShaderMethods[] = {
-    { "nativeCreate",      "(JLandroid/graphics/Bitmap;II)J",  (void*)BitmapShader_constructor },
+    { "nativeCreate",      "(JJII)J",  (void*)BitmapShader_constructor },
 };
 
 static const JNINativeMethod gLinearGradientMethods[] = {
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index 32ac30f..761830b 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -73,12 +73,12 @@
 }
 
 static void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong pagePtr,
-        jobject jbitmap, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom,
+        jlong bitmapPtr, jint clipLeft, jint clipTop, jint clipRight, jint clipBottom,
         jlong transformPtr, jint renderMode) {
     FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
 
     SkBitmap skBitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &skBitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&skBitmap);
 
     const int stride = skBitmap.width() * 4;
 
@@ -117,7 +117,7 @@
     {"nativeClose", "(J)V", (void*) nativeClose},
     {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount},
     {"nativeScaleForPrinting", "(J)Z", (void*) nativeScaleForPrinting},
-    {"nativeRenderPage", "(JJLandroid/graphics/Bitmap;IIIIJI)V", (void*) nativeRenderPage},
+    {"nativeRenderPage", "(JJJIIIIJI)V", (void*) nativeRenderPage},
     {"nativeOpenPageAndGetSize", "(JILandroid/graphics/Point;)J", (void*) nativeOpenPageAndGetSize},
     {"nativeClosePage", "(J)V", (void*) nativeClosePage}
 };
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index d50e60c..09f0e8e 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -703,27 +703,27 @@
 }
 
 static jint util_getInternalFormat(JNIEnv *env, jclass clazz,
-        jobject jbitmap)
+        jlong bitmapPtr)
 {
     SkBitmap nativeBitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &nativeBitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&nativeBitmap);
     return getInternalFormat(nativeBitmap.colorType());
 }
 
 static jint util_getType(JNIEnv *env, jclass clazz,
-        jobject jbitmap)
+        jlong bitmapPtr)
 {
     SkBitmap nativeBitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &nativeBitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&nativeBitmap);
     return getType(nativeBitmap.colorType());
 }
 
 static jint util_texImage2D(JNIEnv *env, jclass clazz,
         jint target, jint level, jint internalformat,
-        jobject jbitmap, jint type, jint border)
+        jlong bitmapPtr, jint type, jint border)
 {
     SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
     SkColorType colorType = bitmap.colorType();
     if (internalformat < 0) {
         internalformat = getInternalFormat(colorType);
@@ -748,10 +748,10 @@
 
 static jint util_texSubImage2D(JNIEnv *env, jclass clazz,
         jint target, jint level, jint xoffset, jint yoffset,
-        jobject jbitmap, jint format, jint type)
+        jlong bitmapPtr, jint format, jint type)
 {
     SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
     SkColorType colorType = bitmap.colorType();
     int internalFormat = getInternalFormat(colorType);
     if (format < 0) {
@@ -1068,10 +1068,10 @@
 };
 
 static const JNINativeMethod gUtilsMethods[] = {
-    { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat },
-    { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType },
-    { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D },
-    { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D },
+    { "native_getInternalFormat", "(J)I", (void*) util_getInternalFormat },
+    { "native_getType", "(J)I", (void*) util_getType },
+    { "native_texImage2D", "(IIIJII)I", (void*)util_texImage2D },
+    { "native_texSubImage2D", "(IIIIJII)I", (void*)util_texSubImage2D },
 };
 
 static const JNINativeMethod gEtc1Methods[] = {
diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp
index f40b461..bd4862d 100644
--- a/core/jni/android_content_res_ApkAssets.cpp
+++ b/core/jni/android_content_res_ApkAssets.cpp
@@ -106,8 +106,7 @@
 
 static jboolean NativeIsUpToDate(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) {
   const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
-  (void)apk_assets;
-  return JNI_TRUE;
+  return apk_assets->IsUpToDate() ? JNI_TRUE : JNI_FALSE;
 }
 
 static jlong NativeOpenXml(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring file_name) {
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index 86cda44..5e4d6e3 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -92,7 +92,9 @@
     CursorWindow* window;
     status_t status = CursorWindow::create(name, cursorWindowSize, &window);
     if (status || !window) {
-        ALOGE("Could not allocate CursorWindow '%s' of size %d due to error %d.",
+        jniThrowExceptionFmt(env,
+                "android/database/CursorWindowAllocationException",
+                "Could not allocate CursorWindow '%s' of size %d due to error %d.",
                 name.string(), cursorWindowSize, status);
         return 0;
     }
@@ -107,7 +109,9 @@
     CursorWindow* window;
     status_t status = CursorWindow::createFromParcel(parcel, &window);
     if (status || !window) {
-        ALOGE("Could not create CursorWindow from Parcel due to error %d, process fd count=%d",
+        jniThrowExceptionFmt(env,
+                "android/database/CursorWindowAllocationException",
+                "Could not create CursorWindow from Parcel due to error %d, process fd count=%d",
                 status, getFdCount());
         return 0;
     }
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 9c48c33..7a8c5c8 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -54,20 +54,20 @@
 }
 
 // Native wrapper constructor used by Canvas(Bitmap)
-static jlong initRaster(JNIEnv* env, jobject, jobject jbitmap) {
+static jlong initRaster(JNIEnv* env, jobject, jlong bitmapHandle) {
     SkBitmap bitmap;
-    if (jbitmap != NULL) {
-        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    if (bitmapHandle != 0) {
+        bitmap::toBitmap(bitmapHandle).getSkBitmap(&bitmap);
     }
     return reinterpret_cast<jlong>(Canvas::create_canvas(bitmap));
 }
 
 // Set the given bitmap as the new draw target (wrapped in a new SkCanvas),
 // optionally copying canvas matrix & clip state.
-static void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap) {
+static void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle) {
     SkBitmap bitmap;
-    if (jbitmap != NULL) {
-        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    if (bitmapHandle != 0) {
+        bitmap::toBitmap(bitmapHandle).getSkBitmap(&bitmap);
     }
     get_canvas(canvasHandle)->setBitmap(bitmap);
 }
@@ -397,7 +397,7 @@
         jlong paintHandle, jint dstDensity, jint srcDensity) {
 
     Canvas* canvas = get_canvas(canvasHandle);
-    Bitmap& bitmap = android::bitmap::toBitmap(env, bitmapHandle);
+    Bitmap& bitmap = android::bitmap::toBitmap(bitmapHandle);
     const android::Res_png_9patch* chunk = reinterpret_cast<android::Res_png_9patch*>(chunkHandle);
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
 
@@ -423,11 +423,11 @@
     }
 }
 
-static void drawBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
+static void drawBitmap(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
                        jfloat left, jfloat top, jlong paintHandle, jint canvasDensity,
                        jint screenDensity, jint bitmapDensity) {
     Canvas* canvas = get_canvas(canvasHandle);
-    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
+    Bitmap& bitmap = android::bitmap::toBitmap(bitmapHandle);
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
 
     if (canvasDensity == bitmapDensity || canvasDensity == 0 || bitmapDensity == 0) {
@@ -458,22 +458,22 @@
     }
 }
 
-static void drawBitmapMatrix(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
+static void drawBitmapMatrix(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
                              jlong matrixHandle, jlong paintHandle) {
     const SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
-    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
+    Bitmap& bitmap = android::bitmap::toBitmap(bitmapHandle);
     get_canvas(canvasHandle)->drawBitmap(bitmap, *matrix, paint);
 }
 
-static void drawBitmapRect(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
+static void drawBitmapRect(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
                            float srcLeft, float srcTop, float srcRight, float srcBottom,
                            float dstLeft, float dstTop, float dstRight, float dstBottom,
                            jlong paintHandle, jint screenDensity, jint bitmapDensity) {
     Canvas* canvas = get_canvas(canvasHandle);
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
 
-    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
+    Bitmap& bitmap = android::bitmap::toBitmap(bitmapHandle);
     if (screenDensity != 0 && screenDensity != bitmapDensity) {
         Paint filteredPaint;
         if (paint) {
@@ -512,7 +512,7 @@
     get_canvas(canvasHandle)->drawBitmap(*androidBitmap, x, y, paint);
 }
 
-static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap,
+static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle,
                            jint meshWidth, jint meshHeight, jfloatArray jverts,
                            jint vertIndex, jintArray jcolors, jint colorIndex, jlong paintHandle) {
     if (Canvas::GetApiLevel() < __ANDROID_API_P__) {
@@ -527,7 +527,7 @@
     AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount);
 
     const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
-    Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
+    Bitmap& bitmap = android::bitmap::toBitmap(bitmapHandle);
     get_canvas(canvasHandle)->drawBitmapMesh(bitmap, meshWidth, meshHeight,
                                              vertA.ptr() + vertIndex*2,
                                              colorA.ptr() + colorIndex, paint);
@@ -651,13 +651,13 @@
 
 static const JNINativeMethod gMethods[] = {
     {"nGetNativeFinalizer", "()J", (void*) CanvasJNI::getNativeFinalizer},
-    {"nInitRaster", "(Landroid/graphics/Bitmap;)J", (void*) CanvasJNI::initRaster},
     {"nFreeCaches", "()V", (void*) CanvasJNI::freeCaches},
     {"nFreeTextLayoutCaches", "()V", (void*) CanvasJNI::freeTextLayoutCaches},
     {"nSetCompatibilityVersion", "(I)V", (void*) CanvasJNI::setCompatibilityVersion},
 
     // ------------ @FastNative ----------------
-    {"nSetBitmap", "(JLandroid/graphics/Bitmap;)V", (void*) CanvasJNI::setBitmap},
+    {"nInitRaster", "(J)J", (void*) CanvasJNI::initRaster},
+    {"nSetBitmap", "(JJ)V", (void*) CanvasJNI::setBitmap},
     {"nGetClipBounds","(JLandroid/graphics/Rect;)Z", (void*) CanvasJNI::getClipBounds},
 
     // ------------ @CriticalNative ----------------
@@ -706,10 +706,10 @@
     {"nDrawPath","(JJJ)V", (void*) CanvasJNI::drawPath},
     {"nDrawVertices", "(JII[FI[FI[II[SIIJ)V", (void*)CanvasJNI::drawVertices},
     {"nDrawNinePatch", "(JJJFFFFJII)V", (void*)CanvasJNI::drawNinePatch},
-    {"nDrawBitmapMatrix", "(JLandroid/graphics/Bitmap;JJ)V", (void*)CanvasJNI::drawBitmapMatrix},
-    {"nDrawBitmapMesh", "(JLandroid/graphics/Bitmap;II[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh},
-    {"nDrawBitmap","(JLandroid/graphics/Bitmap;FFJIII)V", (void*) CanvasJNI::drawBitmap},
-    {"nDrawBitmap","(JLandroid/graphics/Bitmap;FFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect},
+    {"nDrawBitmapMatrix", "(JJJJ)V", (void*)CanvasJNI::drawBitmapMatrix},
+    {"nDrawBitmapMesh", "(JJII[FI[IIJ)V", (void*)CanvasJNI::drawBitmapMesh},
+    {"nDrawBitmap","(JJFFJIII)V", (void*) CanvasJNI::drawBitmap},
+    {"nDrawBitmap","(JJFFFFFFFFJII)V", (void*) CanvasJNI::drawBitmapRect},
     {"nDrawBitmap", "(J[IIIFFIIZJ)V", (void*)CanvasJNI::drawBitmapArray},
     {"nDrawText","(J[CIIFFIJ)V", (void*) CanvasJNI::drawTextChars},
     {"nDrawText","(JLjava/lang/String;IIFFIJ)V", (void*) CanvasJNI::drawTextString},
diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp
index c7805ea..03057dc 100644
--- a/core/jni/android_hardware_SoundTrigger.cpp
+++ b/core/jni/android_hardware_SoundTrigger.cpp
@@ -21,6 +21,7 @@
 
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
 #include "core_jni_helpers.h"
 #include <system/sound_trigger.h>
 #include <soundtrigger/SoundTriggerCallback.h>
@@ -395,7 +396,7 @@
 
 static jint
 android_hardware_SoundTrigger_listModules(JNIEnv *env, jobject clazz,
-                                          jobject jModules)
+                                          jstring opPackageName, jobject jModules)
 {
     ALOGV("listModules");
 
@@ -411,7 +412,10 @@
     unsigned int numModules = 0;
     struct sound_trigger_module_descriptor *nModules = NULL;
 
-    status_t status = SoundTrigger::listModules(nModules, &numModules);
+    ScopedUtfChars opPackageNameStr(env, opPackageName);
+    const String16 opPackageNameString16 = String16(opPackageNameStr.c_str());
+
+    status_t status = SoundTrigger::listModules(opPackageNameString16, nModules, &numModules);
     if (status != NO_ERROR || numModules == 0) {
         return (jint)status;
     }
@@ -419,7 +423,7 @@
     nModules = (struct sound_trigger_module_descriptor *)
                             calloc(numModules, sizeof(struct sound_trigger_module_descriptor));
 
-    status = SoundTrigger::listModules(nModules, &numModules);
+    status = SoundTrigger::listModules(opPackageNameString16, nModules, &numModules);
     ALOGV("listModules SoundTrigger::listModules status %d numModules %d", status, numModules);
 
     if (status != NO_ERROR) {
@@ -470,16 +474,20 @@
 }
 
 static void
-android_hardware_SoundTrigger_setup(JNIEnv *env, jobject thiz, jobject weak_this)
+android_hardware_SoundTrigger_setup(JNIEnv *env, jobject thiz,
+                                    jstring opPackageName, jobject weak_this)
 {
     ALOGV("setup");
 
+    ScopedUtfChars opPackageNameStr(env, opPackageName);
+    const String16 opPackageNameString16 = String16(opPackageNameStr.c_str());
+
     sp<JNISoundTriggerCallback> callback = new JNISoundTriggerCallback(env, thiz, weak_this);
 
     sound_trigger_module_handle_t handle =
             (sound_trigger_module_handle_t)env->GetIntField(thiz, gModuleFields.mId);
 
-    sp<SoundTrigger> module = SoundTrigger::attach(handle, callback);
+    sp<SoundTrigger> module = SoundTrigger::attach(opPackageNameString16, handle, callback);
     if (module == 0) {
         return;
     }
@@ -816,14 +824,14 @@
 
 static const JNINativeMethod gMethods[] = {
     {"listModules",
-        "(Ljava/util/ArrayList;)I",
+        "(Ljava/lang/String;Ljava/util/ArrayList;)I",
         (void *)android_hardware_SoundTrigger_listModules},
 };
 
 
 static const JNINativeMethod gModuleMethods[] = {
     {"native_setup",
-        "(Ljava/lang/Object;)V",
+        "(Ljava/lang/String;Ljava/lang/Object;)V",
         (void *)android_hardware_SoundTrigger_setup},
     {"native_finalize",
         "()V",
diff --git a/core/jni/android_hardware_input_InputApplicationHandle.cpp b/core/jni/android_hardware_input_InputApplicationHandle.cpp
index b9301d4..71edfd5 100644
--- a/core/jni/android_hardware_input_InputApplicationHandle.cpp
+++ b/core/jni/android_hardware_input_InputApplicationHandle.cpp
@@ -56,30 +56,25 @@
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     jobject obj = env->NewLocalRef(mObjWeak);
     if (!obj) {
-        releaseInfo();
         return false;
     }
 
-    if (!mInfo) {
-        mInfo = new InputApplicationInfo();
-    }
+    mInfo.name = getStringField(env, obj, gInputApplicationHandleClassInfo.name, "<null>");
 
-    mInfo->name = getStringField(env, obj, gInputApplicationHandleClassInfo.name, "<null>");
-
-    mInfo->dispatchingTimeout = env->GetLongField(obj,
+    mInfo.dispatchingTimeout = env->GetLongField(obj,
             gInputApplicationHandleClassInfo.dispatchingTimeoutNanos);
 
     jobject tokenObj = env->GetObjectField(obj,
             gInputApplicationHandleClassInfo.token);
     if (tokenObj) {
-        mInfo->token = ibinderForJavaObject(env, tokenObj);
+        mInfo.token = ibinderForJavaObject(env, tokenObj);
         env->DeleteLocalRef(tokenObj);
     } else {
-        mInfo->token.clear();
+        mInfo.token.clear();
     }
 
     env->DeleteLocalRef(obj);
-    return true;
+    return mInfo.token.get() != nullptr;
 }
 
 
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index c8f81e2..a296d64 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -144,6 +144,7 @@
 static jclass gAudioMixingRuleClass;
 static struct {
     jfieldID    mCriteria;
+    jfieldID    mAllowPrivilegedPlaybackCapture;
     // other fields unused by JNI
 } gAudioMixingRuleFields;
 
@@ -1868,6 +1869,8 @@
 
     jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
     jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria);
+    nAudioMix->mAllowPrivilegedPlaybackCapture =
+            env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture);
     env->DeleteLocalRef(jRule);
     jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria,
                                                                  gArrayListMethods.toArray);
@@ -2226,6 +2229,11 @@
     return AudioSystem::isHapticPlaybackSupported();
 }
 
+static jint
+android_media_AudioSystem_setAllowedCapturePolicy(JNIEnv *env, jobject thiz, jint uid, jint flags) {
+    return AudioSystem::setAllowedCapturePolicy(uid, flags);
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gMethods[] = {
@@ -2301,6 +2309,7 @@
     {"isHapticPlaybackSupported", "()Z", (void *)android_media_AudioSystem_isHapticPlaybackSupported},
     {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
                     (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
+    {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy},
 };
 
 static const JNINativeMethod gEventHandlerMethods[] = {
@@ -2456,6 +2465,8 @@
     gAudioMixingRuleClass = MakeGlobalRefOrDie(env, audioMixingRuleClass);
     gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria",
                                                        "Ljava/util/ArrayList;");
+    gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture =
+            GetFieldIDOrDie(env, audioMixingRuleClass, "mAllowPrivilegedPlaybackCapture", "Z");
 
     jclass audioMixMatchCriterionClass =
                 FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion");
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index d7a981e..82acf6f 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -470,6 +470,7 @@
     std::vector<uint8_t> buf(MAXPACKETSIZE, 0);
 
     int res = resNetworkResult(fd, &rcode, buf.data(), MAXPACKETSIZE);
+    jniSetFileDescriptorOfFD(env, javaFd, -1);
     if (res < 0) {
         throwErrnoException(env, "resNetworkResult", -res);
         return nullptr;
@@ -490,6 +491,7 @@
 static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     resNetworkCancel(fd);
+    jniSetFileDescriptorOfFD(env, javaFd, -1);
 }
 
 static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) {
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 8cb1078..236ee61 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -24,10 +24,30 @@
 #include "selinux/android.h"
 #include <errno.h>
 #include <memory>
+#include <atomic>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedUtfChars.h>
 
 namespace android {
+namespace {
+std::atomic<selabel_handle*> sehandle{nullptr};
+
+selabel_handle* GetSELabelHandle() {
+    selabel_handle* h = sehandle.load();
+    if (h != nullptr) {
+        return h;
+    }
+
+    h = selinux_android_file_context_handle();
+    selabel_handle* expected = nullptr;
+    if (!sehandle.compare_exchange_strong(expected, h)) {
+        selabel_close(h);
+        return sehandle.load();
+    }
+    return h;
+}
+
+}
 
 struct SecurityContext_Delete {
     void operator()(security_context_t p) const {
@@ -60,6 +80,44 @@
     return (security_getenforce() == 1) ? true : false;
 }
 
+static jstring fileSelabelLookup(JNIEnv* env, jobject, jstring pathStr) {
+    if (isSELinuxDisabled) {
+        ALOGE("fileSelabelLookup => SELinux is disabled");
+        return NULL;
+    }
+
+    if (pathStr == NULL) {
+      ALOGE("fileSelabelLookup => got null path.");
+      jniThrowNullPointerException(
+          env, "Trying to get security context of a null path.");
+      return NULL;
+    }
+
+    ScopedUtfChars path(env, pathStr);
+    const char* path_c_str = path.c_str();
+    if (path_c_str == NULL) {
+        ALOGE("fileSelabelLookup => Got null path");
+        jniThrowNullPointerException(
+            env, "Trying to get security context of a null path.");
+        return NULL;
+    }
+
+    auto* selabel_handle = GetSELabelHandle();
+    if (selabel_handle == NULL) {
+        ALOGE("fileSelabelLookup => Failed to get SEHandle");
+        return NULL;
+    }
+
+    security_context_t tmp = NULL;
+    if (selabel_lookup(selabel_handle, &tmp, path_c_str, S_IFREG) != 0) {
+      ALOGE("fileSelabelLookup => selabel_lookup for %s failed: %d", path_c_str, errno);
+      return NULL;
+    }
+
+    Unique_SecurityContext context(tmp);
+    return env->NewStringUTF(context.get());
+}
+
 static jstring getFdConInner(JNIEnv *env, jobject fileDescriptor, bool isSocket) {
     if (isSELinuxDisabled) {
         return NULL;
@@ -354,6 +412,7 @@
     { "native_restorecon"        , "(Ljava/lang/String;I)Z"                       , (void*)native_restorecon},
     { "setFileContext"           , "(Ljava/lang/String;Ljava/lang/String;)Z"      , (void*)setFileCon       },
     { "setFSCreateContext"       , "(Ljava/lang/String;)Z"                        , (void*)setFSCreateCon   },
+    { "fileSelabelLookup"        , "(Ljava/lang/String;)Ljava/lang/String;"       , (void*)fileSelabelLookup},
 };
 
 static int log_callback(int type, const char *fmt, ...) {
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index bf56ef4..d3f9196 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -163,7 +163,7 @@
       }
 
       // Generic idmap parameters
-      const char* argv[8];
+      const char* argv[9];
       int argc = 0;
       struct stat st;
 
@@ -199,6 +199,10 @@
         argv[argc++] = AssetManager::PRODUCT_SERVICES_OVERLAY_DIR;
       }
 
+      if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
+        argv[argc++] = AssetManager::ODM_OVERLAY_DIR;
+      }
+
       // Finally, invoke idmap (if any overlay directory exists)
       if (argc > 5) {
         execv(AssetManager::IDMAP_BIN, (char* const*)argv);
@@ -233,6 +237,10 @@
     input_dirs.push_back(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR);
   }
 
+  if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
+    input_dirs.push_back(AssetManager::ODM_OVERLAY_DIR);
+  }
+
   if (input_dirs.empty()) {
     LOG(WARNING) << "no directories for idmap2 to scan";
     return env->NewObjectArray(0, g_stringClass, nullptr);
diff --git a/core/jni/android_view_CompositionSamplingListener.cpp b/core/jni/android_view_CompositionSamplingListener.cpp
index 7141e6e..1c885e3 100644
--- a/core/jni/android_view_CompositionSamplingListener.cpp
+++ b/core/jni/android_view_CompositionSamplingListener.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "CompositionSamplingListener"
 
 #include "android_util_Binder.h"
+#include "core_jni_helpers.h"
 
 #include <nativehelper/JNIHelp.h>
 
@@ -122,6 +123,7 @@
     LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
 
     jclass clazz = env->FindClass("android/view/CompositionSamplingListener");
+    gListenerClassInfo.mClass = MakeGlobalRefOrDie(env, clazz);
     gListenerClassInfo.mDispatchOnSampleCollected = env->GetStaticMethodID(
             clazz, "dispatchOnSampleCollected", "(Landroid/view/CompositionSamplingListener;F)V");
     return 0;
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index ecc2dd0..e7cbf93 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -736,11 +736,11 @@
 }
 
 static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
-        jlong proxyPtr, jlong layerPtr, jobject jbitmap) {
+        jlong proxyPtr, jlong layerPtr, jlong bitmapPtr) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
     SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
     return proxy->copyLayerInto(layer, bitmap);
 }
 
@@ -911,9 +911,9 @@
 
 static jint android_view_ThreadedRenderer_copySurfaceInto(JNIEnv* env,
         jobject clazz, jobject jsurface, jint left, jint top,
-        jint right, jint bottom, jobject jbitmap) {
+        jint right, jint bottom, jlong bitmapPtr) {
     SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
     sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
     return RenderProxy::copySurfaceInto(surface, left, top, right, bottom, &bitmap);
 }
@@ -1106,7 +1106,7 @@
     { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
     { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
     { "nBuildLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_buildLayer },
-    { "nCopyLayerInto", "(JJLandroid/graphics/Bitmap;)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
+    { "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
     { "nPushLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_pushLayerUpdate },
     { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_cancelLayerUpdate },
     { "nDetachSurfaceTexture", "(JJ)V", (void*) android_view_ThreadedRenderer_detachSurfaceTexture },
@@ -1135,7 +1135,7 @@
     { "nRemoveFrameMetricsObserver",
             "(JJ)V",
             (void*)android_view_ThreadedRenderer_removeFrameMetricsObserver },
-    { "nCopySurfaceInto", "(Landroid/view/Surface;IIIILandroid/graphics/Bitmap;)I",
+    { "nCopySurfaceInto", "(Landroid/view/Surface;IIIIJ)I",
                 (void*)android_view_ThreadedRenderer_copySurfaceInto },
     { "nCreateHardwareBitmap", "(JII)Landroid/graphics/Bitmap;",
             (void*)android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode },
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index cde1884..8dd7e8e 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -46,6 +46,7 @@
 #include <fcntl.h>
 #include <grp.h>
 #include <inttypes.h>
+#include <link.h>
 #include <malloc.h>
 #include <mntent.h>
 #include <paths.h>
@@ -54,6 +55,7 @@
 #include <sys/capability.h>
 #include <sys/cdefs.h>
 #include <sys/eventfd.h>
+#include <sys/mman.h>
 #include <sys/personality.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
@@ -69,6 +71,7 @@
 #include <android-base/properties.h>
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
+#include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <cutils/fs.h>
 #include <cutils/multiuser.h>
@@ -1631,6 +1634,8 @@
   // security_getenforce is not allowed on app process. Initialize and cache
   // the value before zygote forks.
   g_is_security_enforced = security_getenforce();
+
+  selinux_android_seapp_context_init();
 }
 
 static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) {
@@ -1975,6 +1980,26 @@
   }
 }
 
+static int disable_execute_only(struct dl_phdr_info *info, size_t size, void *data) {
+  // Search for any execute-only segments and mark them read+execute.
+  for (int i = 0; i < info->dlpi_phnum; i++) {
+    if ((info->dlpi_phdr[i].p_type == PT_LOAD) && (info->dlpi_phdr[i].p_flags == PF_X)) {
+      mprotect(reinterpret_cast<void*>(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr),
+              info->dlpi_phdr[i].p_memsz, PROT_READ | PROT_EXEC);
+    }
+  }
+  // Return non-zero to exit dl_iterate_phdr.
+  return 0;
+}
+
+/**
+ * @param env  Managed runtime environment
+ * @return  True if disable was successful.
+ */
+static jboolean com_android_internal_os_Zygote_nativeDisableExecuteOnly(JNIEnv* env, jclass) {
+  return dl_iterate_phdr(disable_execute_only, nullptr) == 0;
+}
+
 static const JNINativeMethod gMethods[] = {
     { "nativeSecurityInit", "()V",
       (void *) com_android_internal_os_Zygote_nativeSecurityInit },
@@ -2007,7 +2032,9 @@
     { "nativeGetUsapPoolCount", "()I",
       (void *) com_android_internal_os_Zygote_nativeGetUsapPoolCount },
     { "nativeEmptyUsapPool", "()V",
-      (void *) com_android_internal_os_Zygote_nativeEmptyUsapPool }
+      (void *) com_android_internal_os_Zygote_nativeEmptyUsapPool },
+    { "nativeDisableExecuteOnly", "()Z",
+      (void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly }
 };
 
 int register_com_android_internal_os_Zygote(JNIEnv* env) {
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index d8d4656..0996352 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -102,6 +102,8 @@
   static const char* kProductOverlayDir = "/product/overlay";
   static const char* kSystemProductServicesOverlayDir = "/system/product_services/overlay/";
   static const char* kProductServicesOverlayDir = "/product_services/overlay";
+  static const char* kSystemOdmOverlayDir = "/system/odm/overlay";
+  static const char* kOdmOverlayDir = "/odm/overlay";
   static const char* kApkSuffix = ".apk";
 
   if ((android::base::StartsWith(path, kOverlayDir)
@@ -110,7 +112,9 @@
        || android::base::StartsWith(path, kSystemProductOverlayDir)
        || android::base::StartsWith(path, kProductOverlayDir)
        || android::base::StartsWith(path, kSystemProductServicesOverlayDir)
-       || android::base::StartsWith(path, kProductServicesOverlayDir))
+       || android::base::StartsWith(path, kProductServicesOverlayDir)
+       || android::base::StartsWith(path, kSystemOdmOverlayDir)
+       || android::base::StartsWith(path, kOdmOverlayDir))
       && android::base::EndsWith(path, kApkSuffix)
       && path.find("/../") == std::string::npos) {
     return true;
diff --git a/core/proto/android/app/alarmmanager.proto b/core/proto/android/app/alarmmanager.proto
index 58df922..fe27636 100644
--- a/core/proto/android/app/alarmmanager.proto
+++ b/core/proto/android/app/alarmmanager.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 
 import "frameworks/base/core/proto/android/app/pendingintent.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
diff --git a/core/proto/android/app/enums.proto b/core/proto/android/app/enums.proto
index 1754e42..9abe923 100644
--- a/core/proto/android/app/enums.proto
+++ b/core/proto/android/app/enums.proto
@@ -38,6 +38,7 @@
 }
 
 // ActivityManager.java PROCESS_STATEs
+// Next tag: 1021
 enum ProcessStateEnum {
     // Unlike the ActivityManager PROCESS_STATE values, the ordering and numerical values
     // here are completely fixed and arbitrary. Order is irrelevant.
@@ -56,9 +57,11 @@
     // Process is hosting the current top activities. Note that this covers
     // all activities that are visible to the user.
     PROCESS_STATE_TOP = 1002;
+    // Process is bound to a TOP app.
+    PROCESS_STATE_BOUND_TOP = 1020;
     // Process is hosting a foreground service.
     PROCESS_STATE_FOREGROUND_SERVICE = 1003;
-    // Process is hosting a foreground service due to a system binding.
+    // Process is hosting a service bound by the system or another foreground app.
     PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 1004;
     // Process is important to the user, and something they are aware of.
     PROCESS_STATE_IMPORTANT_FOREGROUND = 1005;
diff --git a/core/proto/android/app/notification.proto b/core/proto/android/app/notification.proto
index a6f13d7..bf0b352 100644
--- a/core/proto/android/app/notification.proto
+++ b/core/proto/android/app/notification.proto
@@ -19,7 +19,7 @@
 
 package android.app;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.app.Notification object.
diff --git a/core/proto/android/app/notification_channel.proto b/core/proto/android/app/notification_channel.proto
index 435d32f..c835b90 100644
--- a/core/proto/android/app/notification_channel.proto
+++ b/core/proto/android/app/notification_channel.proto
@@ -20,7 +20,7 @@
 package android.app;
 
 import "frameworks/base/core/proto/android/media/audioattributes.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.app.NotificationChannel object.
diff --git a/core/proto/android/app/notification_channel_group.proto b/core/proto/android/app/notification_channel_group.proto
index 6d6ceb2..c064bb12 100644
--- a/core/proto/android/app/notification_channel_group.proto
+++ b/core/proto/android/app/notification_channel_group.proto
@@ -20,7 +20,7 @@
 package android.app;
 
 import "frameworks/base/core/proto/android/app/notification_channel.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.app.NotificationChannelGroup object.
diff --git a/core/proto/android/app/notificationmanager.proto b/core/proto/android/app/notificationmanager.proto
index 27204cc..b88315e 100644
--- a/core/proto/android/app/notificationmanager.proto
+++ b/core/proto/android/app/notificationmanager.proto
@@ -19,7 +19,7 @@
 
 package android.app;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.app.NotificationManager.Policy object.
diff --git a/core/proto/android/app/pendingintent.proto b/core/proto/android/app/pendingintent.proto
index 04ce850..b8e61a3 100644
--- a/core/proto/android/app/pendingintent.proto
+++ b/core/proto/android/app/pendingintent.proto
@@ -20,7 +20,7 @@
 
 package android.app;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.app.PendingIntent object.
diff --git a/core/proto/android/app/profilerinfo.proto b/core/proto/android/app/profilerinfo.proto
index 20fa3ad..d318533 100644
--- a/core/proto/android/app/profilerinfo.proto
+++ b/core/proto/android/app/profilerinfo.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.app;
 
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index b4be3f5..d029527 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2319,4 +2319,16 @@
 
     // Settings > Display > Theme
     DARK_UI_SETTINGS = 1698;
+
+    // Settings > global bubble settings
+    BUBBLE_SETTINGS = 1699;
+
+    // Settings > app > bubble settings
+    APP_BUBBLE_SETTINGS = 1700;
+
+    // OPEN: Settings > System > Aware > Info dialog
+    DIALOG_AWARE_STATUS = 1701;
+
+    // Open: Settings > app > bubble settings > confirmation dialog
+    DIALOG_APP_BUBBLE_SETTINGS = 1702;
 }
diff --git a/core/proto/android/app/window_configuration.proto b/core/proto/android/app/window_configuration.proto
index 6cc1a40..18439da 100644
--- a/core/proto/android/app/window_configuration.proto
+++ b/core/proto/android/app/window_configuration.proto
@@ -20,7 +20,7 @@
 package android.app;
 
 import "frameworks/base/core/proto/android/graphics/rect.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /** Proto representation for WindowConfiguration.java class. */
 message WindowConfigurationProto {
diff --git a/core/proto/android/content/clipdata.proto b/core/proto/android/content/clipdata.proto
index 4f1c308..72bbb2a 100644
--- a/core/proto/android/content/clipdata.proto
+++ b/core/proto/android/content/clipdata.proto
@@ -21,7 +21,7 @@
 
 import "frameworks/base/core/proto/android/content/clipdescription.proto";
 import "frameworks/base/core/proto/android/content/intent.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // An android.content.ClipData object.
 message ClipDataProto {
diff --git a/core/proto/android/content/clipdescription.proto b/core/proto/android/content/clipdescription.proto
index bc0e940..7145563 100644
--- a/core/proto/android/content/clipdescription.proto
+++ b/core/proto/android/content/clipdescription.proto
@@ -20,7 +20,7 @@
 option java_multiple_files = true;
 
 import "frameworks/base/core/proto/android/os/persistablebundle.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // An android.content.ClipDescription object.
 message ClipDescriptionProto {
diff --git a/core/proto/android/content/component_name.proto b/core/proto/android/content/component_name.proto
index 232d685..5cd0b05 100644
--- a/core/proto/android/content/component_name.proto
+++ b/core/proto/android/content/component_name.proto
@@ -19,7 +19,7 @@
 
 package android.content;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.content.ComponentName object.
diff --git a/core/proto/android/content/configuration.proto b/core/proto/android/content/configuration.proto
index 06f9735..57ced09 100644
--- a/core/proto/android/content/configuration.proto
+++ b/core/proto/android/content/configuration.proto
@@ -21,7 +21,7 @@
 
 import "frameworks/base/core/proto/android/app/window_configuration.proto";
 import "frameworks/base/core/proto/android/content/locale.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android Configuration object.
diff --git a/core/proto/android/content/featureinfo.proto b/core/proto/android/content/featureinfo.proto
index 87bf404..1473ba9 100644
--- a/core/proto/android/content/featureinfo.proto
+++ b/core/proto/android/content/featureinfo.proto
@@ -16,7 +16,7 @@
 
 syntax = "proto2";
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
diff --git a/core/proto/android/content/intent.proto b/core/proto/android/content/intent.proto
index 99ed687..2de538d 100644
--- a/core/proto/android/content/intent.proto
+++ b/core/proto/android/content/intent.proto
@@ -21,7 +21,7 @@
 
 import "frameworks/base/core/proto/android/content/component_name.proto";
 import "frameworks/base/core/proto/android/os/patternmatcher.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Next Tag: 13
 message IntentProto {
diff --git a/core/proto/android/content/locale.proto b/core/proto/android/content/locale.proto
index 86743bf..d8af754 100644
--- a/core/proto/android/content/locale.proto
+++ b/core/proto/android/content/locale.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.content;
 
diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto
index ebb2fa6..4a7d043 100644
--- a/core/proto/android/content/package_item_info.proto
+++ b/core/proto/android/content/package_item_info.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.content.pm;
 
diff --git a/core/proto/android/graphics/point.proto b/core/proto/android/graphics/point.proto
index 04d879f..8180a06 100644
--- a/core/proto/android/graphics/point.proto
+++ b/core/proto/android/graphics/point.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.graphics;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
diff --git a/core/proto/android/graphics/rect.proto b/core/proto/android/graphics/rect.proto
index c216b2b..0bb0494 100644
--- a/core/proto/android/graphics/rect.proto
+++ b/core/proto/android/graphics/rect.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.graphics;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
diff --git a/core/proto/android/internal/locallog.proto b/core/proto/android/internal/locallog.proto
index df0b90b..ecf76a1 100644
--- a/core/proto/android/internal/locallog.proto
+++ b/core/proto/android/internal/locallog.proto
@@ -19,7 +19,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message LocalLogProto {
     option (.android.msg_privacy).dest = DEST_EXPLICIT;
diff --git a/core/proto/android/media/audioattributes.proto b/core/proto/android/media/audioattributes.proto
index d679d9c..288b555 100644
--- a/core/proto/android/media/audioattributes.proto
+++ b/core/proto/android/media/audioattributes.proto
@@ -19,7 +19,7 @@
 
 package android.media;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.media.AudioAttributes object.
diff --git a/core/proto/android/net/OWNERS b/core/proto/android/net/OWNERS
index a845dcb..509699b 100644
--- a/core/proto/android/net/OWNERS
+++ b/core/proto/android/net/OWNERS
@@ -1,5 +1,3 @@
-set noparent
-
 ek@google.com
 lorenzo@google.com
 satk@google.com
diff --git a/core/proto/android/net/network.proto b/core/proto/android/net/network.proto
index e13ca9f..ca9ae61 100644
--- a/core/proto/android/net/network.proto
+++ b/core/proto/android/net/network.proto
@@ -19,7 +19,7 @@
 
 package android.net;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.net.Network object.
diff --git a/core/proto/android/net/networkcapabilities.proto b/core/proto/android/net/networkcapabilities.proto
index 0338bf8..be0cad1 100644
--- a/core/proto/android/net/networkcapabilities.proto
+++ b/core/proto/android/net/networkcapabilities.proto
@@ -20,7 +20,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.net.NetworkCapabilities object.
diff --git a/core/proto/android/net/networkrequest.proto b/core/proto/android/net/networkrequest.proto
index d260b13..b35a020 100644
--- a/core/proto/android/net/networkrequest.proto
+++ b/core/proto/android/net/networkrequest.proto
@@ -21,7 +21,7 @@
 option java_multiple_files = true;
 
 import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * An android.net.NetworkRequest object.
diff --git a/core/proto/android/os/backtrace.proto b/core/proto/android/os/backtrace.proto
index 8bbae17..31ff241 100644
--- a/core/proto/android/os/backtrace.proto
+++ b/core/proto/android/os/backtrace.proto
@@ -19,7 +19,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message BackTraceProto {
     option (android.msg_privacy).dest = DEST_EXPLICIT;
diff --git a/core/proto/android/os/batterystats.proto b/core/proto/android/os/batterystats.proto
index 516fa7b..892ebf7 100644
--- a/core/proto/android/os/batterystats.proto
+++ b/core/proto/android/os/batterystats.proto
@@ -22,7 +22,7 @@
 import "frameworks/base/core/proto/android/app/job/enums.proto";
 import "frameworks/base/core/proto/android/os/powermanager.proto";
 import "frameworks/base/core/proto/android/telephony/enums.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message BatteryStatsProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/os/batterytype.proto b/core/proto/android/os/batterytype.proto
index 2388c1e..82e194f 100644
--- a/core/proto/android/os/batterytype.proto
+++ b/core/proto/android/os/batterytype.proto
@@ -20,7 +20,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message BatteryTypeProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/os/bundle.proto b/core/proto/android/os/bundle.proto
index 5556936..dc59329 100644
--- a/core/proto/android/os/bundle.proto
+++ b/core/proto/android/os/bundle.proto
@@ -19,7 +19,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // An android.os.Bundle object.
 message BundleProto {
diff --git a/core/proto/android/os/cpufreq.proto b/core/proto/android/os/cpufreq.proto
index 46f4901..b86da1a 100644
--- a/core/proto/android/os/cpufreq.proto
+++ b/core/proto/android/os/cpufreq.proto
@@ -17,7 +17,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.os;
 
diff --git a/core/proto/android/os/cpuinfo.proto b/core/proto/android/os/cpuinfo.proto
index ce69fc9..7477db4 100644
--- a/core/proto/android/os/cpuinfo.proto
+++ b/core/proto/android/os/cpuinfo.proto
@@ -17,7 +17,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.os;
 
diff --git a/libs/incident/proto/android/os/header.proto b/core/proto/android/os/header.proto
similarity index 100%
rename from libs/incident/proto/android/os/header.proto
rename to core/proto/android/os/header.proto
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index a5350c9..9a9c9d1 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -22,7 +22,9 @@
 import "frameworks/base/core/proto/android/os/cpufreq.proto";
 import "frameworks/base/core/proto/android/os/cpuinfo.proto";
 import "frameworks/base/core/proto/android/os/data.proto";
+import "frameworks/base/core/proto/android/os/header.proto";
 import "frameworks/base/core/proto/android/os/kernelwake.proto";
+import "frameworks/base/core/proto/android/os/metadata.proto";
 import "frameworks/base/core/proto/android/os/pagetypeinfo.proto";
 import "frameworks/base/core/proto/android/os/procrank.proto";
 import "frameworks/base/core/proto/android/os/ps.proto";
@@ -46,13 +48,12 @@
 import "frameworks/base/core/proto/android/service/package.proto";
 import "frameworks/base/core/proto/android/service/print.proto";
 import "frameworks/base/core/proto/android/service/procstats.proto";
+import "frameworks/base/core/proto/android/service/restricted_image.proto";
 import "frameworks/base/core/proto/android/service/usb.proto";
 import "frameworks/base/core/proto/android/util/event_log_tags.proto";
 import "frameworks/base/core/proto/android/util/log.proto";
-import "frameworks/base/libs/incident/proto/android/os/header.proto";
-import "frameworks/base/libs/incident/proto/android/os/metadata.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
-import "frameworks/base/libs/incident/proto/android/section.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/section.proto";
 
 package android.os;
 
@@ -314,6 +315,12 @@
         (section).args = "role --proto"
     ];
 
+    optional android.service.restricted_image.RestrictedImagesDumpProto restricted_images = 3025 [
+        (section).type = SECTION_DUMPSYS,
+        (section).userdebug_and_eng_only = true,
+        (section).args = "incidentcompanion --restricted_image"
+    ];
+
     // Reserved for OEMs.
     extensions 50000 to 100000;
 }
diff --git a/core/proto/android/os/kernelwake.proto b/core/proto/android/os/kernelwake.proto
index 5021a06..885e62d 100644
--- a/core/proto/android/os/kernelwake.proto
+++ b/core/proto/android/os/kernelwake.proto
@@ -17,7 +17,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.os;
 
diff --git a/core/proto/android/os/looper.proto b/core/proto/android/os/looper.proto
index b9b8cf5..d1ef7bc 100644
--- a/core/proto/android/os/looper.proto
+++ b/core/proto/android/os/looper.proto
@@ -20,7 +20,7 @@
 option java_multiple_files = true;
 
 import "frameworks/base/core/proto/android/os/messagequeue.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message LooperProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/os/message.proto b/core/proto/android/os/message.proto
index 8aaec70..9b48b67 100644
--- a/core/proto/android/os/message.proto
+++ b/core/proto/android/os/message.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.os;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 option java_multiple_files = true;
 
 message MessageProto {
diff --git a/core/proto/android/os/messagequeue.proto b/core/proto/android/os/messagequeue.proto
index 61bbee7..9800865 100644
--- a/core/proto/android/os/messagequeue.proto
+++ b/core/proto/android/os/messagequeue.proto
@@ -20,7 +20,7 @@
 option java_multiple_files = true;
 
 import "frameworks/base/core/proto/android/os/message.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message MessageQueueProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/libs/incident/proto/android/os/metadata.proto b/core/proto/android/os/metadata.proto
similarity index 95%
rename from libs/incident/proto/android/os/metadata.proto
rename to core/proto/android/os/metadata.proto
index 3b0e9c9..6242b27 100644
--- a/libs/incident/proto/android/os/metadata.proto
+++ b/core/proto/android/os/metadata.proto
@@ -27,7 +27,7 @@
     // The id of the incident report.
     optional int64 report_id = 1;
 
-    // The sequence number of the report.
+    // No longer filled in as of Qt.
     optional int32 sequence_number = 2;
 
     // privacy level of the incident report.
@@ -38,8 +38,10 @@
     }
     optional Destination dest = 3;
 
+    // No longer filled in as of Qt.
     optional int32 request_size = 4;
 
+    // No longer filled in as of Qt.
     optional bool use_dropbox = 5;
 
     // stats of each section taken in this incident report.
diff --git a/core/proto/android/os/pagetypeinfo.proto b/core/proto/android/os/pagetypeinfo.proto
index 65e7139..c795e2e 100644
--- a/core/proto/android/os/pagetypeinfo.proto
+++ b/core/proto/android/os/pagetypeinfo.proto
@@ -17,7 +17,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.os;
 
diff --git a/core/proto/android/os/patternmatcher.proto b/core/proto/android/os/patternmatcher.proto
index 520f2f5..ab2010d 100644
--- a/core/proto/android/os/patternmatcher.proto
+++ b/core/proto/android/os/patternmatcher.proto
@@ -16,7 +16,7 @@
 
 syntax = "proto2";
 option java_multiple_files = true;
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.os;
 
diff --git a/core/proto/android/os/persistablebundle.proto b/core/proto/android/os/persistablebundle.proto
index 712f87c..785250c7 100644
--- a/core/proto/android/os/persistablebundle.proto
+++ b/core/proto/android/os/persistablebundle.proto
@@ -19,7 +19,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // An android.os.PersistableBundle object.
 message PersistableBundleProto {
diff --git a/core/proto/android/os/powermanager.proto b/core/proto/android/os/powermanager.proto
index 20b0a74..52b092c 100644
--- a/core/proto/android/os/powermanager.proto
+++ b/core/proto/android/os/powermanager.proto
@@ -20,7 +20,7 @@
 option java_multiple_files = true;
 
 import "frameworks/base/core/proto/android/os/worksource.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message PowerManagerProto {
     /* User activity events in PowerManager.java. */
diff --git a/core/proto/android/os/procrank.proto b/core/proto/android/os/procrank.proto
index f7edaf4..62f75bb 100644
--- a/core/proto/android/os/procrank.proto
+++ b/core/proto/android/os/procrank.proto
@@ -19,7 +19,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Memory usage of running processes
 message ProcrankProto {
diff --git a/core/proto/android/os/ps.proto b/core/proto/android/os/ps.proto
index e032b57..993bfb6 100644
--- a/core/proto/android/os/ps.proto
+++ b/core/proto/android/os/ps.proto
@@ -20,7 +20,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message PsProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/os/statsdata.proto b/core/proto/android/os/statsdata.proto
index 25d76b8..b89b606 100644
--- a/core/proto/android/os/statsdata.proto
+++ b/core/proto/android/os/statsdata.proto
@@ -19,7 +19,7 @@
 
 package android.os;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Dump of statsd report data (dumpsys stats --proto).
 message StatsDataDumpProto {
diff --git a/core/proto/android/os/system_properties.proto b/core/proto/android/os/system_properties.proto
index 1f63be9..d06e1a6 100644
--- a/core/proto/android/os/system_properties.proto
+++ b/core/proto/android/os/system_properties.proto
@@ -18,7 +18,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.os;
 
diff --git a/core/proto/android/os/worksource.proto b/core/proto/android/os/worksource.proto
index 0a9c2ed..1763d44 100644
--- a/core/proto/android/os/worksource.proto
+++ b/core/proto/android/os/worksource.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.os;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
diff --git a/libs/incident/proto/android/privacy.proto b/core/proto/android/privacy.proto
similarity index 100%
rename from libs/incident/proto/android/privacy.proto
rename to core/proto/android/privacy.proto
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index 76a3b5d..e43b6a0 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -23,7 +23,7 @@
 import "frameworks/base/core/proto/android/providers/settings/global.proto";
 import "frameworks/base/core/proto/android/providers/settings/secure.proto";
 import "frameworks/base/core/proto/android/providers/settings/system.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message SettingsServiceDumpProto {
     option (android.msg_privacy).dest = DEST_EXPLICIT;
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 62df6e7..b47097d 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -20,7 +20,7 @@
 option java_multiple_files = true;
 
 import "frameworks/base/core/proto/android/providers/settings/common.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Note: it's a conscious decision to add each setting as a separate field. This
 // allows annotating each setting with its own privacy tag.
@@ -455,6 +455,8 @@
         optional SettingProto show_angle_in_use_dialog = 15;
         // Game Driver - List of libraries in sphal accessible by Game Driver
         optional SettingProto game_driver_sphal_libraries = 16;
+        // ANGLE - External package containing ANGLE libraries
+        optional SettingProto angle_debug_package = 17;
     }
     optional Gpu gpu = 59;
 
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 27a18ee..91d5bc8 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -20,7 +20,7 @@
 option java_multiple_files = true;
 
 import "frameworks/base/core/proto/android/providers/settings/common.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Note: it's a conscious decision to add each setting as a separate field. This
 // allows annotating each setting with its own privacy tag.
diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto
index 41a7498..f8143de8 100644
--- a/core/proto/android/providers/settings/system.proto
+++ b/core/proto/android/providers/settings/system.proto
@@ -20,7 +20,7 @@
 option java_multiple_files = true;
 
 import "frameworks/base/core/proto/android/providers/settings/common.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Note: it's a conscious decision to add each setting as a separate field. This
 // allows annotating each setting with its own privacy tag.
diff --git a/libs/incident/proto/android/section.proto b/core/proto/android/section.proto
similarity index 100%
rename from libs/incident/proto/android/section.proto
rename to core/proto/android/section.proto
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 79a5dd7..a7d4734 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -34,7 +34,7 @@
 import "frameworks/base/core/proto/android/server/intentresolver.proto";
 import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
 import "frameworks/base/core/proto/android/util/common.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
@@ -756,6 +756,7 @@
             optional string file = 2 [ (.android.privacy).dest = DEST_EXPLICIT ];
             optional int32 pid = 3;
             optional int32 uid = 4;
+            optional bool is_user_initiated = 5;
         }
         optional Dump dump = 2;
     }
diff --git a/core/proto/android/server/alarmmanagerservice.proto b/core/proto/android/server/alarmmanagerservice.proto
index b74f28d..490f729 100644
--- a/core/proto/android/server/alarmmanagerservice.proto
+++ b/core/proto/android/server/alarmmanagerservice.proto
@@ -21,7 +21,7 @@
 import "frameworks/base/core/proto/android/internal/locallog.proto";
 import "frameworks/base/core/proto/android/os/worksource.proto";
 import "frameworks/base/core/proto/android/server/forceappstandbytracker.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package com.android.server;
 
diff --git a/core/proto/android/server/animationadapter.proto b/core/proto/android/server/animationadapter.proto
index 0bcc488..70627ed 100644
--- a/core/proto/android/server/animationadapter.proto
+++ b/core/proto/android/server/animationadapter.proto
@@ -18,7 +18,7 @@
 
 import "frameworks/base/core/proto/android/graphics/point.proto";
 import "frameworks/base/core/proto/android/view/remote_animation_target.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package com.android.server.wm;
 option java_multiple_files = true;
diff --git a/core/proto/android/server/appwindowthumbnail.proto b/core/proto/android/server/appwindowthumbnail.proto
index a1be721..f22cdc5 100644
--- a/core/proto/android/server/appwindowthumbnail.proto
+++ b/core/proto/android/server/appwindowthumbnail.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 
 import "frameworks/base/core/proto/android/server/surfaceanimator.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package com.android.server.wm;
 option java_multiple_files = true;
diff --git a/core/proto/android/server/face.proto b/core/proto/android/server/face.proto
index 6ecf328..8b77586 100644
--- a/core/proto/android/server/face.proto
+++ b/core/proto/android/server/face.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package com.android.server.biometrics.face;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 option java_outer_classname = "FaceServiceProto";
diff --git a/core/proto/android/server/fingerprint.proto b/core/proto/android/server/fingerprint.proto
index c5eb85c..a264f18 100644
--- a/core/proto/android/server/fingerprint.proto
+++ b/core/proto/android/server/fingerprint.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package com.android.server.biometrics.fingerprint;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 option java_outer_classname = "FingerprintServiceProto";
diff --git a/core/proto/android/server/forceappstandbytracker.proto b/core/proto/android/server/forceappstandbytracker.proto
index 54f30c3..89424bc 100644
--- a/core/proto/android/server/forceappstandbytracker.proto
+++ b/core/proto/android/server/forceappstandbytracker.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 
 import "frameworks/base/core/proto/android/server/statlogger.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package com.android.server;
 
diff --git a/core/proto/android/server/intentresolver.proto b/core/proto/android/server/intentresolver.proto
index e67723e..7ac50e0 100644
--- a/core/proto/android/server/intentresolver.proto
+++ b/core/proto/android/server/intentresolver.proto
@@ -19,7 +19,7 @@
 
 package com.android.server;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message IntentResolverProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 6c9d13a..1e0b0d8 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -30,7 +30,7 @@
 import "frameworks/base/core/proto/android/os/persistablebundle.proto";
 import "frameworks/base/core/proto/android/server/forceappstandbytracker.proto";
 import "frameworks/base/core/proto/android/server/job/enums.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Next tag: 21
 message JobSchedulerServiceDumpProto {
diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto
index 9bf1825..091e1c2 100644
--- a/core/proto/android/server/powermanagerservice.proto
+++ b/core/proto/android/server/powermanagerservice.proto
@@ -28,7 +28,7 @@
 import "frameworks/base/core/proto/android/providers/settings.proto";
 import "frameworks/base/core/proto/android/server/wirelesschargerdetector.proto";
 import "frameworks/base/core/proto/android/view/enums.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message PowerManagerServiceDumpProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/rolemanagerservice.proto b/core/proto/android/server/rolemanagerservice.proto
index 3453a66..146522c 100644
--- a/core/proto/android/server/rolemanagerservice.proto
+++ b/core/proto/android/server/rolemanagerservice.proto
@@ -20,7 +20,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message RoleManagerServiceDumpProto {
   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/server/statlogger.proto b/core/proto/android/server/statlogger.proto
index 65b1af7..8593da8 100644
--- a/core/proto/android/server/statlogger.proto
+++ b/core/proto/android/server/statlogger.proto
@@ -20,7 +20,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Dump from StatLogger.
 message StatLoggerProto {
diff --git a/core/proto/android/server/surfaceanimator.proto b/core/proto/android/server/surfaceanimator.proto
index e3e8baa..15f4714 100644
--- a/core/proto/android/server/surfaceanimator.proto
+++ b/core/proto/android/server/surfaceanimator.proto
@@ -18,7 +18,7 @@
 
 import "frameworks/base/core/proto/android/server/animationadapter.proto";
 import "frameworks/base/core/proto/android/view/surfacecontrol.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package com.android.server.wm;
 option java_multiple_files = true;
diff --git a/core/proto/android/server/usagestatsservice.proto b/core/proto/android/server/usagestatsservice.proto
index 050ec7a..f26eefa 100644
--- a/core/proto/android/server/usagestatsservice.proto
+++ b/core/proto/android/server/usagestatsservice.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package com.android.server.usage;
 import "frameworks/base/core/proto/android/content/configuration.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 3767ed5..dbd2191 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -27,7 +27,7 @@
 import "frameworks/base/core/proto/android/view/enums.proto";
 import "frameworks/base/core/proto/android/view/surface.proto";
 import "frameworks/base/core/proto/android/view/windowlayoutparams.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package com.android.server.wm;
 
diff --git a/core/proto/android/server/wirelesschargerdetector.proto b/core/proto/android/server/wirelesschargerdetector.proto
index 2118deb..1c98fb9 100644
--- a/core/proto/android/server/wirelesschargerdetector.proto
+++ b/core/proto/android/server/wirelesschargerdetector.proto
@@ -19,7 +19,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message WirelessChargerDetectorProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/service/adb.proto b/core/proto/android/service/adb.proto
index 0060813..493f9b8 100644
--- a/core/proto/android/service/adb.proto
+++ b/core/proto/android/service/adb.proto
@@ -20,7 +20,7 @@
 option java_multiple_files = true;
 option java_outer_classname = "AdbServiceProto";
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message AdbServiceDumpProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/service/battery.proto b/core/proto/android/service/battery.proto
index 34cb229..586411f 100644
--- a/core/proto/android/service/battery.proto
+++ b/core/proto/android/service/battery.proto
@@ -21,7 +21,7 @@
 option java_outer_classname = "BatteryServiceProto";
 
 import "frameworks/base/core/proto/android/os/enums.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message BatteryServiceDumpProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/service/batterystats.proto b/core/proto/android/service/batterystats.proto
index 25b47d3..3ae45ca 100644
--- a/core/proto/android/service/batterystats.proto
+++ b/core/proto/android/service/batterystats.proto
@@ -21,7 +21,7 @@
 option java_outer_classname = "BatteryStatsServiceProto";
 
 import "frameworks/base/core/proto/android/os/batterystats.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Dump of batterystats aggregate data (dumpsys batterystats --proto).
 message BatteryStatsServiceDumpProto {
diff --git a/core/proto/android/service/diskstats.proto b/core/proto/android/service/diskstats.proto
index 1012eb0..f79de39 100644
--- a/core/proto/android/service/diskstats.proto
+++ b/core/proto/android/service/diskstats.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.service.diskstats;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 option java_outer_classname = "DiskStatsServiceProto";
diff --git a/core/proto/android/service/graphicsstats.proto b/core/proto/android/service/graphicsstats.proto
index bb32495..11f0467 100644
--- a/core/proto/android/service/graphicsstats.proto
+++ b/core/proto/android/service/graphicsstats.proto
@@ -20,7 +20,7 @@
 option java_multiple_files = true;
 option java_outer_classname = "GraphicsStatsServiceProto";
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // This file is based on frameworks/base/libs/hwui/protos/graphicsstats.proto.
 // Please try to keep the two files in sync.
diff --git a/core/proto/android/service/netstats.proto b/core/proto/android/service/netstats.proto
index 02d4483..8ebb4a9 100644
--- a/core/proto/android/service/netstats.proto
+++ b/core/proto/android/service/netstats.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.service;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 option java_outer_classname = "NetworkStatsServiceProto";
diff --git a/core/proto/android/service/notification.proto b/core/proto/android/service/notification.proto
index 4ef26dd..1ec05fb 100644
--- a/core/proto/android/service/notification.proto
+++ b/core/proto/android/service/notification.proto
@@ -25,7 +25,7 @@
 import "frameworks/base/core/proto/android/app/notificationmanager.proto";
 import "frameworks/base/core/proto/android/content/component_name.proto";
 import "frameworks/base/core/proto/android/media/audioattributes.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message NotificationServiceDumpProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/service/package.proto b/core/proto/android/service/package.proto
index 7f96d70..6ffa0c9 100644
--- a/core/proto/android/service/package.proto
+++ b/core/proto/android/service/package.proto
@@ -18,7 +18,7 @@
 package android.service.pm;
 
 import "frameworks/base/core/proto/android/content/featureinfo.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 option java_outer_classname = "PackageServiceProto";
diff --git a/core/proto/android/service/print.proto b/core/proto/android/service/print.proto
index a449156..abf1b29 100644
--- a/core/proto/android/service/print.proto
+++ b/core/proto/android/service/print.proto
@@ -21,7 +21,7 @@
 option java_outer_classname = "PrintServiceProto";
 
 import "frameworks/base/core/proto/android/content/component_name.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message PrintServiceDumpProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto
index da801ff..f49a044 100644
--- a/core/proto/android/service/procstats.proto
+++ b/core/proto/android/service/procstats.proto
@@ -22,7 +22,7 @@
 
 import "frameworks/base/core/proto/android/util/common.proto";
 import "frameworks/base/core/proto/android/service/procstats_enum.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * Data from ProcStatsService Dumpsys
diff --git a/core/proto/android/service/restricted_image.proto b/core/proto/android/service/restricted_image.proto
new file mode 100644
index 0000000..4a33d47
--- /dev/null
+++ b/core/proto/android/service/restricted_image.proto
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.service.restricted_image;
+
+option java_multiple_files = true;
+option java_outer_classname = "RestrictedImage";
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+// Restricted Image proto is for collecting images from the user with their
+// permission for the purpose of debugging photos.
+message RestrictedImagesDumpProto {
+    option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+    repeated RestrictedImageSetProto sets = 1;
+}
+
+message RestrictedImageSetProto {
+    option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+    // Name of the service producing the data.
+    optional string category = 1;
+
+    // The images
+    repeated RestrictedImageProto images = 2;
+
+    // Additional metadata
+    optional bytes metadata = 3;
+}
+
+message RestrictedImageProto {
+    option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+    // Type of image data
+    optional string mime_type = 1;
+
+    // The image data
+    optional bytes image_data = 2;
+
+    // Metadata about the image.  Typically this has another proto schema,
+    // but it is undefined exactly what that is in AOSP code.
+    optional bytes metadata = 3;
+}
diff --git a/core/proto/android/service/runtime.proto b/core/proto/android/service/runtime.proto
index ecbccef..440264d 100644
--- a/core/proto/android/service/runtime.proto
+++ b/core/proto/android/service/runtime.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.service.runtime;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 option java_outer_classname = "RuntimeServiceProto";
diff --git a/core/proto/android/service/usb.proto b/core/proto/android/service/usb.proto
index 367c540..2e1de79 100644
--- a/core/proto/android/service/usb.proto
+++ b/core/proto/android/service/usb.proto
@@ -22,7 +22,7 @@
 
 import "frameworks/base/core/proto/android/content/component_name.proto";
 import "frameworks/base/core/proto/android/service/enums.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 message UsbServiceDumpProto {
     option (android.msg_privacy).dest = DEST_AUTOMATIC;
diff --git a/core/proto/android/stats/connectivity/resolv_stats.proto b/core/proto/android/stats/connectivity/resolv_stats.proto
new file mode 100644
index 0000000..43eb673
--- /dev/null
+++ b/core/proto/android/stats/connectivity/resolv_stats.proto
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+syntax = "proto2";
+package android.stats.connectivity;
+import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
+
+enum EventType {
+    EVENT_UNKNOWN       = 0;
+    EVENT_GETADDRINFO   = 1;
+    EVENT_GETHOSTBYNAME = 2;
+    EVENT_GETHOSTBYADDR = 3;
+    EVENT_RES_NSEND     = 4;
+}
+
+enum PrivateDnsModes {
+    OFF           = 0;
+    OPPORTUNISTIC = 1;
+    STRICT        = 2;
+}
+// The return value of the DNS resolver for each DNS lookups.
+// bionic/libc/include/netdb.h
+// system/netd/resolv/include/netd_resolv/resolv.h
+enum ReturnCode {
+    RC_EAI_NO_ERROR   = 0;
+    RC_EAI_ADDRFAMILY = 1;
+    RC_EAI_AGAIN      = 2;
+    RC_EAI_BADFLAGS   = 3;
+    RC_EAI_FAIL       = 4;
+    RC_EAI_FAMILY     = 5;
+    RC_EAI_MEMORY     = 6;
+    RC_EAI_NODATA     = 7;
+    RC_EAI_NONAME     = 8;
+    RC_EAI_SERVICE    = 9;
+    RC_EAI_SOCKTYPE   = 10;
+    RC_EAI_SYSTEM     = 11;
+    RC_EAI_BADHINTS   = 12;
+    RC_EAI_PROTOCOL   = 13;
+    RC_EAI_OVERFLOW   = 14;
+    RC_RESOLV_TIMEOUT = 255;
+    RC_EAI_MAX        = 256;
+}
+
+
+enum NsRcode {
+    ns_r_noerror   = 0;    // No error occurred.
+    ns_r_formerr   = 1;    // Format error.
+    ns_r_servfail  = 2;   // Server failure.
+    ns_r_nxdomain  = 3;   // Name error.
+    ns_r_notimpl   = 4;    // Unimplemented.
+    ns_r_refused   = 5;    // Operation refused.
+    // these are for BIND_UPDATE
+    ns_r_yxdomain  = 6;   // Name exists
+    ns_r_yxrrset   = 7;    // RRset exists
+    ns_r_nxrrset   = 8;    // RRset does not exist
+    ns_r_notauth   = 9;    // Not authoritative for zone
+    ns_r_notzone   = 10;   // Zone of record different from zone section
+    ns_r_max       = 11;
+    // The following are EDNS extended rcodes
+    ns_r_badvers   = 16;
+    // The following are TSIG errors
+    //ns_r_badsig  = 16,
+    ns_r_badkey    = 17;
+    ns_r_badtime   = 18;
+}
+
+// Currently defined type values for resources and queries.
+enum NsType {
+    ns_t_invalid = 0;    // Cookie.
+    ns_t_a = 1;          // Host address.
+    ns_t_ns = 2;         // Authoritative server.
+    ns_t_md = 3;         // Mail destination.
+    ns_t_mf = 4;         // Mail forwarder.
+    ns_t_cname = 5;      // Canonical name.
+    ns_t_soa = 6;        // Start of authority zone.
+    ns_t_mb = 7;         // Mailbox domain name.
+    ns_t_mg = 8;         // Mail group member.
+    ns_t_mr = 9;         // Mail rename name.
+    ns_t_null = 10;      // Null resource record.
+    ns_t_wks = 11;       // Well known service.
+    ns_t_ptr = 12;       // Domain name pointer.
+    ns_t_hinfo = 13;     // Host information.
+    ns_t_minfo = 14;     // Mailbox information.
+    ns_t_mx = 15;        // Mail routing information.
+    ns_t_txt = 16;       // Text strings.
+    ns_t_rp = 17;        // Responsible person.
+    ns_t_afsdb = 18;     // AFS cell database.
+    ns_t_x25 = 19;       // X_25 calling address.
+    ns_t_isdn = 20;      // ISDN calling address.
+    ns_t_rt = 21;        // Router.
+    ns_t_nsap = 22;      // NSAP address.
+    ns_t_nsap_ptr = 23;  // Reverse NSAP lookup (deprecated).
+    ns_t_sig = 24;       // Security signature.
+    ns_t_key = 25;       // Security key.
+    ns_t_px = 26;        // X.400 mail mapping.
+    ns_t_gpos = 27;      // Geographical position (withdrawn).
+    ns_t_aaaa = 28;      // IPv6 Address.
+    ns_t_loc = 29;       // Location Information.
+    ns_t_nxt = 30;       // Next domain (security).
+    ns_t_eid = 31;       // Endpoint identifier.
+    ns_t_nimloc = 32;    // Nimrod Locator.
+    ns_t_srv = 33;       // Server Selection.
+    ns_t_atma = 34;      // ATM Address
+    ns_t_naptr = 35;     // Naming Authority PoinTeR
+    ns_t_kx = 36;        // Key Exchange
+    ns_t_cert = 37;      // Certification record
+    ns_t_a6 = 38;        // IPv6 address (experimental)
+    ns_t_dname = 39;     // Non-terminal DNAME
+    ns_t_sink = 40;      // Kitchen sink (experimentatl)
+    ns_t_opt = 41;       // EDNS0 option (meta-RR)
+    ns_t_apl = 42;       // Address prefix list (RFC 3123)
+    ns_t_ds = 43;        // Delegation Signer
+    ns_t_sshfp = 44;     // SSH Fingerprint
+    ns_t_ipseckey = 45;  // IPSEC Key
+    ns_t_rrsig = 46;     // RRset Signature
+    ns_t_nsec = 47;      // Negative security
+    ns_t_dnskey = 48;    // DNS Key
+    ns_t_dhcid = 49;     // Dynamic host configuratin identifier
+    ns_t_nsec3 = 50;     // Negative security type 3
+    ns_t_nsec3param = 51;// Negative security type 3 parameters
+    ns_t_hip = 55;       // Host Identity Protocol
+    ns_t_spf = 99;       // Sender Policy Framework
+    ns_t_tkey = 249;     // Transaction key
+    ns_t_tsig = 250;     // Transaction signature.
+    ns_t_ixfr = 251;     // Incremental zone transfer.
+    ns_t_axfr = 252;     // Transfer zone of authority.
+    ns_t_mailb = 253;    // Transfer mailbox records.
+    ns_t_maila = 254;    // Transfer mail agent records.
+    ns_t_any = 255;      // Wildcard match.
+    ns_t_zxfr = 256;     // BIND-specific, nonstandard.
+    ns_t_dlv = 32769;    // DNSSEC look-aside validatation.
+    ns_t_max = 65536;
+}
+
+enum IpVersion {
+   IPV4  = 0;
+   IPV6  = 1;
+   MIXED = 2;
+}
+
+enum TransportType {
+    UDP = 0;
+    TCP = 1;
+    DOT = 2;
+    DOT_UDP = 3;
+    DOT_TCP = 4;
+}
+
+message DnsQueryEvent {
+    optional NsRcode rrcode           = 1;
+    optional NsType rrtype            = 2;
+    optional bool cache_hit           = 3;
+    optional IpVersion ipversion      = 4;
+    optional TransportType transport  = 5;
+    optional int32 packet_retransmits = 6;  // Used only by the UDP transport
+    optional int32 reconnects         = 7;  // Used only by TCP and DOT
+    optional int32 latency_micros     = 8;
+    optional int32 active_experiments = 9;
+    optional android.net.NetworkCapabilitiesProto.Transport network_type = 10;
+}
+
+message DnsQueryEventRe {
+    repeated DnsQueryEvent dns_query_event = 1;
+}
+
+
+message DnsCallEvent {
+
+}
+
diff --git a/core/proto/android/util/common.proto b/core/proto/android/util/common.proto
index f8f7885..aad24d1 100644
--- a/core/proto/android/util/common.proto
+++ b/core/proto/android/util/common.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.util;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
diff --git a/core/proto/android/util/event_log_tags.proto b/core/proto/android/util/event_log_tags.proto
index 457219f..40bab9e 100644
--- a/core/proto/android/util/event_log_tags.proto
+++ b/core/proto/android/util/event_log_tags.proto
@@ -19,7 +19,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 // Proto representation of event.logtags.
 // Usually sit in /system/etc/event-log-tags.
diff --git a/core/proto/android/util/log.proto b/core/proto/android/util/log.proto
index 416c055..09870ae 100644
--- a/core/proto/android/util/log.proto
+++ b/core/proto/android/util/log.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.util;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
diff --git a/core/proto/android/view/displaycutout.proto b/core/proto/android/view/displaycutout.proto
index 0a33101..ff98e99 100644
--- a/core/proto/android/view/displaycutout.proto
+++ b/core/proto/android/view/displaycutout.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 
 import "frameworks/base/core/proto/android/graphics/rect.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.view;
 option java_multiple_files = true;
diff --git a/core/proto/android/view/displayinfo.proto b/core/proto/android/view/displayinfo.proto
index 29757fc..49c0a29 100644
--- a/core/proto/android/view/displayinfo.proto
+++ b/core/proto/android/view/displayinfo.proto
@@ -17,7 +17,7 @@
 syntax = "proto2";
 package android.view;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 option java_multiple_files = true;
 
diff --git a/core/proto/android/view/remote_animation_target.proto b/core/proto/android/view/remote_animation_target.proto
index 808c514..24d2785 100644
--- a/core/proto/android/view/remote_animation_target.proto
+++ b/core/proto/android/view/remote_animation_target.proto
@@ -23,7 +23,7 @@
 import "frameworks/base/core/proto/android/graphics/point.proto";
 import "frameworks/base/core/proto/android/graphics/rect.proto";
 import "frameworks/base/core/proto/android/view/surfacecontrol.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /** Proto representation for android.view.RemoteAnimationTarget.java class. */
 message RemoteAnimationTargetProto {
diff --git a/core/proto/android/view/surfacecontrol.proto b/core/proto/android/view/surfacecontrol.proto
index 8a252be..cbb243b 100644
--- a/core/proto/android/view/surfacecontrol.proto
+++ b/core/proto/android/view/surfacecontrol.proto
@@ -19,7 +19,7 @@
 
 option java_multiple_files = true;
 
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 /**
  * Represents a {@link android.view.SurfaceControl} object.
diff --git a/core/proto/android/view/windowlayoutparams.proto b/core/proto/android/view/windowlayoutparams.proto
index 8a011e9..075ebcf 100644
--- a/core/proto/android/view/windowlayoutparams.proto
+++ b/core/proto/android/view/windowlayoutparams.proto
@@ -18,7 +18,7 @@
 
 import "frameworks/base/core/proto/android/graphics/pixelformat.proto";
 import "frameworks/base/core/proto/android/view/display.proto";
-import "frameworks/base/libs/incident/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/privacy.proto";
 
 package android.view;
 option java_multiple_files = true;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cb8ece7..fb92fbf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -116,6 +116,7 @@
     <protected-broadcast android:name="android.app.action.BUGREPORT_SHARE" />
     <protected-broadcast android:name="android.app.action.SHOW_DEVICE_MONITORING_DIALOG" />
     <protected-broadcast android:name="android.intent.action.PENDING_INCIDENT_REPORTS_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.INCIDENT_REPORT_READY" />
 
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_UPDATE_OPTIONS" />
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_DELETED" />
@@ -266,6 +267,7 @@
     <protected-broadcast android:name="android.intent.action.HEADSET_PLUG" />
     <protected-broadcast android:name="android.media.action.HDMI_AUDIO_PLUG" />
     <protected-broadcast android:name="android.media.action.MICROPHONE_MUTE_CHANGED" />
+    <protected-broadcast android:name="android.media.action.SPEAKERPHONE_STATE_CHANGED" />
 
     <protected-broadcast android:name="android.media.AUDIO_BECOMING_NOISY" />
     <protected-broadcast android:name="android.media.RINGER_MODE_CHANGED" />
@@ -627,6 +629,9 @@
 
     <protected-broadcast android:name="android.intent.action.DEVICE_CUSTOMIZATION_READY" />
 
+    <!-- For tether entitlement recheck-->
+    <protected-broadcast
+        android:name="com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM" />
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -784,8 +789,7 @@
     <!-- ====================================================================== -->
     <eat-comment />
 
-    <!-- Used for runtime permissions related to the shared external storage.
-         @deprecated replaced by new strongly-typed permission groups in Q. -->
+    <!-- Used for runtime permissions related to the shared external storage. -->
     <permission-group android:name="android.permission-group.STORAGE"
         android:icon="@drawable/perm_group_storage"
         android:label="@string/permgrouplab_storage"
@@ -813,7 +817,6 @@
      grants your app this permission. If you don't need this permission, be sure your <a
      href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
      targetSdkVersion}</a> is 4 or higher.
-     @deprecated replaced by new strongly-typed permission groups in Q.
      -->
     <permission android:name="android.permission.READ_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -834,7 +837,6 @@
          read/write files in your application-specific directories returned by
          {@link android.content.Context#getExternalFilesDir} and
          {@link android.content.Context#getExternalCacheDir}.
-         @deprecated replaced by new strongly-typed permission groups in Q.
     -->
     <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -842,46 +844,6 @@
         android:description="@string/permdesc_sdcardWrite"
         android:protectionLevel="dangerous" />
 
-    <!-- Runtime permission controlling access to the user's shared aural media
-         collection. -->
-    <permission-group android:name="android.permission-group.MEDIA_AURAL"
-        android:icon="@drawable/perm_group_aural"
-        android:label="@string/permgrouplab_aural"
-        android:description="@string/permgroupdesc_aural"
-        android:request="@string/permgrouprequest_aural"
-        android:priority="910" />
-
-    <!-- Allows an application to read the user's shared audio collection. -->
-    <permission android:name="android.permission.READ_MEDIA_AUDIO"
-        android:permissionGroup="android.permission-group.UNDEFINED"
-        android:label="@string/permlab_audioRead"
-        android:description="@string/permdesc_audioRead"
-        android:protectionLevel="dangerous" />
-
-    <!-- Runtime permission controlling access to the user's shared visual media
-         collection, including images and videos. -->
-    <permission-group android:name="android.permission-group.MEDIA_VISUAL"
-        android:icon="@drawable/perm_group_visual"
-        android:label="@string/permgrouplab_visual"
-        android:description="@string/permgroupdesc_visual"
-        android:request="@string/permgrouprequest_visual"
-        android:requestDetail="@string/permgrouprequestdetail_visual"
-        android:priority="920" />
-
-    <!-- Allows an application to read the user's shared images collection. -->
-    <permission android:name="android.permission.READ_MEDIA_IMAGES"
-        android:permissionGroup="android.permission-group.UNDEFINED"
-        android:label="@string/permlab_imagesRead"
-        android:description="@string/permdesc_imagesRead"
-        android:protectionLevel="dangerous" />
-
-    <!-- Allows an application to read the user's shared video collection. -->
-    <permission android:name="android.permission.READ_MEDIA_VIDEO"
-        android:permissionGroup="android.permission-group.UNDEFINED"
-        android:label="@string/permlab_videoRead"
-        android:description="@string/permdesc_videoRead"
-        android:protectionLevel="dangerous" />
-
     <!-- Allows an application to access any geographic locations persisted in the
          user's shared collection. -->
     <permission android:name="android.permission.ACCESS_MEDIA_LOCATION"
@@ -1009,6 +971,9 @@
          call with the option to redirect the call to a different number or
          abort the call altogether.
          <p>Protection level: dangerous
+
+         @deprecated Applications should use {@link android.telecom.CallRedirectionService} instead
+         of the {@link android.content.Intent#ACTION_NEW_OUTGOING_CALL} broadcast.
     -->
     <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -1598,6 +1563,14 @@
     <permission android:name="android.permission.NETWORK_MANAGED_PROVISIONING"
         android:protectionLevel="signature" />
 
+    <!-- Allows Carrier Provisioning to call methods in Networking services
+         <p>Not for use by any other third-party or privileged applications.
+         @SystemApi
+         @hide This should only be used by CarrierProvisioning.
+    -->
+    <permission android:name="android.permission.NETWORK_CARRIER_PROVISIONING"
+        android:protectionLevel="signature|privileged" />
+
     <!-- #SystemApi @hide Allows applications to access information about LoWPAN interfaces.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCESS_LOWPAN_STATE"
@@ -1712,6 +1685,12 @@
     <permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi Allows an internal user to set signal strength in NetworkRequest. This kind of
+         request will wake up device when signal strength meets the given value.
+         @hide -->
+    <permission android:name="android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP"
+                android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows a system application to access hardware packet offload capabilities.
          @hide -->
     <permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD"
@@ -1853,6 +1832,11 @@
     <permission android:name="android.permission.MANAGE_DYNAMIC_SYSTEM"
         android:protectionLevel="signature" />
 
+    <!-- @SystemApi Allows an application to install a DynamicSystem image and get status updates.
+         @hide -->
+    <permission android:name="android.permission.INSTALL_DYNAMIC_SYSTEM"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows access to Broadcast Radio
          @hide This is not a third-party API (intended for system apps).-->
     <permission android:name="android.permission.ACCESS_BROADCAST_RADIO"
@@ -3555,10 +3539,30 @@
         android:protectionLevel="signature" />
 
     <!-- Allows an application to capture audio output.
+         Use the {@code CAPTURE_MEDIA_OUTPUT} permission if only the {@code USAGE_UNKNOWN}),
+         {@code USAGE_MEDIA}) or {@code USAGE_GAME}) usages are intended to be captured.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi Allows an application to capture the audio played by other apps
+         that have set an allow capture policy of
+         {@link android.media.AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}.
+
+         Without this permission, only audio with an allow capture policy of
+         {@link android.media.AudioAttributes#ALLOW_CAPTURE_BY_ALL} can be used.
+
+         There are strong restriction listed at
+         {@link android.media.AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM}
+         on what an app can do with the captured audio.
+
+         See {@code CAPTURE_AUDIO_OUTPUT} for capturing audio use cases other than media playback.
+
+         <p>Not for use by third-party applications.</p>
+         @hide -->
+    <permission android:name="android.permission.CAPTURE_MEDIA_OUTPUT"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows an application to capture audio for hotword detection.
          <p>Not for use by third-party applications.</p>
          @hide -->
@@ -4426,6 +4430,13 @@
     <permission android:name="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by an {@link android.service.watchdog.ExplicitHealthCheckService} to
+         ensure that only the system can bind to it.
+         @hide This is not a third-party API (intended for OEMs and system apps).
+    -->
+    <permission android:name="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @hide Permission that allows configuring appops.
      <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MANAGE_APPOPS"
@@ -4495,6 +4506,10 @@
     <permission android:name="android.permission.ACCESS_SHARED_LIBRARIES"
                 android:protectionLevel="signature|installer" />
 
+    <!-- Allows input events to be monitored. Very dangerous!  @hide -->
+    <permission android:name="android.permission.MONITOR_INPUT"
+                android:protectionLevel="signature" />
+
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
diff --git a/core/res/res/drawable/ic_bluetooth_share_icon.xml b/core/res/res/drawable/ic_bluetooth_share_icon.xml
new file mode 100644
index 0000000..2446402
--- /dev/null
+++ b/core/res/res/drawable/ic_bluetooth_share_icon.xml
@@ -0,0 +1,27 @@
+<!--
+     Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<!-- This drawable should only be used by the Bluetooth application for its share target icon. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="@android:color/accent_device_default">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L11,14.41V22h1l5.71-5.71L13.41,12L17.71,7.71z M13,5.83 l1.88,1.88L13,9.59V5.83z M14.88,16.29L13,18.17v-3.76L14.88,16.29z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_drag_handle.xml b/core/res/res/drawable/ic_drag_handle.xml
index 67ab84d..9b0e204 100644
--- a/core/res/res/drawable/ic_drag_handle.xml
+++ b/core/res/res/drawable/ic_drag_handle.xml
@@ -13,11 +13,9 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M20.0,9.0L4.0,9.0l0.0,2.0l16.0,0.0L20.0,9.0zM4.0,15.0l16.0,0.0l0.0,-2.0L4.0,13.0l0.0,2.0z"/>
-</vector>
\ No newline at end of file
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle" >
+    <solid android:color="#FFFFFFFF" />
+    <corners android:radius="2dp" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane.xml b/core/res/res/drawable/ic_qs_airplane.xml
similarity index 75%
rename from packages/SystemUI/res/drawable/ic_signal_airplane.xml
rename to core/res/res/drawable/ic_qs_airplane.xml
index f708ed9..166d415 100644
--- a/packages/SystemUI/res/drawable/ic_signal_airplane.xml
+++ b/core/res/res/drawable/ic_qs_airplane.xml
@@ -15,12 +15,11 @@
      limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
+        android:width="18dp"
+        android:height="18dp"
         android:viewportWidth="24"
         android:viewportHeight="24">
-
-<path
-    android:fillColor="#FFFFFF"
-    android:pathData="M21,16v-2l-8-5V3.5C13,2.67,12.33,2,11.5,2S10,2.67,10,3.5V9l-8,5v2l8-2.5V19l-2,1.5V22l3.5-1l3.5,1v-1.5L13,19v-5.5L21,16z" />
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M21,16v-2l-8-5V3.5C13,2.67,12.33,2,11.5,2S10,2.67,10,3.5V9l-8,5v2l8-2.5V19l-2,1.5V22l3.5-1l3.5,1v-1.5L13,19v-5.5L21,16z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml b/core/res/res/drawable/ic_qs_auto_rotate.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml
rename to core/res/res/drawable/ic_qs_auto_rotate.xml
diff --git a/core/res/res/drawable/ic_qs_bluetooth.xml b/core/res/res/drawable/ic_qs_bluetooth.xml
new file mode 100644
index 0000000..91fcff0
--- /dev/null
+++ b/core/res/res/drawable/ic_qs_bluetooth.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 11,14.41L11,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_dnd.xml b/core/res/res/drawable/ic_qs_dnd.xml
similarity index 60%
rename from packages/SystemUI/res/drawable/ic_dnd.xml
rename to core/res/res/drawable/ic_qs_dnd.xml
index 09a6aab..b361169 100644
--- a/packages/SystemUI/res/drawable/ic_dnd.xml
+++ b/core/res/res/drawable/ic_qs_dnd.xml
@@ -14,17 +14,12 @@
      limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="24dp"
+    android:height="17dp"
+    android:width="17dp"
     android:viewportHeight="24.0"
-    android:viewportWidth="24.0"
-    android:width="24dp"
-    android:tint="?android:attr/colorControlNormal">
+    android:viewportWidth="24.0" >
 
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,16.41 16.41,20 12,20z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M7,11h10v2h-10z"/>
-
+        android:fillColor="@android:color/white"
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM7,11h10v2L7,13z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight.xml b/core/res/res/drawable/ic_qs_flashlight.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/ic_signal_flashlight.xml
rename to core/res/res/drawable/ic_qs_flashlight.xml
diff --git a/core/res/res/drawable/ic_settings_bluetooth.xml b/core/res/res/drawable/ic_settings_bluetooth.xml
index 6e32e1a..91fcff0 100644
--- a/core/res/res/drawable/ic_settings_bluetooth.xml
+++ b/core/res/res/drawable/ic_settings_bluetooth.xml
@@ -14,12 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
+        android:width="24dp"
+        android:height="24dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0"
         android:tint="?android:attr/colorControlNormal">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13.5,12l3.8,-3.7c0.4,-0.4 0.4,-1.1 0,-1.5l-4.5,-4.5c-0.4,-0.4 -1.1,-0.4 -1.5,0.1C11.1,2.5 11,2.8 11,3v6.4L6.9,5.4C6.5,5 5.9,5 5.5,5.4s-0.4,1.1 0,1.5l5.1,5.1l-5.1,5.1c-0.4,0.4 -0.4,1.1 0,1.5s1.1,0.4 1.5,0l4.1,-4V21c0,0.6 0.5,1 1,1c0.3,0 0.5,-0.1 0.7,-0.3l0.1,0l4.5,-4.5c0.4,-0.4 0.4,-1.1 0,-1.5L13.5,12zM13,9.7V5.4l2.1,2.2L13,9.7zM13,18.6v-4.3l2.1,2.2L13,18.6z"/>
-</vector>
+        android:fillColor="@android:color/white"
+        android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 11,14.41L11,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_aural.xml b/core/res/res/drawable/perm_group_aural.xml
index 0465e98..b2737f2 100644
--- a/core/res/res/drawable/perm_group_aural.xml
+++ b/core/res/res/drawable/perm_group_aural.xml
@@ -19,6 +19,12 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF000000"
-        android:pathData="M20,2H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zm-2,5h-3v5.5c0,1.38 -1.12,2.5 -2.5,2.5S10,13.88 10,12.5s1.12,-2.5 2.5,-2.5c0.57,0 1.08,0.19 1.5,0.51V5h4v2zM4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6z"/>
+        android:fillColor="#000000"
+        android:pathData="M20,2H8C6.9,2,6,2.9,6,4v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C22,2.9,21.1,2,20,2z M20,16H8V4h12V16z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M12.5,15c1.38,0,2.5-1.12,2.5-2.5V7h3V5h-4v5.51C13.58,10.19,13.07,10,12.5,10c-1.38,0-2.5,1.12-2.5,2.5S11.12,15,12.5,15z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M4,6H2v14c0,1.1,0.9,2,2,2h14v-2H4V6z" />
 </vector>
diff --git a/core/res/res/drawable/perm_group_visual.xml b/core/res/res/drawable/perm_group_visual.xml
index bf9a0b1..9b21c27 100644
--- a/core/res/res/drawable/perm_group_visual.xml
+++ b/core/res/res/drawable/perm_group_visual.xml
@@ -19,6 +19,8 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF000000"
-        android:pathData="M22,16V4c0,-1.1 -0.9,-2 -2,-2H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zm-11,-4l2.03,2.71L16,11l4,5H8l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2H4V6H2z"/>
+        android:fillColor="#000000"
+        android:pathData="M20,4v12H8V4H20 M20,2H8C6.9,2,6,2.9,6,4v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C22,2.9,21.1,2,20,2L20,2z M2,6v14 c0,1.1,0.9,2,2,2h14v-2H4V6H2z M15.67,11l-2.5,2.98L11.5,11.8L9,15h10L15.67,11z" />
+    <path
+        android:pathData="M0,0h24v24H0V0z" />
 </vector>
diff --git a/core/res/res/layout-car/car_preference.xml b/core/res/res/layout-car/car_preference.xml
index 939c3fb..ae3d63b 100644
--- a/core/res/res/layout-car/car_preference.xml
+++ b/core/res/res/layout-car/car_preference.xml
@@ -20,7 +20,7 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="?android:attr/selectableItemBackground"
-    android:focusable="true"
+    android:clipToPadding="false"
     android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
     android:paddingStart="?android:attr/listPreferredItemPaddingStart">
diff --git a/core/res/res/layout/chooser_grid.xml b/core/res/res/layout/chooser_grid.xml
index 2860ee4..1f80417 100644
--- a/core/res/res/layout/chooser_grid.xml
+++ b/core/res/res/layout/chooser_grid.xml
@@ -20,7 +20,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:maxCollapsedHeight="288dp"
+    android:maxCollapsedHeight="0dp"
     android:maxCollapsedHeightSmall="56dp"
     android:id="@id/contentPanel">
 
@@ -32,12 +32,12 @@
 
         <ImageView
             android:id="@+id/drag"
-            android:layout_width="48dp"
-            android:layout_height="wrap_content"
+            android:layout_width="32dp"
+            android:layout_height="4dp"
             android:src="@drawable/ic_drag_handle"
             android:clickable="true"
-            android:paddingTop="@dimen/chooser_edge_margin_normal"
-            android:tint="?android:attr/textColorSecondary"
+            android:layout_marginTop="@dimen/chooser_view_spacing"
+            android:tint="@color/lighter_gray"
             android:layout_centerHorizontal="true"
             android:layout_alignParentTop="true" />
 
@@ -62,8 +62,8 @@
                   android:textAppearance="?attr/textAppearanceMedium"
                   android:textSize="20sp"
                   android:gravity="center"
-                  android:paddingTop="18dp"
-                  android:paddingBottom="18dp"
+                  android:paddingTop="@dimen/chooser_view_spacing"
+                  android:paddingBottom="@dimen/chooser_view_spacing"
                   android:paddingLeft="24dp"
                   android:paddingRight="24dp"
                   android:layout_below="@id/profile_button"
diff --git a/core/res/res/layout/resolve_grid_item.xml b/core/res/res/layout/resolve_grid_item.xml
index 4a3dfba..7065149 100644
--- a/core/res/res/layout/resolve_grid_item.xml
+++ b/core/res/res/layout/resolve_grid_item.xml
@@ -22,46 +22,43 @@
               android:layout_height="wrap_content"
               android:minHeight="100dp"
               android:gravity="center"
-              android:paddingTop="8dp"
+              android:paddingTop="24dp"
               android:paddingBottom="8dp"
+              android:paddingLeft="2dp"
+              android:paddingRight="2dp"
               android:focusable="true"
               android:background="?attr/selectableItemBackgroundBorderless">
 
     <ImageView android:id="@+id/icon"
                android:layout_width="@dimen/resolver_icon_size"
                android:layout_height="@dimen/resolver_icon_size"
-               android:layout_marginLeft="3dp"
-               android:layout_marginRight="3dp"
-               android:layout_marginBottom="3dp"
                android:scaleType="fitCenter" />
 
-    <!-- Activity name -->
+    <!-- Size manually tuned to match specs -->
+    <Space android:layout_width="1dp"
+           android:layout_height="7dp"/>
+
+    <!-- App name or Direct Share target name, DS set to 2 lines -->
     <TextView android:id="@android:id/text1"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
-              android:layout_marginTop="4dp"
-              android:layout_marginLeft="4dp"
-              android:layout_marginRight="4dp"
               android:textAppearance="?attr/textAppearanceSmall"
               android:textColor="?attr/textColorPrimary"
-              android:textSize="12sp"
+              android:textSize="14sp"
               android:fontFamily="sans-serif-condensed"
               android:gravity="top|center_horizontal"
-              android:minLines="2"
-              android:maxLines="2"
-              android:ellipsize="marquee" />
-    <!-- Extended activity info to distinguish between duplicate activity names -->
+              android:lines="1"
+              android:ellipsize="end" />
+
+    <!-- Activity name if set, gone for Direct Share targets -->
     <TextView android:id="@android:id/text2"
               android:textAppearance="?android:attr/textAppearanceSmall"
               android:textSize="12sp"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
-              android:layout_marginLeft="4dp"
-              android:layout_marginRight="4dp"
-              android:minLines="2"
-              android:maxLines="2"
+              android:lines="1"
               android:gravity="top|center_horizontal"
-              android:ellipsize="marquee"
-              android:visibility="gone" />
+              android:ellipsize="end"/>
+
 </LinearLayout>
 
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 78c0b80..bb8f3d6 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi-oproepe"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Af"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Verkies Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Verkies mobiel"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Net Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nie aangestuur nie"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Foutverslag"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Beëindig sessie"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skermkiekie"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Neem foutverslag"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Dit sal inligting oor die huidige toestand van jou toestel insamel om as \'n e-posboodskap te stuur. Dit sal \'n tydjie neem vandat die foutverslag begin is totdat dit reg is om gestuur te word; wees asseblief geduldig."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiewe verslag"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Gebruik dit in die meeste gevalle. Maak dit vir jou moontlik om die vordering van die verslag na te spoor, meer besonderhede oor die probleem in te voer en skermkiekies te neem. Dit sal dalk sommige afdelings wat minder gebruik word en waarvoor verslagdoening lank duur, weglaat."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Ligging"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"toegang te verkry tot hierdie toestel se ligging"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Gee &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang tot hierdie toestel se ligging?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Die program sal net toegang tot die ligging hê terwyl jy die program gebruik."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Gee &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; altyd toegang tot toestelligging?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Die program sal altyd toegang tot die ligging hê, selfs wanneer jy nie die program gebruik nie."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"by jou kalender in te gaan"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Gee &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang tot jou kalender?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Gee &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang tot jou musiek?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Foto\'s en video\'s"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"toegang tot jou foto\'s en video\'s"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Laat &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toe om by jou foto\'s en video\'s in te gaan, insluitend gemerkte liggings?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Venster-inhoud ophaal"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Die inhoud ondersoek van \'n venster waarmee jy interaksie het."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Verken deur raak aanskakel"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Laat die program toe om met kortveldkommunikasie- (NFC) merkers, kaarte en lesers te kommunikeer."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktiveer jou skermslot"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Laat die program toe om die sleutelslot en enige verwante wagwoordsekuriteit te deaktiveer. Byvoorbeeld, die foon deaktiveer die sleutelslot wanneer ’n oproep inkom, en atkiveer dit dan weer wanneer die oproep eindig."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"versoek skermslot-kompleksiteit"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Laat die program toe om die skermslot-kompleksiteitvlak (hoog, medium, laag of geen) te leer, wat die moontlike omvang van die lengte en soort skermslot aandui. Hierdie program kan ook aan gebruikers voorstel dat hulle die skermslot na \'n sekere vlak toe opdateer, maar gebruikers kan dit vrylik ignoreer en weggaan. Let daarop dat die skermslot nie in skoonteks geberg word nie sodat die program nie die presiese wagwoord ken nie."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"gebruik biometriese hardeware"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Laat die program toe om biometriese hardeware vir stawing te gebruik"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"bestuur vingerafdrukhardeware"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Laat program toe om metodes te benut om gesigtemplate vir gebruik by te voeg en uit te vee."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"gebruik gesigstawinghardeware"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Laat die program toe om gesigstawinghardeware vir stawing te gebruik"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Kon nie gesig verwerk nie. Probeer weer."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Gesig is te helder. Probeer met minder lig."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Gesig is te donker. Maak ligbron oop."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Beweeg sensor verder weg van gesig af."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Bring sensor nader aan gesig."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Beweeg sensor na bo."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Beweeg sensor na onder."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Beweeg sensor na regs."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Beweeg sensor na links."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Kyk na die sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Geen gesig bespeur nie."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Te veel beweging."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Skryf jou gesig asseblief weer in."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Ander gesig is bespeur."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Te eenders. Verander asseblief jou pose."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Kyk asseblief meer reguit na die kamera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Kyk asseblief meer reguit na die kamera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Hou asseblief jou kop regop."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Ontbloot asseblief jou gesig."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Gesighardeware is nie beskikbaar nie."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Gesiguittelling is bereik. Probeer weer."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Gesig kan nie geberg word nie."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Gesighandeling is gekanselleer."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Gesigstawing is deur gebruiker gekanselleer."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Te veel pogings. Probeer later weer."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Te veel pogings. Gesigstawingsensor is gedeaktiveer."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Probeer weer."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Geen gesigte is geregistreer nie."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Hierdie toestel het nie \'n gesigstawingsensor nie."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Gesig <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Maak <xliff:g id="NEW_APP">%1$s</xliff:g> oop"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> sal toemaak sonder om te stoor"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> het berginglimiet oorskry"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Hoopstorting is ingesamel. Tik om te deel."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Deel hoopstorting?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Die proses <xliff:g id="PROC">%1$s</xliff:g> het sy prosesberginglimiet van <xliff:g id="SIZE">%2$s</xliff:g> oorskry. \'n Hoopstorting is beskikbaar wat jy met sy ontwikkelaar kan deel. Pas op: Hierdie hoopstorting kan enige van jou persoonlike inligting bevat waartoe die program toegang het."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Kies \'n handeling vir teks"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Luiervolume"</string>
     <string name="volume_music" msgid="5421651157138628171">"Mediavolume"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerke te sien"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koppel"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netwerke"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"\'n Wi‑Fi-netwerk voorgestel deur <xliff:g id="NAME">%s</xliff:g> is beskikbaar"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Wil jy koppel aan netwerke wat <xliff:g id="NAME">%s</xliff:g> voorgestel het?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nee"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi sal outomaties aanskakel"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Meld by netwerk aan"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi‑Fi het geen internettoegang nie"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tik vir opsies"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Gekoppel"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Veranderings aan jou warmkolinstellings"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Jou warmkolband het verander."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Hierdie toestel steun nie jou voorkeur vir net 5 GHz nie. Hierdie toestel sal in plaas daarvan die 5 GHz-band gebruik wanneer dit beskikbaar is."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tik om USB-ontfouting af te skakel"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Kies om USB-ontfouting te deaktiveer."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vloeistof of vuilgoed in USB-poort"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-poort is outomaties gedeaktiveer. Tik om meer te wete te kom."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Veilig om USB-poort te gebruik"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Tik om werkprofiel te ontsluit"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Gekoppel aan <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tik om lêers te bekyk"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Speld vas"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Ontspeld"</string>
     <string name="app_info" msgid="6856026610594615344">"Programinligting"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Begin tans demonstrasie …"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Roetinemodus-inligtingkennisgewing"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Battery kan afloop voordat dit normaalweg gelaai word"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Batterybespaarder is geaktiveer om batterylewe te verleng"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Vouer"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android-program"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Lêer"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index cabca7f..b42fd20 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"የWi-Fi ጥሪ"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ጠፍቷል"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ተመርጧል"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"የተንቀሳቃሽ ስልክ ተመራጭ ነው"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi ብቻ"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>፡አልተላለፈም"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"የሳንካ ሪፖርት"</string>
     <string name="global_action_logout" msgid="935179188218826050">"ክፍለ-ጊዜን አብቃ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ቅጽበታዊ ገጽ እይታ"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"የሳንካ ሪፖርት ውሰድ"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"ይሄ እንደ የኢሜይል መልዕክት አድርጎ የሚልከውን ስለመሣሪያዎ የአሁኑ ሁኔታ መረጃ ይሰበስባል። የሳንካ ሪፖርቱን ከመጀመር ጀምሮ እስኪላክ ድረስ ትንሽ ጊዜ ይወስዳል፤ እባክዎ ይታገሱ።"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"መስተጋብራዊ ሪፖርት"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"በአብዛኛዎቹ ሁኔታዎች ላይ ይህን ይጠቀሙ። የሪፖርቱን ሂደት እንዲከታተሉ፣ ስለችግሩ ተጨማሪ ዝርዝሮችን እንዲያስገቡ እና ቅጽበታዊ ገጽ እይታዎችን እንዲያነሱ ያስችልዎታል። ሪፖርት ለማድረግ ረዥም ጊዜ የሚወስዱ አንዳንድ ብዙም ጥቅም ላይ የማይውሉ ክፍሎችን ሊያልፋቸው ይችላል።"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"መገኛ አካባቢ"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"የዚህን መሣሪያ አካባቢ ይድረሱበት"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; የዚህ መሣሪያ አካባቢን እንዲደርስ ይፈቀድለት?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"መተግበሪያው እርስዎ ሲጠቀሙበት ብቻ ነው የአካባቢው መዳረሻ የሚኖረው።"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"ሁልጊዜ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; የዚህ መሣሪያ አካባቢን እንዲደርስ ይፈቀድለት?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"መተግበሪያው ሁልጊዜ የአካባቢው መዳረሽ ይኖረዋል፣ እርስዎ መተግበሪያውን እየተጠቀሙ ባይሆኑም እንኳ።"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ቀን መቁጠሪያ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"የእርስዎን ቀን መቁጠሪያ ይድረሱበት"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ቀን መቁጠሪያዎን እንዲደርስ ይፈቀድለት?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ቀን ሙዚቃዎን እንዲደርስ ይፈቀድለት?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ፎቶዎች እና ቪዲዮዎች"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"የእርስዎን ፎቶዎች እና ቪዲዮዎች መድረስ"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"የእርስዎን ፎቶዎች እና ቪዲዮዎች መለያ ስያሜ የተደረገባቸውን መገኛ አካባቢዎች ጨምሮ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; እንዲደርስ ይፈቀድለት?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"የመስኮት ይዘት ሰርስረው ያውጡ"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"መስተጋበር የሚፈጥሩት የመስኮት ይዘት ይመርምሩ።"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"በመንካት ያስሱን ያብሩ"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"ከቅርብ ግኑኙነት መስክ (NFC) መለያዎች፣ ካርዶች እና አንባቢ ጋር ለማገናኘት ለመተግበሪያው ይፈቅዳሉ።"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"የማያ ገጽዎን መቆለፊያ ያሰናክሉ"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"መተግበሪያው መቆለፊያውና ማንኛውም የተጎዳኘ የይለፍ ቃል ደህንነት እንዲያሰናክል ይፈቅድለታል። ለምሳሌ ስልኩ ገቢ የስልክ ጥሪ በሚቀበልበት ጊዜ መቆለፊያውን ያሰናክልና ከዚያም ጥሪው ሲጠናቀቅ መቆለፊያውን በድጋሚ ያነቃዋል።"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"የማያ ገጽ መቆለፊያ ውስብስብነትን ጠይቅ"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"መተግበሪያው የማያ ገጽ መቆለፊያው ውስብስብነት ደረጃ (ከፍተኛ፣ መካከለኛ፣ ዝቅተኛ ወይም ምንም) እንዲያውቅ ያስችለዋል፣ ይህም ሊሆኑ የሚችለው የማያ ገጽ መቆለፊያው ርዝመት እና አይነት ክልል ያመለክታል። መተግበሪያው እንዲሁም ለተጠቃሚዎች የማያ ገጽ መቆለፊያውን ወደተወሰነ ደረጃ እንዲያዘምኑት ሊጠቁማቸው ይችላል። የማያ ገጽ መቆለፊያው በስነጣ አልባ ጽሑፍ እንደማይከማች ልብ ይበሉ፣ በዚህም መተግበሪያው ትክክለኛውን የይለፍ ቃል አያውቅም።"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ባዮሜትራዊ ሃርድዌርን መጠቀም"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"መተግበሪያው የባዮሜትራዊ ሃርድዌር ለማረጋገጥ ስራ እንዲጠቀም ያስችለዋል"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"የጣት አሻራ ሃርድዌርን አስተዳድር"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"መተግበሪያው ጥቅም ላይ እንዲውሉ የፊት ቅንብር ደንቦችን ለማከል እና ለመሰረዝ የሚያስችሉ ስልቶችን እንዲያስጀምር ያስችለዋል።"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"የፊት ማረጋገጫ ሃርድዌር ይጠቀሙ"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"መተግበሪያው የማረጋገጫ ሃርድዌር ለማረጋገጥ ሥራ እንዲጠቀም ያስችለዋል"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"ፊትን መሥራት አልተቻለም። እባክዎ እንደገና ይሞክሩ።"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"ፊት ከልክ በላይ ብሩህ ነው። እባክዎ በዝቅተኛ ብርሃን ውስጥ ይሞክሩት።"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"ፊት ከልክ በላይ ጨለም ያለ ነው። እባክዎ የብርሃን ምንጩን ይግለጹት።"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"እባክዎ ዳሳሹን ከፊት አሁንም ያርቁት።"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"እባክዎ ዳሳሹን ወደ ፊት ያስጠጉት።"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"እባክዎ ዳሳሽን ከፍ ያድርጉት።"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"እባክዎ ዳሳሽን ዝቅ ያድርጉት።"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"እባክዎ ዳስሽን ወደ ቀኝ ያንቀሳቅሱት።"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"እባክዎ ዳስሽን ወደ ግራ ያንቀሳቅሱት።"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"እባክዎ ዳሳሹ ላይ ይመልከቱ።"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"ምንም መልክ አልተገኘም።"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"ከልክ በላይ ብዙ እንቅስቃሴ።"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"እባክዎ ፊትዎን እንደገና ያስመዝግቡ"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"የተለየ ፊት ተገኝቷል።"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"በጣም ይመሳሰላል፣ እባክዎ የእርስዎን ፎቶ አነሳስ ይለውጡ"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"እባክዎ ወደ ካሜራው በቀጥታ ይመልከቱ።"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"እባክዎ ወደ ካሜራው በቀጥታ ይመልከቱ።"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"እባክዎ ጭንቅላትዎን ቀጥ ያድርጉ።"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"እባክዎ ከፊትዎ ላይ ያለውን ጨርቅ ያንሱ።"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"የፊት ሃርድዌር አይገኝም።"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"የፊት ማብቂያ ጊዜ ደርሷል። እንደገና ይሞክሩ።"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"ፊት ሊከማች አይችልም።"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"የፊት ሥርዓተ ክወና ተሰርዟል።"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"ፊትን ማረጋገጥ በተጠቃሚ ተሰርዟል።"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ከልክ በላይ ብዙ ሙከራዎች። በኋላ ላይ እንደገና ይሞክሩ።"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"በጣም ብዙ ሙከራዎች። የፊት ማረጋገጫ ተሰናክሏል።"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"እንደገና ይሞክሩ።"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"ምንም ፊት አልተመዘገበም።"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"ይህ መሣሪያ የፊት ማረጋገጫ ዳሳሽ የለውም።"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"ፊት <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g>ን ይክፈቱ"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> ሳያስቀምጥ ይዘጋል"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> የማህደረ ትውስታ ገደብን አልፏል"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"የቆሻሻ ቁልል ተሰብስቧል። ለማጋራት መታ ያድርጉ።"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"የቆሻሻ ቁልል ይጋራ?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"የ<xliff:g id="PROC">%1$s</xliff:g> ሂደት የማህደረ ትውስታ ሂደት <xliff:g id="SIZE">%2$s</xliff:g> ገደቡን አልፏል። የቆሻሻ ቁልል ከገንቢው ጋር እንዲያጋሩ ለእርስዎ ሊገኝ ይችላል። ጥንቃቄ ያድርጉ፦ ይህ የቆሻሻ ቁልል መተግበሪያው መዳረሻ ያለው የሆነ የእርስዎ የግል መረጃን ሊይዝ ይችላል።"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"ለፅሁፍ ድርጊት ምረጥ"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"የስልክ ጥሪ ድምፅ"</string>
     <string name="volume_music" msgid="5421651157138628171">" ማህደረ መረጃ  ክፍልፍል"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ሁሉንም አውታረ መረቦችን ለማየት መታ ያድርጉ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"አገናኝ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ሁሉም አውታረ መረቦች"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"በ<xliff:g id="NAME">%s</xliff:g> የተጠቆመ የWi-Fi አውታረ መረብ ይገኛል"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"በ<xliff:g id="NAME">%s</xliff:g> ከተጠቆሙ አውታረ መረቦች ጋር መገናኘት ይፈልጋሉ?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"አዎ"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"አይ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi በራስ-ሰር ይበራል"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi በይነመረብ መዳረሻ የለውም"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ለአማራጮች መታ ያድርጉ"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"ተገናኝቷል"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"በእርስዎ ሆትስፖት ቅንብሮች ላይ ለውጦች"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"የእርስዎ ሆትስፖት ባንድ ተለውጧል።"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"ይህ መሣሪያ የእርስዎን ምርጫ ለ5GHz ብቻ አይደግፍም። በምትኩ፣ ይህ መሣሪያ ሲገኝ 5GHz ባንድ ይጠቀማል።"</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"የዩኤስቢ ማረሚያን ለማጥፋት መታ ያድርጉ"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ማረሚያ ላለማንቃት ምረጥ።"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"በዩኤስቢ ወደብ ውስጥ ፈሳሽ ወይም ፍርስራሽ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"የዩኤስቢ ወደብ በራስ-ሰር ተሰናክሏል። የበለጠ ለመረዳት መታ ያድርጉ።"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"የዩኤስቢ ወደቡን መጠቀም አደጋ የለውም"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"የስራ መገለጫውን እገዳ ለማንሳት መታ ያድርጉ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"ከ<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ጋር ተገናኝቷል"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ፋይሎችን ለመመልከት መታ ያድርጉ"</string>
-    <string name="pin_target" msgid="3052256031352291362">"ፒን"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"ንቀል"</string>
     <string name="app_info" msgid="6856026610594615344">"የመተግበሪያ መረጃ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ማሳያን በማስጀመር ላይ…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"የዕለት ተዕለት ሁነታ መረጃ ማሳወቂያዎች"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ባትሪ ከተለመደው ኃይል መሙላት በፊት ሊያልቅ ይችላል"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"የባትሪ ቆጣቢ የባትሪ ዕድሜን ለማራዘም ገብሯል።"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"አቃፊ"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"የAndroid መተግበሪያ"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ፋይል"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index e7dad2f..5a24461 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"ৱাই-ফাই কলিং"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"অফ হৈ আছে"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ৱাই-ফাইক অগ্ৰাধিকাৰ দিয়া হৈছে"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ম\'বাইলক অগ্ৰাধিকাৰ দিয়া হৈছে"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"কোৱল ৱাই-ফাই"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ফৰৱাৰ্ড কৰা নহ\'ল"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"বাগ সম্পর্কীয় অভিযোগ"</string>
     <string name="global_action_logout" msgid="935179188218826050">"ছেশ্বন সমাপ্ত কৰক"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"স্ক্ৰীণশ্বট"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"বাগ সম্পর্কীয় অভিযোগ লওক"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"এই কার্যই ইমেইল বাৰ্তা হিচাপে পঠিয়াবলৈ আপোনাৰ ডিভাইচৰ বৰ্তমান অৱস্থাৰ বিষয়ে তথ্য সংগ্ৰহ কৰিব৷ ইয়াক বাগ সম্পর্কীয় অভিযোগ পঠিওৱা কাৰ্য আৰম্ভ কৰোঁতে অলপ সময় লাগিব; অনুগ্ৰহ কৰি ধৈৰ্য ধৰক।"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ইণ্টাৰেক্টিভ অভিযোগ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"বেছিভাগ পৰিস্থিতিত এয়া ব্যৱহাৰ কৰক। ই আপোনাক অভিযোগৰ অগ্ৰগতি ট্ৰেক কৰিবলৈ, সমস্যাটোৰ সম্পর্কে অধিক বিৱৰণ দিবলৈ আৰু স্ক্ৰীণশ্বট ল\'বলৈ অনুমতি দিয়ে। ই কম ব্যৱহাৰ হোৱা সেই শাখাসমূহক অন্তৰ্ভুক্ত নকৰিব পাৰে যিবোৰক অভিযোগ কৰিবলৈ দীৰ্ঘ সময়ৰ প্ৰয়োজন হয়।"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"অৱস্থান"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"এই ডিভাইচৰ অৱস্থান ব্যৱহাৰ কৰিব পাৰে"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক এই ডিভাইচটোৰ অৱস্থান জানিবলৈ অনুমতি দিবনে?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"আপুনি এই এপ্ ব্য়ৱহাৰ কৰি থাকোঁতে ই সদায় অৱস্থান চাব পাৰে।"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক সদায় এই ডিভাইচৰ অৱস্থান চাবলৈ অনুমতি দিবনে?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"আপুনি এই এপ্ ব্য়ৱহাৰ কৰি থকা নাই যদিও ই সদায় অৱস্থান চাব পাৰে।"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"কেলেণ্ডাৰ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"আপোনাৰ কেলেণ্ডাৰ ব্যৱহাৰ কৰিব পাৰে"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক আপোনাৰ কেলেণ্ডাৰ চাবলৈ অনুমতি দিবনে?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক আপোনাৰ সংগীত এক্সেছ কৰিবলৈ দিবনে?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ফট’ আৰু ভিডিঅ’"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"আপোনাৰ ফট’ আৰু ভিডিঅ’সমূহ এক্সেছ কৰিবলৈ"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"টেগ কৰা অৱস্থানসহ আপোনাৰ ফট’ আৰু ভিডিঅ’ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক এক্সেছ কৰিবলৈ দিবনে?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ৱিণ্ড’ সমল বিচাৰি উলিওৱাৰ"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"আপুনি চাই থকা ৱিণ্ড’খনৰ সমল পৰীক্ষা কৰাৰ।"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পৰ্শৰ দ্বাৰা অন্বেষণ কৰাৰ সুবিধা অন কৰাৰ"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"এপটোক নিয়েৰ ফিল্ড কমিউনিকেশ্বন (NFC) টেগ, কাৰ্ড আৰু ৰিডাৰসমূহৰ সৈতে যোগাযোগ কৰিবলৈ অনুমতি দিয়ে।"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"আপোনাৰ স্ক্ৰীণ ল\'ক অক্ষম কৰক"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"এপটোক কী ল\'ক আৰু জড়িত হোৱা যিকোনো পাছৱৰ্ডৰ সুৰক্ষা অক্ষম কৰিব দিয়ে৷ উদাহৰণস্বৰূপে, কোনো অন্তৰ্গামী ফ\'ন কল উঠোৱাৰ সময়ত ফ\'নটোৱে কী-লকটো অক্ষম কৰে, তাৰ পিছত কল শেষ হ\'লেই কী লকটো পুনৰ সক্ষম কৰে৷"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"স্ক্ৰীণ লকৰ জটিলতাৰ অনুৰোধ জনোৱা"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"এপটোক স্ক্ৰীণ ল’কৰ জটিলতাৰ স্তৰ (উচ্চ, মধ্যম, নিম্ন বা একেবাৰে নাই), শিকিবলৈ অনুমতি দিয়ে ই স্ক্ৰীণ ল’কৰ সম্ভাব্য দৈৰ্ঘ্য বা স্ক্ৰীণ ল’কৰ প্ৰকাৰ দৰ্শায়। লগতে এপটোৱে ব্যৱহাৰকাৰীক স্ক্ৰীণ ল’কটো এটা নিৰ্দিষ্ট স্তৰলৈ আপডে’ট কৰিবলৈ পৰামৰ্শ দিব পাৰে যিটো ব্যৱহাৰকাৰীয়ে উপেক্ষা কৰি পৰৱর্তী পৃষ্ঠালৈ যাব পাৰে। মনত ৰাখিব যে স্ক্ৰীণ ল’কটো সাধাৰণ পাঠ হিচাপে সঞ্চয় কৰা নহয় সেয়ে এপটোৱে সঠিক পাছৱৰ্ডটো জানিব নোৱাৰে।"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্য়ৱহাৰ কৰক"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"বিশ্বাসযোগ্য়তা প্ৰমাণীকৰণৰ বাবে এপক বায়োমেট্ৰিক হাৰ্ডৱেৰ ব্য়ৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ফিংগাৰপ্ৰিণ্ট হাৰ্ডৱেৰ পৰিচালনা কৰিব পাৰে"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"মুখমণ্ডলৰ টেম্প্লেট যোগ কৰাৰ বা মচাৰ পদ্ধতি কামত লগাবলৈ আহ্বান কৰিবলৈ এপটোক অনুমতি দিয়ে।"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"মুখমণ্ডল সত্যাপন হাৰ্ডৱেৰ ব্যৱহাৰ কৰক"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"বিশ্বাসযোগ্য়তা প্ৰমাণীকৰণৰ বাবে এপক মুখমণ্ডল সত্যাপন হাৰ্ডৱেৰ ব্য়ৱহাৰ কৰিবলৈ অনুমতি দিয়ে"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"মুখমণ্ডল চিনাক্ত কৰিব পৰা নাই; আকৌ চেষ্টা কৰক।"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"মুখমণ্ডল অত্যন্ত উজ্জ্বল হৈছে। অনুগ্ৰহ কৰি পোহৰ কম থকা ঠাইত চেষ্টা কৰক।"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"মুখমণ্ডল অত্যন্ত আন্ধাৰ হৈছে। অনুগ্ৰহ কৰি পোহৰ থকা ঠাইলৈ যাওক।"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"অনুগ্ৰহ কৰি মুখৰ পৰা ছেন্সৰ অলপ দূৰত ৰাখক।"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"অনুগ্ৰহ কৰি ছেন্সৰটো মুখৰ ওচৰলৈ আনক।"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"অনুগ্ৰহ কৰি ছেন্সৰটো ওপৰলৈ নিয়ক।"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"অনুগ্ৰহ কৰি ছেন্সৰটো তললৈ নিয়ক।"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"অনুগ্ৰহ কৰি ছেন্সৰটো সোঁফাললৈ নিয়ক।"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"অনুগ্ৰহ কৰি ছেন্সৰটো বাওঁফাললৈ নিয়ক।"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"অনুগ্ৰহ কৰি ছেন্সৰটোলৈ চাওক।"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"কোনো মুখমণ্ডল চিনাক্ত কৰিব পৰা নগ’ল।"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"বেছি লৰচৰ কৰি আছে।"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"আপোনাৰ মুখমণ্ডল পুনৰ পঞ্জীয়ন কৰক।"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"অন্য মুখমণ্ডল চিনাক্ত কৰা হৈছে।"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"একে ধৰণৰ হৈছে, অনুগ্ৰহ কৰি আপোনাৰ প’জটো সলনি কৰক।"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"অনুগ্ৰহ কৰি পোনে পোনে কেমেৰালৈ চাওক।"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"অনুগ্ৰহ কৰি পোনে পোনে কেমেৰালৈ চাওক।"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"অনুগ্ৰহ কৰি আপোনাৰ মূৰটো উলম্বভাৱে চিধা কৰক।"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"আপোনাৰ মুখমণ্ডলৰপৰা আৱৰণ আঁতৰাওক।"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"মুখমণ্ডলৰ হাৰ্ডৱেৰ উপলব্ধ নহয়।"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"মুখমণ্ডল গ্ৰহণৰ সময়সীমা উকলি গৈছে। আকৌ চেষ্টা কৰক।"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"মুখমণ্ডল সঞ্চয় কৰিব নোৱাৰি।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"মুখমণ্ডলৰ প্ৰক্ৰিয়া বাতিল কৰা হ’ল।"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"ব্যৱহাৰকাৰীয়ে মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ বাতিল কৰিছে।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"অত্যধিক ভুল প্ৰয়াস। কিছুসময়ৰ পাছত আকৌ চেষ্টা কৰক।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"অত্যধিক প্ৰয়াস। মুখমণ্ডলৰ জৰিয়তে সত্যাপন অক্ষম কৰা হ’ল।"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"আকৌ চেষ্টা কৰক।"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"কোনো মুখমণ্ডল যোগ কৰা নহ’ল।"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"এই ডিভাইচটোত মুখমণ্ডল সত্যাপন ছেন্সৰ নাই।"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"মুখমণ্ডল <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> খোলক"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> ছেভ নকৰাকৈ বন্ধ হ\'ব"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> মেম\'ৰিৰ সীমা অতিক্ৰম কৰিছে"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"হীপ ডাম্প সংগ্ৰহ কৰা হ’ল। শ্বেয়াৰ কৰিবলৈ টিপক"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"হীপ ডাম্প শ্বেয়াৰ কৰিবনে?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"এই <xliff:g id="PROC">%1$s</xliff:g> প্ৰক্ৰিয়াটোৱে তাৰ মেম\'ৰিৰ সীমা <xliff:g id="SIZE">%2$s</xliff:g> অতিক্ৰম কৰিছে। ইয়াৰ বিকাশকৰ্তাৰ সৈতে আপুনি শ্বেয়াৰ কৰিবপৰাকৈ হীপ ডাম্প মজুত আছে। সাৱধান হ\'ব: এই হীপ ডাম্পত এপ্লিকেশ্বনটোৱে ব্যৱহাৰ কৰা আপোনাৰ কোনো ব্য়ক্তিগত তথ্য়ও থাকিব পাৰে।"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"বার্তাৰ বাবে কাৰ্য বাছনি কৰক"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"ৰিংগাৰৰ ধ্বনি"</string>
     <string name="volume_music" msgid="5421651157138628171">"মিডিয়াৰ ধ্বনি"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সকলো নেটৱৰ্ক চাবলৈ টিপক"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযোগ কৰক"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"সকলো নেটৱৰ্ক"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g>এ প্ৰস্তাৱ কৰা এটা ৱাই-ফাই নেটৱৰ্ক উপলব্ধ হৈছে"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"আপুনি <xliff:g id="NAME">%s</xliff:g>এ প্ৰস্তাৱ কৰা নেটৱৰ্ককেইটাৰ সৈতে সংযোগ কৰিবনে?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"হয়"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"নহয়"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ৱাই-ফাই স্বয়ংক্ৰিয়ভাৱে অন হ\'ব"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"নেটৱৰ্কত ছাইন ইন কৰক"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"ৱাই-ফাইত ইণ্টাৰনেট নাই"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"অধিক বিকল্পৰ বাবে টিপক"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"সংযোগ কৰা হ’ল"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"আপোনাৰ হটস্পট ছেটিংসমূহত কৰা সালসলনি"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"আপোনাৰ হটস্পটৰ বেণ্ড সলনি কৰা হ’ল।"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"আপোনাৰ কেৱল ৫গিগাহাৰ্টজৰ প্ৰতি অগ্ৰাধিকাৰ এই ডিভাচইচটোৱে সমৰ্থন নকৰে। ইয়াৰ পৰিৱৰ্তে, ডিভাচইচটোৱে যেতিয়া ৫গিগাহাৰ্টজ বেণ্ড উপলব্ধ হ’ব তেতিয়া সেইয়া ব্যৱহাৰ কৰিব।"</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"ইউএছবি ডিবাগিং সংযোগ কৰা হ’ল"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"ইউএছবি ডিবাগিং বন্ধ কৰিবলৈ টিপক"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ইউএছবি ডিবাগিং অক্ষম কৰিবলৈ বাছনি কৰক।"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএছবি প’ৰ্টত তৰল বা ধূলি-মাকতি আছে"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএছবি প’ৰ্ট স্বয়ংক্ৰিয়ভাৱে অক্ষম কৰা হয়। অধিক জানিবৰ বাবে টিপক।"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"ইউএছবি প’ৰ্ট ব্যৱহাৰ কৰিব পৰাকৈ নিৰাপদ"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"কৰ্মস্থানৰ প্ৰ’ফাইল আনলক কৰিবলৈ টিপক"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>ৰ সৈতে সংযুক্ত হৈ আছে"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ফাইলসমূহ চাবৰ বাবে টিপক"</string>
-    <string name="pin_target" msgid="3052256031352291362">"পিন"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"আনপিন"</string>
     <string name="app_info" msgid="6856026610594615344">"এপ্ সম্পৰ্কীয় তথ্য"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ডেম\' আৰম্ভ কৰি থকা হৈছে…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"ৰুটিন ম’ডৰ তথ্য জাননী"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"চ্চাৰ্জ কৰাৰ সচৰাচৰ সময়ৰ আগতেই বেটাৰি শেষ হ’ব পাৰে"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"বেটাৰিৰ খৰচ কমাবলৈ বেটাৰি সঞ্চয়কাৰী অন কৰা হৈছে"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ফ’ল্ডাৰ"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android এপ্লিকেশ্বন"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ফাইল"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 7186da9..9ac4a2a 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WiFi Zəngi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Deaktiv"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi tərcih edilir"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobil tərcih"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Yalnız Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yönləndirilmədi"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Baq hesabatı"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Sessiyanı sonlandırın"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skrinşot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Baqı xəbər verin"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Bu, sizin hazırkı cihaz durumu haqqında məlumat toplayacaq ki, elektron məktub şəklində göndərsin. Baq raportuna başlamaq üçün bir az vaxt lazım ola bilər, bir az səbr edin."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"İnteraktiv hesabat"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Bir çox hallarda bundan istifadə edin. Bu hesabatın gedişatını izləməyə, problem haqqında daha ətraflı məlumat daxil etməyə və skrinşot etməyə imkan verir. Bu, çox vaxt tələb edən bəzi az istifadə olunan bölmələri ixtisar edə bilər."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Yer"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"cihazın yerini bilmək"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinə bu cihazın məkanına daxil olmaq icazəsi verilsin?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Tətbiq yalnız ondan istifadə etiyiniz zaman məkanı əldə edə bilər."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinə bu cihazın məkanına daxil olmaq icazəsi verilsin?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Tətbiq hətta ondan istifadə etmədiyiniz zaman belə məkanı əldə edə bilər."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Təqvim"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"təqvimə daxil olun"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinə təqvimə daxil olmaq icazəsi verilsin?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinin musiqiyə daxil olmağına icazə verilsin?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Foto və videolar"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"foto və videolara daxil olun"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinə işarələnmiş məkanlar daxil olmaqla, foto və videolara girişinə icazə verilsin?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pəncərənin məzmununu əldə edin"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Əlaqədə olduğunuz pəncərənin məzmununu nəzərdən keçirin."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Toxunaraq Kəşf et funksiyasını yandırın"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Tətbiqə Yaxın Məsafə Kommunikasiyası (NFC) teqləri, kartları və oxuyucuları ilə əlaqə qurmağa icazə verir."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Ekran kilidini deaktiv edir"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Tətbiqə kilid açarını və təhlükəsizlik parolunu deaktiv etməyə imkan verir. Qanuni misal budur ki, telefon zəng qəbul edən zaman kilidi açır və zəng qurtarandan sonra kilidi bağlayır."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ekran kilidi mürəkkəbliyi tələb edin"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Tətbiqə ekran kilidinin uzunluq intervalı və növünü göstərən ekran kilidi mürəkkəbliliyinin səviyyəsini (yüksək, orta, aşağı və ya heç biri) öyrənməyə icazə verir. Tətbiq, istifadəçilərə ekran kilidini müəyyən səviyyəyə yeniləməyi təklif edə bilər, lakin istifadəçilər istənilən vaxt bunu iqnor edə bilər. Nəzərə alın ki, ekran kilidi açıq şəkildə saxlanılmır, buna görə də tətbiq dəqiq parolu bilmir."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"biometrik proqramdan istifadə edin"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Doğrulama üçün biometrik proqramdan istifadə etməyə imkan verir"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"barmaq izi avadanlığını idarə edin"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Proqramdan istifadə üçün barmaq izi şablonlarını əlavə etmək və silmək məqsədilə üsullara müraciət etməyə imkan verir."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"üz identifikasiyası proqramından istifadə edin"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Tətbiqin üz identifikasiyası proqramından identifikasiya zamanı istifadə etməsinə icazə verir"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Üz tanınmadı. Yenidən cəhd edin."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Üz çox parlaqdır. Daha zəif işıqda sınayın."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Üz çox tünddür. İşığı ortaya çıxarın."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Sensoru üzdən kənara gətirin."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Sensoru üzə biraz da yaxınlaşdırın."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Sensoru daha yuxarı gətirin."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Sensoru daha aşağı gətirin."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Sensoru sağa gətirin."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Sensoru sola gətirin."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Sensora baxın."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Üz aşkarlanmadı."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Cihazı sabit saxlayın."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Üzünüzü yenidən qeydiyyatdan keçirin."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Fərqli üz aşkar edildi."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Digəri ilə oxşardır, pozanızı dəyişin."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Birbaşa kameraya baxın."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Birbaşa kameraya baxın."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Başınızı şaquli istiqamətdə qaldırın."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Üzünüzü açıq saxlayın."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Üz proqramı əlçatan deyil."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Üz proqramı taymerinin vaxtı bitdi. Yenidən cəhd edin."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Üz bərpa edilmədi."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Üz əməliyyatı ləğv edildi."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Üz dorğulaması istifadəçi tərəfindən ləğv edildi."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Həddindən çox cəhd. Sonraya saxlayın."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Həddindən çox cəhd. Üz identifikasiyası deaktiv edildi."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Yenidən cəhd edin."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Üz qeydə alınmayıb."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Bu cihazda üz identifikasiyası sensoru yoxdur."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Üz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> tətbiqini açın"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> yadda saxlamadan bağlanacaq"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> yaddaş limitini keçdi"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Şəkil çəkildi. Paylaşmaq üçün klikləyin."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Yığın paylaşılsın?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> prosesi <xliff:g id="SIZE">%2$s</xliff:g> ölçüsünün yaddaş limitini prosesini keçib. Yığın tərtibatçısı ilə paylaşmaq üçün sizə istifadəsi mümkündür. Ehtiyatlı olun: bu yığında proqramın giriş icazəsi olduğu şəxsi məlumatlarınız ola bilər."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Mətn üçün əməliyyat seçin"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Zəngin səs gücü"</string>
     <string name="volume_music" msgid="5421651157138628171">"Media həcmi"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Bütün şəbəkələri görmək üçün klikləyin"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Qoşulun"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Bütün şəbəkələr"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> tərəfindən təklif edilən Wi‑Fi şəbəkəsi əlçatandır"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> tərəfindən təklif edilən şəbəkələrə qoşulmaq istəyirsiniz?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Bəli"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Xeyr"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi avtomatik olaraq aktiv ediləcək"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Şəbəkəyə daxil olun"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi şəbəkəsinin internetə girişi yoxdur"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Seçimlər üçün tıklayın"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Qoşuldu"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Hotspot ayarlarınızda dəyişiklik"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Hotspot qrupu dəyişdi."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Bu cihaz yalnız 5GHz üçün tərcihinizi dəstəkləmir. Əvəzinə əlçatan olduqda bu cihaz 5GHz qrupundan istifadə edəcək."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB sazlamanı deaktiv etmək üçün klikləyin"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USb debaqı deaktivasiya etməyi seçin."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB portuna maye sızıb və ya qırılıb"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB portu avtomatik deaktiv edildi. Ətraflı məlumat üçün klikləyin."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB portundan istifadə təhlükəsizdir"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"İş profilinin kilidini açmaq üçün tıklayın"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> məhsuluna bağlandı"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Faylları görmək üçün basın"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Pin kod"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Çıxarın"</string>
     <string name="app_info" msgid="6856026610594615344">"Tətbiq məlumatı"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo başlayır…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Rejim üçün məlumat bildirişi"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Batareya həmişəki vaxtdan əvvəl bitə bilər"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Enerjiyə Qənaət rejimi batareya istifadəsinin müddətini artırmaq üçün aktiv edilir"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Qovluq"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android tətbiqi"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fayl"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 788b5d6..363b5ea 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -142,8 +142,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Pozivanje preko Wi-Fi-ja"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Želim mobilne podatke"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije prosleđeno"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -230,7 +232,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izveštaj o grešci"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Završi sesiju"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snimak ekrana"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Napravi izveštaj o grešci"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Ovim će se prikupiti informacije o trenutnom stanju uređaja kako bi bile poslate u poruci e-pošte. Od započinjanja izveštaja o grešci do trenutka za njegovo slanje proći će neko vreme; budite strpljivi."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv. izveštaj"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Koristite ovo u većini slučajeva. To vam omogućava da pratite napredak izveštaja, da unosite dodatne detalje o problemu i da snimate snimke ekrana. Verovatno će izostaviti neke manje korišćene odeljke za koje pravljenje izveštaja dugo traje."</string>
@@ -284,9 +287,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"pristupi lokaciji ovog uređaja"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Želite li da omogućite da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa lokaciji ovog uređaja?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplikacija će imati pristup lokaciji samo dok koristite aplikaciju."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Želite li da omogućite da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa lokaciji ovog uređaja?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplikacija će uvek imati pristup lokaciji, čak i kada ne koristite aplikaciju."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupi kalendaru"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Želite li da omogućite da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa kalendaru?"</string>
@@ -319,7 +325,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Želite li da omogućite da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa muzici?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Slike i video snimci"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"pristup slikama i video snimcima"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Želite li da dozvolite da „<xliff:g id="APP_NAME">%1$s</xliff:g>“ pristupa slikama i video snimcima, uključujući označene lokacije?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"da preuzima sadržaj prozora"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Proverava sadržaj prozora sa kojim ostvarujete interakciju."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"da uključi Istraživanja dodirom"</string>
@@ -512,8 +521,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Dozvoljava aplikaciji da komunicira sa oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogućavanje zaključavanja ekrana"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Dozvoljava aplikaciji da onemogući zaključavanje tastature i sve povezane bezbednosne mere sa lozinkama. Na primer, telefon onemogućava zaključavanje tastature pri prijemu dolaznog telefonskog poziva, a zatim ga ponovo omogućava po završetku poziva."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"traženje složenosti zaključavanja ekrana"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Dozvoljava aplikaciji da sazna nivo složenosti zaključavanja ekrana (visoka, srednja, niska ili nijedna), što ukazuje na mogući opseg trajanja i tip zaključavanja ekrana. Aplikacija može i da predlaže korisnicima da ažuriraju zaključavanje ekrana na određeni nivo, ali korisnici slobodno mogu da zanemare to i da idu na druge stranice. Imajte na umu da se podaci za zaključavanje ekrana ne čuvaju kao običan tekst, pa aplikacija ne zna tačnu lozinku."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"koristi biometrijski hardver"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Dozvoljava aplikaciji da koristi biometrijski hardver za potvrdu identiteta"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljaj hardverom za otiske prstiju"</string>
@@ -568,37 +579,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Dozvoljava da aplikacija aktivira metode za dodavanje i brisanje šablona lica radi korišćenja."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"korišćenje hardv. za potvrdu identiteta pomoću lica"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Dozvoljava da aplikacija koristi hardver za potvrdu identiteta pomoću lica"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Obrada lica nije uspela. Probajte ponovo."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Lice je presvetlo. Probajte sa slabijim osvetljenjem."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Lice je isuviše tamno. Otkrijte izvor svetla."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Udaljite senzor od lica."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Približite senzor licu."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Pomerite senzor naviše."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Pomerite senzor naniže."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Pomerite senzor udesno."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Pomerite senzor ulevo."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Gledajte u senzor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nije otkriveno nijedno lice."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Mnogo se pomerate."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Ponovo registrujte lice."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Otkriveno je drugo lice."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Previše je slično, promenite pozu."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Gledajte pravo u kameru."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Gledajte pravo u kameru."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Ispravite glavu."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Otkrijte lice."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Harvder za lice nije dostupan."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Isteklo je vreme za proveru lica. Probajte ponovo."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Nije moguće sačuvati lice."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Obrada lica je otkazana."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Korisnik je otkazao potvrdu lica."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Previše pokušaja. Probajte ponovo kasnije."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Više pokušaja. Potvrda identiteta je onemogućena."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Probajte ponovo."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nije registrovano nijedno lice."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Ovaj uređaj nema senzor za potvrdu identiteta pomoću lica."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1233,9 +1266,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Otvori <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> će se zatvoriti bez čuvanja"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> premašuje ograničenje memorije"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Snimak dinamičkog dela memorije je napravljen. Dodirnite za deljenje."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Želite li da delite snimak dinamičkog dela memorije?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> je premašio ograničenje memorije za proces od <xliff:g id="SIZE">%2$s</xliff:g>. Snimak dinamičkog dela memorije je dostupan i možete da ga delite sa programerom. Budite oprezni: ovaj snimak dinamičkog dela memorije može da sadrži neke lične podatke kojima aplikacija može da pristupa."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Izaberite radnju za tekst"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Jačina zvuka zvona"</string>
     <string name="volume_music" msgid="5421651157138628171">"Jačina zvuka medija"</string>
@@ -1276,8 +1316,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da biste videli sve mreže"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Wi‑Fi mreža koju predlaže <xliff:g id="NAME">%s</xliff:g> je dostupna"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Želite li da se povežete na mreže koje predlaže <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi će se automatski uključiti"</string>
@@ -1289,9 +1331,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijavite se na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi nema pristup internetu"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Dodirnite za opcije"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Povezano je"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Promene podešavanja za hotspot"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Opseg hotspota je promenjen."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Ovaj uređaj ne podržava podešavanje samo za 5 GHz. Uređaj će koristiti opseg od 5 GHz kada bude dostupan."</string>
@@ -1376,6 +1423,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka sa USB-a je omogućeno"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Dodirnite da biste isključili otklanjanje grešaka sa USB-a"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izaberite da biste onemogućili otklanjanja grešaka sa USB-a."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tečnost ili nečistoća u USB portu"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port je automatski isključen. Dodirnite da biste saznali više."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Korišćenje USB porta je bezbedno"</string>
@@ -1939,8 +1990,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Dodirom otklj. profil za Work"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Povezano je sa proizvodom <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dodirnite za pregled datoteka"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Zakači"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Otkači"</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Pokrećemo demonstraciju..."</string>
@@ -2032,6 +2081,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Obaveštenje o informacijama Rutinskog režima"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Baterija će se možda isprazniti pre uobičajenog punjenja"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Ušteda baterije je aktivirana da bi se produžilo trajanje baterije"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Direktorijum"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android aplikacija"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Datoteka"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 83b268a..18e345a 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -143,8 +143,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi-тэлефанія"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWi-Fi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Выкл."</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Прыярытэт Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Прыярытэт мабільнай сеткі"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Толькі Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не пераадрасоўваецца"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -232,7 +234,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Справаздача пра памылкі"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Скончыць сеанс"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Здымак экрана"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Справаздача пра памылку"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Будзе збiрацца iнфармацыя пра бягучы стан прылады, якая будзе адпраўляцца на электронную пошту. Стварэнне справаздачы пра памылкi зойме некаторы час."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Інтэрактыўная справаздача"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Выкарыстоўвайце ў большасці выпадкаў. Гэта дазваляе сачыць за ходам справаздачы, уводзіць дадатковыя звесткі аб праблеме і рабіць здымкі экрана. Могуць быць прапушчаны некаторыя раздзелы, якія выкарыстоўваюцца менш і паведамленне пра якія займае шмат часу."</string>
@@ -287,9 +290,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Месцазнаходжанне"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"атрымліваць доступ да месцазнаходжання гэтай прылады"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Дазволіць праграме &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ да звестак аб месцазнаходжанні гэтай прылады?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Праграма будзе мець доступ да звестак пра месцазнаходжанне, толькі калі яна выкарыстоўваецца."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Дазволіць праграме &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; мець доступ да месцазнаходжання?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Праграма заўсёды будзе мець доступ да звестак пра месцазнаходжанне, нават калі яна не выкарыстоўваецца."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Каляндар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"атрымліваць доступ да вашага календара"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Дазволіць праграме &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ да вашага календара?"</string>
@@ -322,7 +328,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Дазволіць праграме &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ да музыкі?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Фота і відэа"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"доступ да фота і відэа"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Дазволіць &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ да фота і відэа, у тым ліку з пазначаным месцам?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Атрымліваць змесціва вакна"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Аналізаваць змесціва актыўнага вакна."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Уключаць Азнаямленне дотыкам"</string>
@@ -515,8 +524,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Дазваляе прыкладаннzv спалучацца з тэгамі, картамі і счытваючымі прыладамі Near Field Communication (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"адключэнне блакiроўкi экрана"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Дазваляе прыкладанням адключаць блакiроўку клавіятуры і любыя сродкі абароны, звязаныя з паролем. Прыкладам гэтага з\'яўляецца адключэнне тэлефонам блакiроўкi клавіятуры пры атрыманні ўваходнага выкліку і паўторнае ўключэнне блакiроўкi клавіятуры, калі выклік завершаны."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"запытваць узровень складанасці блакіроўкі экрана"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Дазваляе праграме вызначаць узровень складанасці блакіроўкі экрана (высокі, сярэдні, нізкі ці нулявы), які залежыць ад даўжыні пароля і ад тыпу блакіроўкі экрана. Праграма можа прапанаваць карыстальнікам ускладніць блакіроўку экрана, аднак гэту прапанову можна ігнараваць. Заўважце, што праграма не можа ведаць тып і пароль блакіроўкі экрана, таму што яны захоўваюцца ў зашыфраваным выглядзе."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"выкарыстоўваць біяметрычнае абсталяванне"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Дазваляе праграме выкарыстоўваць для аўтэнтыфікацыі біяметрычнае абсталяванне"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"кіраваць апаратнымі сродкамі для адбіткаў пальцаў"</string>
@@ -571,37 +582,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Праграма зможа дадаваць і выдаляць шаблоны твару."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"карыстацца абсталяваннем для распазнавання твару"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Праграма зможа выкарыстоўваць абсталяванне распазнавання твару для аўтэнтыфікацыі"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Не ўдалося распазнаць твар. Паўтарыце спробу."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Твар занадта светлы. Паспрабуйце зменшыць святло."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Твар занадта цёмны. Павялічце асвятленне."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Перамясціце датчык далей ад твару."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Наблізьце датчык да твару."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Падыміце датчык вышэй."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Апусціце датчык ніжэй."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Перамясціце датчык управа."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Перамясціце датчык улева."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Глядзіце на датчык."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Твар не знойдзены."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Трымайце прыладу нерухома."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Паўтарыце рэгістрацыю твару."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Выяўлены іншы твар."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Не бачна розніцы. Памяняйце позу."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Глядзіце прама ў камеру."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Глядзіце прама ў камеру."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Выраўнуйце галаву."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Твар павінен быць добра бачны."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Абсталяванне для распазнавання твару недаступнае."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Час чакання твару выйшаў. Паўтарыце спробу."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Не ўдалося захаваць твар."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Распазнаванне твару скасавана."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Распазнаванне твару скасавана карыстальнікам."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Занадта шмат спроб. Паўтарыце спробу пазней."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Занадта шмат спроб. Аўтэнтыфікацыя твару адключана"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Паўтарыце спробу."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Твар не зарэгістраваны."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"На гэтай прыладзе адсутнічае датчык аўтэнтыфікацыі твару."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Твар <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1253,9 +1286,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Адкрыць праграму \"<xliff:g id="NEW_APP">%1$s</xliff:g>\""</string>
     <string name="new_app_description" msgid="5894852887817332322">"Праграма \"<xliff:g id="OLD_APP">%1$s</xliff:g>\" будзе закрыта. Даныя не будуць захаваны"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Працэс <xliff:g id="PROC">%1$s</xliff:g> перавысіў ліміт памяці"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Быў сабраны дамп кучы; абагульце дотыкам."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Абагуліць дамп дынамічнай вобласці?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Працэс <xliff:g id="PROC">%1$s</xliff:g> перавысіў ліміт памяці працэсу <xliff:g id="SIZE">%2$s</xliff:g>. Дамп дынамічнай вобласці даступны для вас, вы можаце абагуліць яго з распрацоўшчыкам. Будзьце асцярожныя: гэты дамп дынамічнай вобласці можа ўтрымліваць асабістую інфармацыю, да якой маюць доступ праграмы."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Выберыце дзеянне для тэкста"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Гучнасць званка"</string>
     <string name="volume_music" msgid="5421651157138628171">"Гучнасць прайгравальніка"</string>
@@ -1298,8 +1338,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Дакраніцеся, каб убачыць усе сеткі"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Падключыцца"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Усе сеткі"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Даступная сетка Wi‑Fi, прапанаваная праграмай <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Падключыцца да сетак, прапанаваных праграмай <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Так"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi уключыцца аўтаматычна"</string>
@@ -1311,9 +1353,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Увайдзіце ў сетку"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"У Wi-Fi няма доступу да інтэрнэту"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Дакраніцеся, каб убачыць параметры"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Падключана"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Змяненні ў наладах хот-спота"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Частата хот-спота змянілася."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Прылада не можа працаваць толькі на частаце 5 ГГц. Гэта частата будзе выкарыстоўвацца, калі гэта магчыма."</string>
@@ -1398,6 +1445,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Адладка па USB падключана"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Націсніце, каб адключыць адладку па USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Выберыце, каб адключыць адладку USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Вадкасць або смецце ў порце USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Порт USB аўтаматычна адключаны. Каб даведацца больш, націсніце тут."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Можна бяспечна выкарыстоўваць порт USB"</string>
@@ -1973,8 +2024,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Кран., каб разбл. раб. профіль"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Падлучана да <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Краніце для прагляду файлаў"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Замацаваць"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Адмацаваць"</string>
     <string name="app_info" msgid="6856026610594615344">"Інфармацыя пра праграму"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Ідзе запуск дэманстрацыі…"</string>
@@ -2067,6 +2116,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Апавяшчэнне з інфармацыяй пра ўсталяваны рэжым"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Акумулятар можа разрадзіцца хутчэй, чым прыйдзе час звычайнай зарадкі"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Каб павялічыць тэрмін работы акумулятара, уключаны рэжым эканоміі зараду"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Папка"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Праграма Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Файл"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index da29c0e..2311322 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Обаждания през Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Изключено"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Предпочита се Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Предпочитат се мобилни данни"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Само Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Не е пренасочено"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Сигнал за програмна грешка"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Прекратяване на сесията"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Екранна снимка"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Сигнал за програмна грешка"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"По този начин ще се събере информация за текущото състояние на устройството ви, която да се изпрати като имейл съобщение. След стартирането на процеса ще мине известно време, докато сигналът за програмна грешка бъде готов за подаване. Моля, имайте търпение."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивен сигнал"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Използвайте тази опция в повечето случаи. Тя ви позволява да следите напредъка на сигнала, да въвеждате допълнителни подробности за проблема и да правите екранни снимки. Възможно е да бъдат пропуснати някои по-рядко използвани секции, за които подаването на сигнал отнема дълго време."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Местоположение"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"получи достъп до местоположението на това устройство"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Да се разреши ли на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да осъществява достъп до местоположението на това устройство?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Само когато използвате приложението, то ще има достъп до местоположението."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Да се разреши ли на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; достъп до местопол. на у-вото?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Дори когато не използвате приложението, то винаги ще има достъп до местоположението."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"има достъп до календара ви"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Да се разреши ли на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да осъществява достъп до календара ви?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Да се разреши ли на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да осъществява достъп до музиката ви?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Снимки и видеоклипове"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"достъп до снимките и видеоклиповете ви"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Да се разреши ли на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; достъп до снимките и видеоклиповете ви, включително маркерите за местоположение?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Извличане на съдържанието от прозореца"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Инспектиране на съдържанието на прозорец, с който взаимодействате."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Включване на изследването чрез докосване"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Разрешава на приложението да комуникира с маркери, карти и четци, ползващи комуникация в близкото поле (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"деактивиране на заключването на екрана ви"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Разрешава на приложението да деактивира заключването на клавиатурата и свързаната защита с парола. Например телефонът деактивира заключването при получаване на входящо обаждане и после го активира отново, когато обаждането завърши."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"заявяване на сложност на опцията за заключване на екрана"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Разрешава на приложението да разбере нивото на сложност на опцията за заключване на екрана (високо, средно, ниско или липса на такова), което указва възможния диапазон на дължината и типа на опцията. Приложението може също да предложи на потребителите да актуализират опцията за заключване на екрана до определено ниво, но те могат да пренебрегнат това и да излязат от него. Обърнете внимание, че опцията за заключване на екрана не се съхранява като обикновен текст, така че приложението не знае точната парола."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"използване на хардуера за биометрични данни"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Разрешава на приложението да използва хардуера за биометрични данни с цел удостоверяване"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управление на хардуера за отпечатъци"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Разрешава на прил. да извиква методи за добавяне и изтриване на лицеви шаблони за ползване"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"използване на хардуера за удостоверяване с лице"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Разрешава на приложението при необходимост да използва хардуера за удостоверяване с лице"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Лицето не можа да се обработи. Опитайте отново."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Лицето е твърде осветено. Oпитайте на по-тъмно."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Лицето е твърде тъмно. Моля, осветете го по-добре."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Моля, отдалечете сензора от лицето си."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Моля, приближете сензора към лицето си."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Моля, повдигнете сензора."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Моля, преместете сензора надолу."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Моля, преместете сензора надясно."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Моля, преместете сензора наляво."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Моля, гледайте към сензора."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Не е открито лице."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Стабилизирайте устройството."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Моля, регистрирайте лицето си отново."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Разпознато е различно лице."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Позата ви е сходна с предишна. Моля, променете я."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Моля, гледайте по-директно към камерата."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Моля, гледайте по-директно към камерата."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Моля, изправете главата си."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Моля, открийте лицето си."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Няма достъп до хардуера за лице."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Времето за изчакване изтече. Опитайте отново."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Лицето не може да бъде съхранено."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Операцията с лице е анулирана."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Удостоверяв. на лицето е анулирано от потребителя."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Твърде много опити. Опитайте отново по-късно."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Твърде много опити. Удост. с лице е деактивирано."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Опитайте отново."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Няма регистрирано лице."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Това устройство няма сензор за удостоверяване с лице."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Отваряне на <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> ще се затвори без запазване"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> надхвърли ограничението за памет"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Извлечена е моментна снимка на паметта. Докоснете, за да я споделите."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Да се сподели ли моментната снимка на паметта?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Процесът <xliff:g id="PROC">%1$s</xliff:g> надхвърли ограничението си от <xliff:g id="SIZE">%2$s</xliff:g>. Налице е моментна снимка на паметта, която да споделите със съответния програмист. Бъдете внимателни, защото тя може да съдържа ваши лични данни, до които приложението има достъп."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Избиране на действие за текст"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Сила на звука при звънене"</string>
     <string name="volume_music" msgid="5421651157138628171">"Сила на звука"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Докоснете, за да видите всички мрежи"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Свързване"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Всички мрежи"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Налице е Wi‑Fi мрежа, предложена от <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Искате ли да се свържете с мрежите, предложени от <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ще се включи автоматично"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Вход в мрежата"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi мрежата няма достъп до интернет"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Докоснете за опции"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Установена е връзка"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Промени в настройките ви за точка за достъп"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Честотната лента на точката ви за достъп е променена."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Това устройство не поддържа предпочитанието ви за използване само на честотната лента от 5 ГХц. Вместо това то ще я ползва, когато е възможно."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Докоснете, за да изключите отстраняването на грешки през USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или замърсяване в USB порта"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портът е деактивиран автоматично. Докоснете, за да научите повече."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Безопасно е да използвате USB порта"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Докоснете за откл. на служ. потр. профил"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Установена е връзка с <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Докоснете, за да прегледате файловете"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Фиксиране"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Освобождаване"</string>
     <string name="app_info" msgid="6856026610594615344">"Информация за приложението"</string>
     <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Демонстрацията се стартира…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Известие с информация за режима на поредица"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Батерията може да се изтощи преди обичайното зареждане"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Режимът за запазване на батерията е активиран с цел удължаване на живота на батерията"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Папка"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Приложение за Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Файл"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index e0f866d..fc7022d 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"ওয়াই-ফাই কলিং"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"বন্ধ আছে"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"পছন্দের ওয়াই-ফাই"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"পছন্দের মোবাইল"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"শুধুমাত্র ওয়াই-ফাই"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ফরওয়ার্ড করা হয়নি"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ত্রুটির প্রতিবেদন"</string>
     <string name="global_action_logout" msgid="935179188218826050">"সেশন শেষ করুন"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"স্ক্রিনশট নিন"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"ত্রুটির অভিযোগ করুন"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"এটি একটি ই-মেল মেসেজ পাঠানোর জন্য আপনার ডিভাইসের বর্তমান অবস্থা সম্পর্কে তথ্য সংগ্রহ করবে৷ ত্রুটির প্রতিবেদন শুরুর সময় থেকে এটি পাঠানোর জন্য প্রস্তুত হতে কিছুটা সময় নেবে; অনুগ্রহ করে ধৈর্য রাখুন৷"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ইন্টারেক্টিভ প্রতিবেদন"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"বেশিরভাগ পরিস্থিতিতে এটিকে ব্যবহার করুন৷ এটি আপনাকে প্রতিবেদনের কাজ কতটা হয়েছে তার উপর নজর রাখতে দেয়, সমস্যাটির সম্পর্কে আরও অনেক কিছু লিখতে দেয় এবং স্ক্রীনশটগুলি নিতে দেয়৷ এটি হয়ত প্রতিবেদন করতে খুব বেশি সময় নেয় এমনকি কম-ব্যবহৃত বিভাগগুলি সরিয়ে দিতে পারে৷"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"লোকেশন"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"এই ডিভাইসের লোকেশন অ্যাক্সেস"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-কে এই ডিভাইসের লোকেশন অ্যাক্সেস করতে দেবেন?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"আপনি এই অ্যাপটি ব্যবহার করার সময়েই সেটি আপনার লোকেশন অ্যাক্সেস করতে পারবে।"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;কে সবসময় এই ডিভাইসের লোকেশন অ্যাক্সেস করতে দেবেন?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"এই অ্যাপটি সবসময় আপনার লোকেশন অ্যাক্সেস করতে পারবে, এমনকি আপনি অ্যাপটি ব্যবহার না করার সময়েও।"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ক্যালেন্ডার"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"আপনার ক্যালেন্ডারে অ্যাক্সেস"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-কে আপনার ক্যালেন্ডারে অ্যাক্সেস দেবেন?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-কে আপনার মিউজিকে অ্যাক্সেস দেবেন?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ফটো ও ভিডিও"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"আপনার ফটো ও ভিডিও অ্যাক্সেস করুন"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-কে ট্যাগ করা লোকেশন সহ ফটো এবং ভিডিও অ্যাক্সেস করার অনুমতি দেবেন?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"উইন্ডোর কন্টেন্ট পুনরুদ্ধার করে"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ব্যবহার করছেন এমন একটি উইন্ডোর কন্টেন্ট নিরীক্ষণ করে৷"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পর্শের মাধ্যমে অন্বেষণ করা চালু করুন"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"অ্যাপ্লিকেশানকে নিয়ার ফিল্ড কমিউনিকেশন (NFC) ট্যাগ, কার্ড এবং রিডারগুলির সাথে যোগাযোগ করতে দেয়৷"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"আপনার স্ক্রিন লক অক্ষম করুন"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"কী-লক এবং যেকোনো সংশ্লিষ্ট পাসওয়ার্ড সুরক্ষা অক্ষম করতে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷ উদাহরণস্বরূপ, একটি ইনকামিং ফোন কল গ্রহণ করার সময়ে ফোনটি কী-লক অক্ষম করে, তারপরে কল শেষ হয়ে গেলে কী-লকটিকে আবার সক্ষম করে৷"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"স্ক্রিন লকের জটিলতা জানার অনুরোধ করুন"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"এটি অ্যাপটিকে স্ক্রিন লকের জটিলতার লেভেল বুঝতে সাহায্য করে (খুব জটিল, মাঝারি ধরনের জটিল, অল্প জটিল বা কোনও জটিলতা নেই), যা স্ক্রিন লকটি সম্ভত কত দীর্ঘ ও সেটির ধরন কীরকম, তার ইঙ্গিত দেয়। একটি নির্দিষ্ট লেভেল পর্যন্ত স্ক্রিন লক আপডেট করা যাবে তাও এই অ্যাপটি সাজেস্ট করতে পারে, তবে ব্যবহারকারীর তা উপেক্ষা করার এবং অন্য কোথাও চলে যাওয়ার স্বাধীনতা আছে। লক্ষ্য করবেন, স্ক্রিন লকটি যেহেতু প্লেন টেক্সট ফর্ম্যাটে স্টোর করা হয় না, তাই সঠিক পাসওয়ার্ডটি অ্যাপের পক্ষে জানা সম্ভব নয়।"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"বায়োমেট্রিক হার্ডওয়্যার ব্যবহার করুন"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"অ্যাপটিকে যাচাইকরণের জন্য বায়োমেট্রিক হার্ডওয়্যার ব্যবহার করার অনুমতি দেয়"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"আঙ্গুলের ছাপ নেওয়ার হার্ডওয়্যার পরিচালনা করুন"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ব্যবহার করার জন্য ফেস টেম্পলেট যোগ করা এবং মোছার পদ্ধতি গ্রহণ করতে অ্যাপটিকে অনুমতি দেয়৷"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"ফেস যাচাইকরণ হার্ডওয়্যার ব্যবহার করুন"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"প্রমাণীকরণের জন্য ফেস যাচাইকরণ হার্ডওয়্যার ব্যবহার করার অনুমতি অ্যাপটিকে দেয়"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"ফেস প্রক্রিয়া করা যায়নি৷ আবার চেষ্টা করুন৷"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"ফেসটি খুব উজ্জ্বল লাগছে। কম আলোতে চেষ্টা করুন।"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"ফেসটি খুব অন্ধকার লাগছে। বেশি আলোতে চেষ্টা করুন।"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"অনুগ্রহ করে ফেস থেকে সেন্সরটি দূরে সরান।"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"অনুগ্রহ করে ফেসের কাছাকাছি সেন্সরটি আনুন।"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"অনুগ্রহ করে সেন্সরটি উঁচুতে নিয়ে যান।"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"অনুগ্রহ করে সেন্সরটি নিচে নিয়ে যান।"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"অনুগ্রহ করে সেন্সরটি ডান দিকে নিয়ে যান।"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"অনুগ্রহ করে সেন্সরটি বাঁ দিকে নিয়ে যান।"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"অনুগ্রহ করে সেন্সরের দিকে তাকান।"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"কোনও ফেস শনাক্ত করা যায়নি।"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"খুব বেশি নড়ছে।"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"আপনার মুখের ছবি আবার নথিভুক্ত করুন।"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"বিভিন্ন ব্যক্তির মুখের ছবি শনাক্ত করা হয়েছে।"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"একই ধরনের দেখতে, একটু অন্যদিকে ঘুরে দাঁড়ান।"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"সরাসরি ক্যামেরার দিকে তাকান।"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"সরাসরি ক্যামেরার দিকে তাকান।"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"মাথা সোজা করে রাখুন।"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"আপনার মুখটা আলোর দিকে নিয়ে আসুন।"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"ফেসের হার্ডওয়্যার উপলভ্য নয়৷"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"ফেসের ছাপ নেওয়ার সময়সীমা শেষ৷ আবার চেষ্টা করুন৷"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"ফেস স্টোর করা যাবে না।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ফেস অপারেশন বাতিল করা হয়েছে৷"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"ফেস যাচাইকরণ ব্যবহারকারীর দ্বারা বাতিল করা হয়েছে।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"অনেকবার চেষ্টা করা হয়েছে। পরে আবার চেষ্টা করুন।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"অনেকবার চেষ্টা করা হয়েছে৷ ফেস যাচাইকরণ বন্ধ আছে।"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"আবার চেষ্টা করুন।"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"কোনও ফেস নথিভুক্ত করা হয়নি।"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"এই ডিভাইসের ফেস যাচাইকরণ সেন্সর নেই।"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> ফেস"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> খুলুন"</string>
     <string name="new_app_description" msgid="5894852887817332322">"সেভ না করেই <xliff:g id="OLD_APP">%1$s</xliff:g> বন্ধ হবে"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> মেমরি সীমা অতিক্রম করেছে"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"হিপ ডাম্প সংগ্রহ করা হয়েছে। শেয়ার করতে ট্যাপ করুন।"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"হিপ ডাম্প শেয়ার করবেন?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> প্রক্রিয়াটি তার <xliff:g id="SIZE">%2$s</xliff:g> এর মেমরি সীমা অতিক্রম করেছে৷ তার ডেভেলপারের সাথে শেয়ার করার জন্য একটি হিপ ডাম্প উপলব্ধ৷ সতর্কতা অবলম্বন করুন: এই হিপ ডাম্পে অ্যাপ্লিকেশানটির অ্যাক্সেস আছে এমন আপনার যেকোন ব্যক্তিগত তথ্য থাকতে পারে৷"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"পাঠ্যের জন্য একটি কাজ বেছে নিন"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"রিং ভলিউম"</string>
     <string name="volume_music" msgid="5421651157138628171">"মিডিয়ার ভলিউম"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সমস্ত নেটওয়ার্ক দেখতে ট্যাপ করুন"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযুক্ত করুন"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"সব নেটওয়ার্ক"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g>-এর সাজেস্ট করা ওয়াই-ফাই নেটওয়ার্ক এখন উপলভ্য"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"আপনি কি <xliff:g id="NAME">%s</xliff:g>-এর সাজেস্ট করা নেটওয়ার্ক দিয়ে কানেক্ট করতে চান?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"হ্যাঁ"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"না"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ওয়াই-ফাই অটোমেটিক চালু হবে"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"নেটওয়ার্কে সাইন-ইন করুন"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"ওয়াই-ফাই এ ইন্টারনেট অ্যাক্সেস নেই"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"বিকল্পগুলির জন্য আলতো চাপুন"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"কানেক্ট করা হয়েছে"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"আপনার হটস্পট সেটিংসে পরিবর্তনগুলি"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"আপনার হটস্পট ব্যান্ড পরিবর্তন করা হয়েছে।"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"এই ডিভাইসটি শুধুমাত্র 5GHz এর জন্য আপনার পছন্দ সমর্থন করে না। পরিবর্তে, এই ডিভাইসটি 5GHz ব্যান্ড ব্যবহার করবে।"</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"ইউএসবি ডিবাগিং বন্ধ করতে ট্যাপ করুন"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ডিবাগিং অক্ষম করতে বেছে নিন।"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএসবি পোর্টে তরল পদার্থ অথবা ধুলো কণা"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএসবি পোর্ট নিজে থেকে বন্ধ করা হবে। আরও জানতে ট্যাপ করুন।"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"ইউএসবি পোর্ট এখন ব্যবহার করতে পারবেন"</string>
@@ -1397,8 +1448,7 @@
     <string name="ext_media_init_action" msgid="7952885510091978278">"সেট আপ করুন"</string>
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"বের করে নিন"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"ঘুরে দেখুন"</string>
-    <!-- no translation found for ext_media_seamless_action (6575980560886881233) -->
-    <skip />
+    <string name="ext_media_seamless_action" msgid="6575980560886881233">"আউটপুট পাল্টান"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> অনুপস্থিত"</string>
     <string name="ext_media_missing_message" msgid="4012389235250987930">"ডিভাইসটি আবার ঢোকান"</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> সরানো হচ্ছে"</string>
@@ -1907,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"কর্মস্থলের প্রোফাইল আনলক করতে আলতো চাপ দিন"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> এর সাথে সংযুক্ত হয়েছে"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ফাইলগুলি দেখতে আলতো চাপ দিন"</string>
-    <string name="pin_target" msgid="3052256031352291362">"পিন করুন"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"আনপিন করুন"</string>
     <string name="app_info" msgid="6856026610594615344">"অ্যাপের তথ্য"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ডেমো শুরু করা হচ্ছে…"</string>
@@ -1999,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"রুটিন মোডের তথ্য সংক্রান্ত বিজ্ঞপ্তি"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"সাধারণত যখন চার্জ দেন, তার আগে চার্জ শেষ হয়ে যেতে পারে"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"ডিভাইস বেশিক্ষণ চালু রাখতে ব্যাটারি সেভার চালু করা হয়েছে"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ফোল্ডার"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android অ্যাপ্লিকেশন"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ফাইল"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index a78796f..1d5a7d8 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -142,8 +142,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Pozivanje putem WIFi-ja"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferira se WiFi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferira se mobilna mreža"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo WiFi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije proslijeđen"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -230,7 +232,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izvještaj o greškama"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Završi sesiju"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snimak ekrana"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Kreiranje izvještaja o greškama"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Ovim će se prikupljati informacije o trenutnom stanju uređaja, koji će biti poslani kao e-poruka. Može malo potrajati dok se izvještaj o greškama ne kreira i bude spreman za slanje. Budite strpljivi."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktivni izvještaj"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Koristite ovu opciju u većini slučajeva. Ova opcija vam omogućava praćenje napretka izvještaja, unos dodatnih detalja o problemu i pravljenje snimaka ekrana. Moglo bi doći do izostavljanja nekih manje korištenih dijelova za čije prijavljivanje je potrebno dugo vremena."</string>
@@ -284,9 +287,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"pristupa lokaciji ovog uređaja"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristup lokaciji ovog uređaja?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Ova aplikacija će moći pristupiti lokaciji uređaja samo kada je koristite."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Uvijek dozvoliti da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupi lokaciji uređaja?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Ova aplikacija će uvijek moći pristupiti lokaciji uređaja, čak i kada je ne koristite."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupa vašem kalendaru"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupi vašem kalendaru?"</string>
@@ -319,7 +325,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;da pristupi vašoj muzici?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotografije i videozapisi"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"pristup fotografijama i videozapisima"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Dozvoliti da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa fotografijama i videozapisima, uključujući označene lokacije?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Preuzima sadržaj prozora"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Pregleda sadržaj prozora koji trenutno koristite."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključi opciju Istraživanje dodirom"</string>
@@ -512,8 +521,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Dozvoljava aplikaciji komuniciranje sa NFC (komunikacija bliskog polja) oznakama, karticama i čitačima."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivacija zaključavanja ekrana"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Omogućava aplikaciji deaktivaciju zaključane tastature i svih povezanih zaštita. Naprimjer, telefon deaktivira zaključavanje tastature kod dolaznog telefonskog poziva, a zatim ponovo aktivira zaključavanje tastature kada je poziv završen."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"zahtjev za kompleksnost zaključavanja ekrana"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Omogućava aplikaciji da sazna nivo kompleksnosti zaključavanja ekrana (visoki, srednji, niski ili bez zaključavanja), što naznačava mogući raspon trajanja i vrste zaključavanja ekrana. Aplikacija također može korisnicima predložiti da ažuriraju zaključavanje ekrana do određenog nivoa ali korisnici slobodno mogu ignorirati prijedlog i napustiti stranicu. Važno je napomenuti da se zaključavanje ekrana ne pohranjuje kao obični tekst tako da aplikacija ne zna tačnu lozinku."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"koristi biometrijski hardver za otiske prstij"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Omogućava aplikaciji da za autentifikaciju koristi biometrijski hardver"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljanje hardverom za otiske prstiju"</string>
@@ -568,37 +579,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Omogućava aplikaciji korištenje metoda za dodavanje i brisanje šablona lica za upotrebu."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"upotreba hardvera za autentifikaciju licem"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Omogućava aplikaciji da za autentifikaciju koristi hardver za autentifikaciju licem"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Obrada lica nije uspjela. Pokušajte ponovo."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Lice je presvijetlo. Pokušajte s manje svjetla."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Lice je pretamno. Pojačajte izvor svjetlosti."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Odmaknite senzor od lica."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Približite senzor licu."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Pomjerite senzor prema gore."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Pomjerite senzor prema dolje."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Pomjerite senzor udesno."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Pomjerite senzor ulijevo."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Gledajte u senzor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nije pronađeno nijedno lice."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Previše pokreta."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Ponovo registrirajte lice."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Otkriveno je lice koje nije vaše."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Previše slično, promijenite položaj."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Gledajte direktno u kameru."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Gledajte direktno u kameru."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Poravnajte položaj glave vertikalno."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Otkrijte lice."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardver za prepoznavanje lica nije dostupan."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Vrijeme za prepoznavanje lica je isteklo. Pokušajte ponovo."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Nije moguće pohraniti lice."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Prepoznavanje lica je otkazano."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Korisnik je otkazao provjeru lica."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Previše pokušaja. Autentifikacija lica onemogućena."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Pokušajte ponovo."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nije prijavljeno nijedno lice."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Ovaj uređaj nema senzor za autentifikaciju lica."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1235,9 +1268,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Otvori aplikaciju <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"Aplikacija <xliff:g id="OLD_APP">%1$s</xliff:g> će se zatvoriti bez pohranjivanja"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> premašuje ograničenje memorije"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Snimak dinamičkog stanja memorije je napravljen. Dodirnite za dijeljenje."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Želite li dijeliti snimak dinamičkog dijela memorije?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> je premašio ograničenje procesne memorije od <xliff:g id="SIZE">%2$s</xliff:g>. Snimak dinamičkog dijela memorije vam je dostupan i možete ga dijeliti sa njegovim programerom. Budite oprezni: ovaj snimak dinamičkog dijela memorije može sadržavati vaše lične podatke kojima aplikacija ima pristup."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Biranje akcije za tekst"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Jačina zvuka zvona"</string>
     <string name="volume_music" msgid="5421651157138628171">"Jačina zvuka medija"</string>
@@ -1278,8 +1318,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da vidite sve mreže"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Povežite se"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"WiFi mreža koju je predložila aplikacija <xliff:g id="NAME">%s</xliff:g> je dostupna"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Želite li se povezati na mreže koje je predložila aplikacija <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi veza će se automatski uključiti"</string>
@@ -1291,9 +1333,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"WiFi nema pristup internetu"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Dodirnite za opcije"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Povezano"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Promjene postavki vaše pristupne tačke"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Opseg vaše pristupne tačke je promijenjen."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Ovaj uređaj ne podržava vašu postavku za mreže od isključivo 5GHz. Uređaj će koristiti opseg of 5GHz kada je dostupan."</string>
@@ -1378,6 +1425,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka putem uređaja spojenog na USB je uspostavljeno"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Dodirnite da isključite otklanjanje grešaka putem USB-a"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da onemogućite ispravljanje grešaka koristeći USB"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tečnost ili nečistoće u USB priključku"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB priključak je automatski onemogućen. Dodirnite da saznate više."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB priključak je sada sigurno koristiti"</string>
@@ -1941,8 +1992,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Dodirnite da biste otključali radni profil"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Povezan na uređaj <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dodirnite za prikaz fajlova"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Zakači"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Otkači"</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Pokretanje demonstracije…"</string>
@@ -2034,6 +2083,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Obavještenje za informacije Rutinskog načina"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Moguće je da će se baterija isprazniti prije uobičajenog punjenja"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Ušteda baterije je aktivirana da bi se produžio vijek trajanja baterije"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folder"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android aplikacija"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fajl"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index be2c0de..a0e3e21 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -143,8 +143,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Volání přes WiFi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Vypnuto"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferována síť W-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferována mobilní data"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Pouze Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nepřesměrováno"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -232,7 +234,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Hlášení chyb"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Ukončit relaci"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snímek obrazovky"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Vytvořit chybové hlášení"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Shromažďuje informace o aktuálním stavu zařízení. Tyto informace je následně možné poslat v e-mailové zprávě, chvíli však potrvá, než bude hlášení o chybě připraveno k odeslání. Buďte prosím trpěliví."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktivní přehled"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Tato možnost se používá ve většině případů. Umožňuje sledovat průběh přehledu, zadat další podrobnosti o problému a pořizovat snímky obrazovky. Mohou být vynechány některé méně používané sekce, jejichž kontrola trvá dlouho."</string>
@@ -287,9 +290,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Poloha"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"přístup k poloze tohoto zařízení"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; přístup k poloze tohoto zařízení?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplikace bude mít přístup k poloze, pouze když ji budete používat."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; přístup k poloze tohoto zařízení?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplikace bude mít přístup k poloze vždy, i když ji nebudete používat."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendář"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"přístup ke kalendáři"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; přístup ke kalendáři?"</string>
@@ -322,7 +328,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; přístup k hudbě?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotky a videa"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"přístup k fotkám a videím"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; přístup k fotkám a videím včetně označených míst?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Načítat obsah oken"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Může prozkoumávat obsah oken, se kterými pracujete."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Zapnout funkci Prozkoumání dotykem"</string>
@@ -400,13 +409,13 @@
     <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Umožňuje aplikaci odesílat trvalá vysílání, která přetrvávají i po skončení vysílání. Nadměrné používání může televizi zpomalit či způsobit její nestabilitu, protože bude používat příliš mnoho paměti."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Umožňuje aplikaci odesílat trvalá vysílání, která přetrvávají i po skončení vysílání. Nadměrné používání může telefon zpomalit či způsobit jeho nestabilitu, protože bude používat příliš mnoho paměti."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"čtení kontaktů"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Umožňuje aplikaci číst údaje o kontaktech uložených v tabletu, včetně toho, jak často voláte, posíláte e-maily nebo jinak komunikujete s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
-    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Umožňuje aplikaci číst údaje o kontaktech uložených v televizi včetně toho, jak často voláte, posíláte e-maily nebo jinými způsoby komunikujete s konkrétními kontakty. Toto oprávnění umožňuje aplikacím ukládat údaje o vašich kontaktech a škodlivé aplikace mohou sdílet údaje o kontaktech bez vašeho vědomí."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Umožňuje aplikaci číst údaje o kontaktech uložených v telefonu, včetně toho, jak často voláte, posíláte e-maily nebo komunikujete jinými způsoby s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Umožňuje aplikaci číst údaje o kontaktech uložených v tabletu, včetně toho, jak často voláte, posíláte e‑maily nebo jinak komunikujete s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Umožňuje aplikaci číst údaje o kontaktech uložených v televizi včetně toho, jak často voláte, posíláte e‑maily nebo jinými způsoby komunikujete s konkrétními kontakty. Toto oprávnění umožňuje aplikacím ukládat údaje o vašich kontaktech a škodlivé aplikace mohou sdílet údaje o kontaktech bez vašeho vědomí."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Umožňuje aplikaci číst údaje o kontaktech uložených v telefonu, včetně toho, jak často voláte, posíláte e‑maily nebo komunikujete jinými způsoby s konkrétními osobami. Toto oprávnění umožňuje aplikacím ukládat údaje o kontaktech. Škodlivé aplikace mohou tyto údaje bez vašeho vědomí sdílet."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"úprava kontaktů"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Umožňuje aplikaci upravit údaje o kontaktech uložených v tabletu včetně toho, jak často voláte, posíláte e-maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
-    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Umožňuje aplikaci upravit údaje o kontaktech uložených v televizi včetně toho, jak často voláte, posíláte e-maily nebo jinými způsoby komunikujete s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Umožňuje aplikaci upravit údaje o kontaktech uložených v telefonu včetně toho, jak často voláte, posíláte e-maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Umožňuje aplikaci upravit údaje o kontaktech uložených v tabletu včetně toho, jak často voláte, posíláte e‑maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
+    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Umožňuje aplikaci upravit údaje o kontaktech uložených v televizi včetně toho, jak často voláte, posíláte e‑maily nebo jinými způsoby komunikujete s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Umožňuje aplikaci upravit údaje o kontaktech uložených v telefonu včetně toho, jak často voláte, posíláte e‑maily nebo komunikujete jinými způsoby s konkrétními kontakty. Toto oprávnění aplikacím umožňuje mazat údaje o kontaktech."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"čtení seznamu hovorů"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"Tato aplikace může číst historii volání."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"zápis do seznamu hovorů"</string>
@@ -515,8 +524,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Umožňuje aplikaci komunikovat se štítky, kartami a čtečkami s podporou technologie NFC."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"vypnutí zámku obrazovky"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Umožňuje aplikaci vypnout zámek kláves a související zabezpečení heslem. Telefon například vypne zámek klávesnice při příchozím hovoru a po skončení hovoru jej zase zapne."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"zjištění složitosti zámku obrazovky"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Umožňuje aplikaci zjistit úroveň složitosti zámku obrazovky (vysoká, střední, nízká nebo žádná), která ukazuje možnou délku a typ zámku obrazovky. Aplikace také může uživatelům navrhovat, aby zámek obrazovky upravili na určitou úroveň, ale uživatelé mohou návrhy klidně ignorovat a odejít. Zámek obrazovky není uložen jako prostý text, a tak aplikace přesné heslo nezná."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"použití biometrického hardwaru"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Umožňuje aplikaci použít k ověření biometrický hardware"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"správa hardwaru na čtení otisků prstů"</string>
@@ -571,37 +582,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Umožňuje aplikaci volat metody k přidání a smazání šablon obličeje, které budou použity."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"použití hardwaru k ověření obličeje"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Umožňuje aplikaci provést ověření pomocí hardwaru k ověření obličeje"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Zpracování obličeje se nezdařilo. Zkuste to znovu."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Obličej je moc jasný. Zkuste to v menším světle."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Obličej je moc tmavý. Odkryjte zdroj světla."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Oddalte senzor od obličeje."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Posuňte senzor blíž k obličeji."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Posuňte senzor výš."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Posuňte senzor níž."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Posuňte senzor doprava."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Posuňte senzor doleva."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Podívejte se do senzoru."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nebyl rozpoznán žádný obličej."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Příliš mnoho pohybu."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Zaznamenejte obličej znovu."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Byl rozpoznán jiný obličej."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Příliš podobné, změňte výraz."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Dívejte se přímo na fotoaparát."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Dívejte se přímo na fotoaparát."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Narovnejte hlavu."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Odhalte obličej."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Není k dispozici hardware ke snímání obličeje."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Limit ověření obličeje vypršel. Zkuste to znovu."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Obličej nelze uložit."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operace snímání obličeje byla zrušena."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Ověření obličeje bylo zrušeno uživatelem."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Příliš mnoho pokusů. Zkuste to později."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Příliš mnoho pokusů. Ověření obličeje je zakázáno."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Zkuste to znovu."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Není zaregistrován žádný obličej."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Toto zařízení nemá snímač ověření obličeje."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Obličej <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1253,9 +1286,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Otevřít aplikaci <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"Aplikace <xliff:g id="OLD_APP">%1$s</xliff:g> se zavře bez uložení"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> překročil limit paměti"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Byl shromážděn výpis haldy. Klepnutím jej můžete sdílet."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Sdílet výpis haldy?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> překročil limit paměti procesu <xliff:g id="SIZE">%2$s</xliff:g>. Je k dispozici výpis haldy, který můžete sdílet s vývojářem. Buďte opatrní, výpis haldy může obsahovat osobní údaje, ke kterým má aplikace přístup."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Vyberte akci pro text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Hlasitost vyzvánění"</string>
     <string name="volume_music" msgid="5421651157138628171">"Hlasitost médií"</string>
@@ -1298,8 +1338,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všechny sítě"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Připojit"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Všechny sítě"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Je k dispozici síť Wi‑Fi navrhovaná aplikací <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Chcete se připojit k sítím, které navrhuje aplikace <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ano"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi se zapne automaticky"</string>
@@ -1311,9 +1353,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Přihlásit se k síti"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi nemá přístup k internetu"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Klepnutím zobrazíte možnosti"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Připojeno"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Změny nastavení hotspotu"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Pásmo hotspotu se změnilo."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Toto zařízení nepodporuje vaše nastavení jen 5GHz pásma. Zařízení použije pásmo 5 GHz, jen když bude dostupné."</string>
@@ -1398,6 +1445,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes USB připojeno"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Klepnutím vypnete ladění přes USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění přes USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Kapalina nebo nečistota v portu USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB byl automaticky deaktivován. Klepnutím zobrazíte další informace."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Port USB lze bezpečně použít"</string>
@@ -1973,8 +2024,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Klepnutím jej odemknete"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Připojeno k zařízení <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Klepnutím zobrazíte soubory"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Připnout"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Odepnout"</string>
     <string name="app_info" msgid="6856026610594615344">"O aplikaci"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Spouštění ukázky…"</string>
@@ -2067,6 +2116,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Informační oznámení režimu sledu činností"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Baterie se možná vybije před obvyklým časem nabití"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Byl aktivován spořič baterie za účelem prodloužení výdrže"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Složka"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplikace pro Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Soubor"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 4a30a4d..80256ee 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi-opkald"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Fra"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"WiFi-netværk er foretrukket"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobildata foretrækkes"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Kun Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Ikke viderestillet"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Fejlrapport"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Afslut sessionen"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Lav fejlrapport"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Der indsamles oplysninger om din enheds aktuelle status, der efterfølgende sendes i en mail. Der går lidt tid, fra fejlrapporten påbegyndes, til den er klar til at blive sendt. Tak for tålmodigheden."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv rapport"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Brug dette workflow under de fleste omstændigheder. Det giver dig mulighed for at se status på rapporten, angive flere oplysninger om problemet og tage screenshots. Nogle mindre brugte sektioner, der tager lang tid at rapportere, udelades muligvis."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Placering"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"få adgang til enhedens placering"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vil du give &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; adgang til enhedens placering?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Appen har kun adgang til placeringen, når du bruger appen."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Skal &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; altid have adgang til enhedens placering?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Appen har altid adgang til placeringen, også selvom du ikke bruger appen."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"have adgang til din kalender"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vil du give &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; adgang til din kalender?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Vil du give &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; adgang til din musik?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Billeder og videoer"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"adgang til dine billeder og videoer"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Vil du give &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; adgang til dine billeder og videoer, herunder taggede placeringer?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Hente indholdet i vinduet"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Undersøge indholdet i et vindue, du interagerer med."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivere Udforsk ved berøring"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Tillader, at appen kan kommunikere med NFC-tags (Near Field Communication), -kort og -læsere."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivere din skærmlås"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Tillader, at appen kan deaktivere tastaturlåsen og anden form for tilknyttet adgangskodesikkerhed. Telefonen deaktiverer f.eks. tastaturlåsen ved indgående telefonopkald og aktiverer tastaturlåsen igen, når opkaldet er afsluttet."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"anmode om skærmlåsens kompleksitet"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Giver appen tilladelse til at kende skærmlåsens kompleksitet (høj, medium, lav eller ingen), hvilket kan afsløre oplysninger om skærmlåsens længde og type. Appen kan også foreslå brugerne at opdatere deres skærmlås til et bestemt niveau, men brugerne kan frit ignorere det og gå videre. Bemærk! Skærmlåsen gemmes ikke som almindelig tekst, så appen kender ikke adgangskoden."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"brug biometrisk hardware"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Tillader, at appen kan bruge biometrisk hardware til godkendelse"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"administrer fingeraftrykhardware"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Tillader, at appen kan bruge metoder til at tilføje og slette ansigtsskabeloner."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"brug hardware til ansigtsgenkendelse"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Tillader, at appen bruger ansigtsgenkendelseshardware til godkendelse"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Ansigtet kunne ikke behandles. Prøv igen."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Ansigtet er for lyst. Prøv i svagere belysning."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Ansigtet er for mørkt. Ryk tættere på en lyskilde."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Flyt sensoren længere væk fra ansigtet."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Ryk sensoren tættere på ansigtet."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Flyt sensoren højere op."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Flyt sensoren længere ned."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Flyt sensoren til højre."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Flyt sensoren til venstre."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Kig på sensoren."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Der er ikke registreret noget ansigt."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Der er for meget bevægelse."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registrer dit ansigt igen."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Der blev registreret et andet ansigt."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Det minder for meget om et andet. Skift stilling."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Kig mere direkte ind i kameraet."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Kig mere direkte ind i kameraet."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Hold hovedet helt lodret."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Sørg for, at ansigtet ikke er dækket til."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardwaren til ansigtsregistrering er ikke klar."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Ansigtsgenkendelse fik timeout. Prøv igen."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Ansigtet kan ikke gemmes."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Ansigtshandlingen blev annulleret."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Ansigtsgodkendelsen blev annulleret af brugeren."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Du har prøvet for mange gange. Prøv igen senere."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"For mange forsøg – Ansigtsgenkendelse deaktiveret."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Prøv igen."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Der er ikke registreret nogen ansigter."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Denne enhed har ingen sensor til ansigtsgenkendelse."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Ansigt <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Åbn <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> lukkes uden at gemme"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> har overskredet sin hukommelsesgrænse"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Der er indsamlet en heap dump. Tryk for at dele."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vil du dele en heap dump?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Processen <xliff:g id="PROC">%1$s</xliff:g> har overskredet sin proceshukommelsesgrænse på <xliff:g id="SIZE">%2$s</xliff:g>. En heap dump er tilgængelig og kan deles med udvikleren. Vær forsigtig: Denne heap dump kan indeholde dine personlige oplysninger, som appen har adgang til."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Vælg en handling for teksten"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Lydstyrke for opkald"</string>
     <string name="volume_music" msgid="5421651157138628171">"Lydstyrke for medier"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryk for at se alle netværk"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Opret forbindelse"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netværk"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> har foreslået et tilgængeligt Wi-Fi-netværk"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Vil du oprette forbindelse til netværk, som <xliff:g id="NAME">%s</xliff:g> foreslår?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nej"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi aktiveres automatisk"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Log ind på netværk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi-netværket har ikke internetadgang"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tryk for at se valgmuligheder"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Der er oprettet forbindelse"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Ændringer af dine indstillinger for hotspot"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Dit hotspotbånd er ændret."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Denne enhed understøtter ikke din præference om kun 5 GHz. Denne enhed vil i stedet bruge 5 GHz-båndet, når det er muligt."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tryk for at deaktivere USB-fejlretning"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Væske eller snavs i USB-porten"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten deaktiveres automatisk. Tryk for at få flere oplysninger."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Det er sikkert at bruge USB-porten"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Tryk for at låse profilen op"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Tilsluttet <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tryk for at se filer"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Fastgør"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Frigør"</string>
     <string name="app_info" msgid="6856026610594615344">"Appinfo"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starter demoen…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notifikation med oplysninger om rutinetilstand"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Enheden løber muligvis tør for batteri, inden du normalt oplader den"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Batterisparefunktion er aktiveret for at forlænge batteritiden"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Mappe"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android-app"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fil"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index f4f7918..5381511 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Κλήση Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Ανενεργό"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Προτίμηση Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Προτίμηση δικτύου κινητής τηλεφωνίας"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Μόνο Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Δεν προωθήθηκε"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Αναφορά σφαλμάτων"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Λήξη περιόδου σύνδεσης"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Στιγμιότυπο οθόνης"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Λήψη αναφοράς σφάλματος"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Θα συλλέξει πληροφορίες σχετικά με την τρέχουσα κατάσταση της συσκευής σας και θα τις στείλει μέσω μηνύματος ηλεκτρονικού ταχυδρομείου. Απαιτείται λίγος χρόνος για τη σύνταξη της αναφοράς σφάλματος και την αποστολή της. Κάντε λίγη υπομονή."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Διαδραστική αναφορά"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Χρησιμοποιήστε αυτήν την επιλογή στις περισσότερες περιπτώσεις. Σας επιτρέπει να παρακολουθείτε την πρόοδο της αναφοράς, να εισάγετε περισσότερες λεπτομέρειες σχετικά με το πρόβλημα που αντιμετωπίζετε και να τραβήξετε στιγμιότυπα οθόνης. Ενδέχεται να παραλείψει ορισμένες ενότητες που δεν χρησιμοποιούνται συχνά και για τις οποίες απαιτείται μεγάλο χρονικό διάστημα για τη δημιουργία αναφορών."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Τοποθεσία"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"έχει πρόσβαση στην τοποθεσία της συσκευής"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να έχει πρόσβαση στην τοποθεσία αυτής της συσκευής;"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Η εφαρμογή θα έχει πρόσβαση στην τοποθεσία μόνο κατά τη διάρκεια χρήσης της εφαρμογής."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Να επιτρέπεται πάντα στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να έχει πρόσβαση στην τοποθεσία αυτής της συσκευής;"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Η εφαρμογή θα έχει πάντα πρόσβαση στην τοποθεσία, ακόμα και όταν δεν χρησιμοποιείτε την εφαρμογή."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Ημερολόγιο"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"έχει πρόσβαση στο ημερολόγιό σας"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να έχει πρόσβαση στο ημερολόγιό σας;"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να έχει πρόσβαση στη μουσική σας;"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Φωτογραφίες και βίντεο"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"πρόσβαση στις φωτογραφίες και στα βίντεό σας"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Να επιτρέπεται η πρόσβαση του &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; σε φωτογραφίες και βίντεο, μεταξύ άλλων σε επισημασμένες τοποθεσίες;"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ανάκτηση του περιεχομένου του παραθύρου"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Έλεγχος του περιεχομένου ενός παραθύρου με το οποίο αλληλεπιδράτε."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ενεργοποίηση της \"Εξερεύνησης με άγγιγμα\""</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Επιτρέπει στην εφαρμογή την επικοινωνία με ετικέτες, κάρτες και αναγνώστες της Επικοινωνίας κοντινού πεδίου (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"απενεργοποιεί το κλείδωμα οθόνης"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Επιτρέπει στην εφαρμογή την απενεργοποίηση του κλειδώματος πληκτρολογίου και άλλης σχετικής ασφάλειας με κωδικό πρόσβασης. Για παράδειγμα, το κλείδωμα πληκτρολογίου στο τηλέφωνο απενεργοποιείται όταν λαμβάνεται εισερχόμενη τηλεφωνική κλήση και ενεργοποιείται ξανά όταν η κλήση τερματιστεί."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"υποβολή αιτήματος για πολυπλοκότητα οθόνης κλειδώματος"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Επιτρέπει στην εφαρμογή να μάθει το επίπεδο πολυπλοκότητας του κλειδώματος οθόνης (υψηλό, μέσο, χαμηλό ή κανένα), το οποίο υποδεικνύει το πιθανό εύρος του μήκους και του τύπου κλειδώματος οθόνης. Η εφαρμογή μπορεί επίσης να προτείνει στους χρήστες να ενημερώσουν το κλείδωμα οθόνης σε ένα συγκεκριμένο επίπεδο, όμως οι χρήστες μπορούν να την αγνοήσουν και να συνεχίσουν. Λάβετε υπόψη ότι το κλείδωμα οθόνης δεν αποθηκεύεται σε απλό κείμενο. Συνεπώς, η εφαρμογή δεν γνωρίζει τον κωδικό."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"χρήση βιομετρικού εξοπλισμού"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί βιομετρικό εξοπλισμό για έλεγχο ταυτότητας"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"διαχειρίζεται τον εξοπλισμό δακτυλικού αποτυπώματος"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Επιτρέπει στην εφαρμογή να επικαλείται μεθόδους προσθήκης/διαγραφής προτύπων για χρήση."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"χρήση υλικολογισμικού ελέγχου ταυτότητας προσώπου"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί υλικολογισμικό για έλεγχο ταυτότητας"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Αδυναμία επεξεργασίας προσώπου. Δοκιμάστε ξανά."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Υψηλή φωτεινότητα. Δοκιμάστε χαμηλότερο φωτισμό."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Πολύ σκοτεινό πρόσωπο. Ξεσκεπάστε την πηγή φωτός."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Μετακινήστε τον αισθητήρα πιο μακριά."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Τοποθετήστε τον αισθητήρα πιο κοντά στο πρόσωπο."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Μετακινήστε τον αισθητήρα ψηλότερα."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Μετακινήστε τον αισθητήρα χαμηλότερα."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Μετακινήστε τον αισθητήρα προς τα δεξιά."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Μετακινήστε τον αισθητήρα προς τα αριστερά."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Κοιτάξτε στον αισθητήρα."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Δεν εντοπίστηκε κάποιο πρόσωπο."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Υπερβολικά πολλή κίνηση."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Καταχωρίστε ξανά το πρόσωπό σας."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Ανιχνεύτηκε διαφορετικό πρόσωπο."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Πολύ παρόμοιο, αλλάξτε την πόζα σας."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Κοιτάξτε απευθείας στην κάμερα."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Κοιτάξτε απευθείας στην κάμερα."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Ευθυγραμμίστε το κεφάλι σας στον κατακόρυφο άξονα."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Μην καλύπτετε το πρόσωπό σας."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Το υλικολογισμικό προσώπου δεν είναι διαθέσιμο."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Λήξη χρονικού ορίου προσώπου. Δοκιμάστε ξανά."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Δεν είναι δυνατή η αποθήκευση του προσώπου."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Η ενέργεια προσώπου ακυρώθηκε."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Ο έλεγχος ταυτότητας προσώπου ακυρώθηκε από τον χρήστη."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Πάρα πολλές προσπάθειες. Δοκιμάστε ξανά αργότερα."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Πολλές προσπάθειες. Αποτυχία ελέγ. ταυτ. προσώπου."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Δοκιμάστε ξανά."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Δεν έχει καταχωριστεί κάποιο πρόσωπο."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Η συσκευή δεν διαθέτει αισθητήρα ελέγχου ταυτότ. προσώπου."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Πρόσωπο <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Ανοίξτε την εφαρμογή <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"Η εφαρμογή <xliff:g id="OLD_APP">%1$s</xliff:g> θα κλείσει χωρίς αποθήκευση"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Η διαδικασία <xliff:g id="PROC">%1$s</xliff:g> υπερβαίνει το όριο μνήμης"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Το στιγμιότυπο οθόνης λήφθηκε. Πατήστε για κοινοποίηση."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Κοινή χρήση στιγμιότυπου μνήμης;"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Η διαδικασία <xliff:g id="PROC">%1$s</xliff:g> υπερβαίνει το όριο μνήμης <xliff:g id="SIZE">%2$s</xliff:g>. Είναι διαθέσιμο ένα στιγμιότυπο μνήμης για να μοιραστείτε με τον προγραμματιστή. Να είστε προσεκτικοί: αυτό το στιγμιότυπο μνήμης μπορεί να περιέχει οποιοδήποτε από τα προσωπικά σας στοιχεία στα οποία έχει πρόσβαση η εφαρμογή."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Επιλέξτε μια ενέργεια για το κείμενο"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Ένταση ήχου ειδοποίησης"</string>
     <string name="volume_music" msgid="5421651157138628171">"Ένταση ήχου πολυμέσων"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Πατήστε για να δείτε όλα τα δίκτυα"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Σύνδεση"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Όλα τα δίκτυα"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Είναι διαθέσιμο ένα δίκτυο Wi‑Fi που προτείνεται από <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Θέλετε να συνδέσετε τα δίκτυα που προτείνονται από <xliff:g id="NAME">%s</xliff:g>;"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ναι"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Όχι"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Το Wi‑Fi θα ενεργοποιηθεί αυτόματα"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Σύνδεση στο δίκτυο"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Το Wi-Fi δεν έχει πρόσβαση στο διαδίκτυο"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Πατήστε για να δείτε τις επιλογές"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Συνδέθηκε"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Αλλαγές στις ρυθμίσεις σημείου πρόσβασης Wi-Fi"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Το εύρος σημείου πρόσβασης Wi-Fi άλλαξε."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Αυτή η συσκευή δεν υποστηρίζει την προτίμησή σας για τη ζώνη 5 GHz μόνο. Αντ\' αυτού, αυτή η συσκευή θα χρησιμοποιεί τη ζώνη 5 GHz όταν είναι διαθέσιμη."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Πατήστε για να απενεργοποιήσετε τον εντοπισμό και τη διόρθωση σφαλμάτων USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Υγρασία ή ακαθαρσίες στη θύρα USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Η θύρα USB απενεργοποιείται αυτόματα. Πατήστε για να μάθετε περισσότερα."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Μπορείτε να χρησιμοποιήσετε με ασφάλεια τη θύρα USB"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Πατήστε για ξεκλ. προφίλ εργ."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Συνδέθηκε με το <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Πατήστε για να δείτε τα αρχεία"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Καρφίτσωμα"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Ξεκαρφίτσωμα"</string>
     <string name="app_info" msgid="6856026610594615344">"Πληροφορίες εφαρμογής"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Έναρξη επίδειξης…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Ειδοποίηση πληροφοριών λειτουργίας Ρουτίνας"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Η μπαταρία μπορεί να εξαντληθεί πριν από τη συνηθισμένη φόρτιση"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Η Εξοικονόμηση μπαταρίας ενεργοποιήθηκε για την επέκταση της διάρκειας ζωής της μπαταρίας"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Φάκελος"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Εφαρμογή Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Αρχείο"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 8ed7bd8..a90fef7 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi Calling"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi only"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="global_action_logout" msgid="935179188218826050">"End session"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive report"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Use this under most circumstances. It allows you to track progress of the report, enter more details about the problem and take screenshots. It might omit some less-used sections that take a long time to report."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"access this device\'s location"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device\'s location?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"The app will only have access to the location while you’re using the app."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Always allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device’s location?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"The app will always have access to the location, even when you’re not using the app."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your calendar?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your music?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Photos &amp; videos"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"access your photos &amp; videos"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your photos and videos, including tagged locations?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"request screen lock complexity"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"use biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Allows the app to use biometric hardware for authentication"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Allows the app to invoke methods to add and delete facial templates for use."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"use face authentication hardware"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Allows the app to use face authentication hardware for authentication"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Couldn’t process face. Please try again."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Face is too bright. Please try in lower light."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Face is too dark. Please uncover light source."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Please move sensor farther away from face."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Please bring sensor closer to face."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Please move sensor higher."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Please move sensor lower."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Please move sensor to the right."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Please move sensor to the left."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Please look at the sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"No face detected."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Too much motion."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Please re-enroll your face."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Different face detected."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Too similar, please change your pose."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Please look more directly at the camera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Please look more directly at the camera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Please straighten your head vertically."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Please uncover your face."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Face hardware not available."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Face time out reached. Try again."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Face can’t be stored."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Face authentication cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Too many attempts. Facial authentication disabled."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Try again."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"No face enrolled."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"This device does not have a face authentication sensor."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Open <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> will close without saving"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Heap dump collected. Tap to share."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"The process <xliff:g id="PROC">%1$s</xliff:g> has exceeded its process memory limit of <xliff:g id="SIZE">%2$s</xliff:g>. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Choose an action for text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Ringer volume"</string>
     <string name="volume_music" msgid="5421651157138628171">"Media volume"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"A Wi‑Fi network proposed by <xliff:g id="NAME">%s</xliff:g> is available"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Do you want to connect to networks proposed by <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi has no Internet access"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tap for options"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Connected"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Changes to your hotspot settings"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Your hotspot band has changed."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"This device doesn’t support your preference for 5 GHz only. Instead, this device will use the 5 GHz band when available."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tap to turn off USB debugging"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Safe to use USB port"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap to unlock work profile"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tap to view files"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Pin"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starting demo…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Routine Mode info notification"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Battery Saver activated to extend battery life"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folder"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android application"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"File"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 722d132..a10300e 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi Calling"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi only"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="global_action_logout" msgid="935179188218826050">"End session"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive report"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Use this under most circumstances. It allows you to track progress of the report, enter more details about the problem and take screenshots. It might omit some less-used sections that take a long time to report."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"access this device\'s location"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device\'s location?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"The app will only have access to the location while you’re using the app."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Always allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device’s location?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"The app will always have access to the location, even when you’re not using the app."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your calendar?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your music?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Photos &amp; videos"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"access your photos &amp; videos"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your photos and videos, including tagged locations?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"request screen lock complexity"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"use biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Allows the app to use biometric hardware for authentication"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Allows the app to invoke methods to add and delete facial templates for use."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"use face authentication hardware"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Allows the app to use face authentication hardware for authentication"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Couldn’t process face. Please try again."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Face is too bright. Please try in lower light."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Face is too dark. Please uncover light source."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Please move sensor farther away from face."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Please bring sensor closer to face."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Please move sensor higher."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Please move sensor lower."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Please move sensor to the right."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Please move sensor to the left."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Please look at the sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"No face detected."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Too much motion."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Please re-enroll your face."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Different face detected."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Too similar, please change your pose."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Please look more directly at the camera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Please look more directly at the camera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Please straighten your head vertically."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Please uncover your face."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Face hardware not available."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Face time out reached. Try again."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Face can’t be stored."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Face authentication cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Too many attempts. Facial authentication disabled."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Try again."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"No face enrolled."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"This device does not have a face authentication sensor."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Open <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> will close without saving"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Heap dump collected. Tap to share."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"The process <xliff:g id="PROC">%1$s</xliff:g> has exceeded its process memory limit of <xliff:g id="SIZE">%2$s</xliff:g>. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Choose an action for text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Ringer volume"</string>
     <string name="volume_music" msgid="5421651157138628171">"Media volume"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"A Wi‑Fi network proposed by <xliff:g id="NAME">%s</xliff:g> is available"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Do you want to connect to networks proposed by <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi has no Internet access"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tap for options"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Connected"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Changes to your hotspot settings"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Your hotspot band has changed."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"This device doesn’t support your preference for 5 GHz only. Instead, this device will use the 5 GHz band when available."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tap to turn off USB debugging"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Safe to use USB port"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap to unlock work profile"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tap to view files"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Pin"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starting demo…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Routine Mode info notification"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Battery Saver activated to extend battery life"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folder"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android application"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"File"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 8ed7bd8..a90fef7 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi Calling"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi only"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="global_action_logout" msgid="935179188218826050">"End session"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive report"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Use this under most circumstances. It allows you to track progress of the report, enter more details about the problem and take screenshots. It might omit some less-used sections that take a long time to report."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"access this device\'s location"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device\'s location?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"The app will only have access to the location while you’re using the app."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Always allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device’s location?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"The app will always have access to the location, even when you’re not using the app."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your calendar?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your music?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Photos &amp; videos"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"access your photos &amp; videos"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your photos and videos, including tagged locations?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"request screen lock complexity"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"use biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Allows the app to use biometric hardware for authentication"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Allows the app to invoke methods to add and delete facial templates for use."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"use face authentication hardware"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Allows the app to use face authentication hardware for authentication"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Couldn’t process face. Please try again."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Face is too bright. Please try in lower light."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Face is too dark. Please uncover light source."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Please move sensor farther away from face."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Please bring sensor closer to face."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Please move sensor higher."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Please move sensor lower."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Please move sensor to the right."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Please move sensor to the left."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Please look at the sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"No face detected."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Too much motion."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Please re-enroll your face."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Different face detected."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Too similar, please change your pose."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Please look more directly at the camera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Please look more directly at the camera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Please straighten your head vertically."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Please uncover your face."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Face hardware not available."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Face time out reached. Try again."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Face can’t be stored."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Face authentication cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Too many attempts. Facial authentication disabled."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Try again."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"No face enrolled."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"This device does not have a face authentication sensor."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Open <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> will close without saving"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Heap dump collected. Tap to share."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"The process <xliff:g id="PROC">%1$s</xliff:g> has exceeded its process memory limit of <xliff:g id="SIZE">%2$s</xliff:g>. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Choose an action for text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Ringer volume"</string>
     <string name="volume_music" msgid="5421651157138628171">"Media volume"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"A Wi‑Fi network proposed by <xliff:g id="NAME">%s</xliff:g> is available"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Do you want to connect to networks proposed by <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi has no Internet access"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tap for options"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Connected"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Changes to your hotspot settings"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Your hotspot band has changed."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"This device doesn’t support your preference for 5 GHz only. Instead, this device will use the 5 GHz band when available."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tap to turn off USB debugging"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Safe to use USB port"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap to unlock work profile"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tap to view files"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Pin"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starting demo…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Routine Mode info notification"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Battery Saver activated to extend battery life"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folder"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android application"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"File"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 8ed7bd8..a90fef7 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi Calling"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi only"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="global_action_logout" msgid="935179188218826050">"End session"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive report"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Use this under most circumstances. It allows you to track progress of the report, enter more details about the problem and take screenshots. It might omit some less-used sections that take a long time to report."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"access this device\'s location"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device\'s location?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"The app will only have access to the location while you’re using the app."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Always allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access this device’s location?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"The app will always have access to the location, even when you’re not using the app."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your calendar?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your music?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Photos &amp; videos"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"access your photos &amp; videos"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access your photos and videos, including tagged locations?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"request screen lock complexity"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plain text so the app does not know the exact password."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"use biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Allows the app to use biometric hardware for authentication"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"manage fingerprint hardware"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Allows the app to invoke methods to add and delete facial templates for use."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"use face authentication hardware"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Allows the app to use face authentication hardware for authentication"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Couldn’t process face. Please try again."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Face is too bright. Please try in lower light."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Face is too dark. Please uncover light source."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Please move sensor farther away from face."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Please bring sensor closer to face."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Please move sensor higher."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Please move sensor lower."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Please move sensor to the right."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Please move sensor to the left."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Please look at the sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"No face detected."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Too much motion."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Please re-enroll your face."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Different face detected."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Too similar, please change your pose."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Please look more directly at the camera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Please look more directly at the camera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Please straighten your head vertically."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Please uncover your face."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Face hardware not available."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Face time out reached. Try again."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Face can’t be stored."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Face operation cancelled."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Face authentication cancelled by user."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Too many attempts. Try again later."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Too many attempts. Facial authentication disabled."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Try again."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"No face enrolled."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"This device does not have a face authentication sensor."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Face <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Open <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> will close without saving"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> exceeded memory limit"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Heap dump collected. Tap to share."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share heap dump?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"The process <xliff:g id="PROC">%1$s</xliff:g> has exceeded its process memory limit of <xliff:g id="SIZE">%2$s</xliff:g>. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Choose an action for text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Ringer volume"</string>
     <string name="volume_music" msgid="5421651157138628171">"Media volume"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"A Wi‑Fi network proposed by <xliff:g id="NAME">%s</xliff:g> is available"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Do you want to connect to networks proposed by <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Sign in to network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi has no Internet access"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tap for options"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Connected"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Changes to your hotspot settings"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Your hotspot band has changed."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"This device doesn’t support your preference for 5 GHz only. Instead, this device will use the 5 GHz band when available."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tap to turn off USB debugging"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Safe to use USB port"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap to unlock work profile"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tap to view files"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Pin"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starting demo…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Routine Mode info notification"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Battery Saver activated to extend battery life"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folder"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android application"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"File"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index a8173dd..a531355 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎WiFi Calling‎‏‎‎‏‎"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‎VoWifi‎‏‎‎‏‎"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‎Off‎‏‎‎‏‎"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎Wi-Fi preferred‎‏‎‎‏‎"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎Mobile preferred‎‏‎‎‏‎"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎Wi-Fi only‎‏‎‎‏‎"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>‎‏‎‎‏‏‏‎: Not forwarded‎‏‎‎‏‎"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>‎‏‎‎‏‏‏‎: ‎‏‎‎‏‏‎<xliff:g id="DIALING_NUMBER">{1}</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎Bug report‎‏‎‎‏‎"</string>
     <string name="global_action_logout" msgid="935179188218826050">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎End session‎‏‎‎‏‎"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎Screenshot‎‏‎‎‏‎"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎Take bug report‎‏‎‎‏‎"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‎‎‎This will collect information about your current device state, to send as an e-mail message. It will take a little time from starting the bug report until it is ready to be sent; please be patient.‎‏‎‎‏‎"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎Interactive report‎‏‎‎‏‎"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎Use this under most circumstances. It allows you to track progress of the report, enter more details about the problem, and take screenshots. It might omit some less-used sections that take a long time to report.‎‏‎‎‏‎"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎Location‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎access this device\'s location‎‏‎‎‏‎"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎Allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to access this device\'s location?‎‏‎‎‏‎"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎The app will only have access to the location while you’re using the app.‎‏‎‎‏‎"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎Always allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to access this device’s location?‎‏‎‎‏‎"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎The app will always have access to the location, even when you’re not using the app.‎‏‎‎‏‎"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎Calendar‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‎access your calendar‎‏‎‎‏‎"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎Allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to access your calendar?‎‏‎‎‏‎"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎Allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to access your music?‎‏‎‎‏‎"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎Photos &amp; videos‎‏‎‎‏‎"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎access your photos &amp; videos‎‏‎‎‏‎"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‏‏‎‎‏‎‎Allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to access your photos and videos, including tagged locations?‎‏‎‎‏‎"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‎‎‎Retrieve window content‎‏‎‎‏‎"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎Inspect the content of a window you\'re interacting with.‎‏‎‎‏‎"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎Turn on Explore by Touch‎‏‎‎‏‎"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‎Allows the app to communicate with Near Field Communication (NFC) tags, cards, and readers.‎‏‎‎‏‎"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‎‎disable your screen lock‎‏‎‎‏‎"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‏‎‎‎‎‎Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished.‎‏‎‎‏‎"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎request screen lock complexity‎‏‎‎‏‎"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‎Allows the app to learn the screen lock complexity level (high, medium, low or none), which indicates the possible range of length and type of the screen lock. The app can also suggest to users that they update the screen lock to a certain level but users can freely ignore and navigate away. Note that the screen lock is not stored in plaintext so the app does not know the exact password.‎‏‎‎‏‎"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‏‏‎‎use biometric hardware‎‏‎‎‏‎"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎Allows the app to use biometric hardware for authentication‎‏‎‎‏‎"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎‎manage fingerprint hardware‎‏‎‎‏‎"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎Allows the app to invoke methods to add and delete facial templates for use.‎‏‎‎‏‎"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‏‏‎use face authentication hardware‎‏‎‎‏‎"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎Allows the app to use face authentication hardware for authentication‎‏‎‎‏‎"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎Couldn’t process face. Please try again.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎Face is too bright. Please try in lower light.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎Face is too dark. Please uncover light source.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎Please move sensor farther from face.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‎Please bring sensor closer to face.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎Please move sensor higher.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‎‏‎Please move sensor lower.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‎Please move sensor to the right.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎Please move sensor to the left.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎Please look at the sensor.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‏‏‎No face detected.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‎Too much motion.‎‏‎‎‏‎"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎Please re-enroll your face.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‎‎Different face detected.‎‏‎‎‏‎"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎Too similar, please change your pose.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‎‎Please look more directly at the camera.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎Please look more directly at the camera.‎‏‎‎‏‎"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎Please straighten your head vertically.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‎Please uncover your face.‎‏‎‎‏‎"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎Face hardware not available.‎‏‎‎‏‎"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‎‎Face time out reached. Try again.‎‏‎‎‏‎"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎‎‎‏‎‎Face can’t be stored.‎‏‎‎‏‎"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎Face operation canceled.‎‏‎‎‏‎"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎Face authentication canceled by user.‎‏‎‎‏‎"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‎Too many attempts. Try again later.‎‏‎‎‏‎"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎Too many attempts. Facial authentication disabled.‎‏‎‎‏‎"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎Try again.‎‏‎‎‏‎"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎No face enrolled.‎‏‎‎‏‎"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‏‎This device does not have a face authentication sensor.‎‏‎‎‏‎"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎Face ‎‏‎‎‏‏‎<xliff:g id="FACEID">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎Open ‎‏‎‎‏‏‎<xliff:g id="NEW_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="new_app_description" msgid="5894852887817332322">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="OLD_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ will close without saving‎‏‎‎‏‎"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="PROC">%1$s</xliff:g>‎‏‎‎‏‏‏‎ exceeded memory limit‎‏‎‎‏‎"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎Heap dump collected. Tap to share.‎‏‎‎‏‎"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎Share heap dump?‎‏‎‎‏‎"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‏‎‏‎The process ‎‏‎‎‏‏‎<xliff:g id="PROC">%1$s</xliff:g>‎‏‎‎‏‏‏‎ has exceeded its process memory limit of ‎‏‎‎‏‏‎<xliff:g id="SIZE">%2$s</xliff:g>‎‏‎‎‏‏‏‎. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to.‎‏‎‎‏‎"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‎Choose an action for text‎‏‎‎‏‎"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎Ringer volume‎‏‎‎‏‎"</string>
     <string name="volume_music" msgid="5421651157138628171">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‎Media volume‎‏‎‎‏‎"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎Tap to see all networks‎‏‎‎‏‎"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‎Connect‎‏‎‎‏‎"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎All networks‎‏‎‎‏‎"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎A Wi‑Fi network proposed by ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ is available‎‏‎‎‏‎"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‎Do you want to connect to networks proposed by ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎Yes‎‏‎‎‏‎"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎No‎‏‎‎‏‎"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎Wi‑Fi will turn on automatically‎‏‎‎‏‎"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎Sign in to network‎‏‎‎‏‎"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎Wi-Fi has no internet access‎‏‎‎‏‎"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎Tap for options‎‏‎‎‏‎"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎Connected‎‏‎‎‏‎"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎Changes to your hotspot settings‎‏‎‎‏‎"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‏‎‏‏‎Your hotspot band has changed.‎‏‎‎‏‎"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎This device doesn’t support your preference for 5GHz only. Instead, this device will use the 5GHz band when available.‎‏‎‎‏‎"</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎USB debugging connected‎‏‎‎‏‎"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎Tap to turn off USB debugging‎‏‎‎‏‎"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‎Select to disable USB debugging.‎‏‎‎‏‎"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎Liquid or debris in USB port‎‏‎‎‏‎"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‎‎USB port is automatically disabled. Tap to learn more.‎‏‎‎‏‎"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎Safe to use USB port‎‏‎‎‏‎"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‎‎Tap to unlock work profile‎‏‎‎‏‎"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‎‎‎Connected to ‎‏‎‎‏‏‎<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‏‎‎Tap to view files‎‏‎‎‏‎"</string>
-    <string name="pin_target" msgid="3052256031352291362">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎Pin‎‏‎‎‏‎"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‎‎Unpin‎‏‎‎‏‎"</string>
     <string name="app_info" msgid="6856026610594615344">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎App info‎‏‎‎‏‎"</string>
     <string name="negative_duration" msgid="5688706061127375131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎−‎‏‎‎‏‏‎<xliff:g id="TIME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎Starting demo…‎‏‎‎‏‎"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎Routine Mode info notification‎‏‎‎‏‎"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎Battery may run out before usual charge‎‏‎‎‏‎"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎Battery Saver activated to extend battery life‎‏‎‎‏‎"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎Folder‎‏‎‎‏‎"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎Android application‎‏‎‎‏‎"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‎File‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 387eea3..d058728 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Llamada por Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivada"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Red Wi-Fi preferida"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Red móvil preferida"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Solo Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: no se ha remitido"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de errores"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Finalizar sesión"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Iniciar informe de errores"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Se recopilará información sobre el estado actual de tu dispositivo, que se enviará por correo. Pasarán unos minutos desde que se inicie el informe de errores hasta que se envíe, por lo que te recomendamos que tengas paciencia."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Informe interactivo"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Usa esta opción en la mayoría de los casos. Te permite realizar un seguimiento del progreso del informe, ingresar más detalles acerca del problema y tomar capturas de pantalla. Es posible que se omitan secciones menos usadas cuyos informes demoran más en completarse."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Ubicación"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"acceder a la ubicación de este dispositivo"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"¿Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a la ubicación de este dispositivo?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"La app solo tendrá acceso a la ubicación cuando la uses."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"¿Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a la ubicación?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"La app siempre tendrá acceso a la ubicación, incluso cuando no la uses."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder al calendario"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"¿Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a tu calendario?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"¿Quieres permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a tu música?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotos y videos"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"acceder a tus fotos y videos"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"¿Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a tus fotos y videos, incluidas las ubicaciones etiquetadas?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contenido de las ventanas"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contenido de la ventana con la que estés interactuando."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar la Exploración táctil"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Permite que la aplicación se comunique con lectores, tarjetas y etiquetas de Comunicación de campo cercano (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivar el bloqueo de pantalla"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite que la aplicación desactive el bloqueo del teclado y cualquier protección con contraseña asociada. Por ejemplo, el dispositivo puede desactivar el bloqueo del teclado cuando recibe una llamada telefónica y volver a activarlo cuando finaliza la llamada."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"solicitar complejidad del bloqueo de pantalla"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Permite que la app conozca el nivel de complejidad del bloqueo de pantalla (alta, media, baja o ninguna), lo que indica el rango de duración posible y el tipo de bloqueo. La app también puede sugerirles a los usuarios que actualicen el bloqueo de pantalla a un determinado nivel, aunque ellos pueden ignorar esta sugerencia y seguir navegando. Ten en cuenta que el bloqueo de pantalla no se almacena como texto sin formato, por lo que la app no conoce la contraseña exacta."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"usar hardware biométrico"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que la app use hardware biométrico para realizar la autenticación"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Administrar el hardware de huellas digitales"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que la app emplee métodos para agregar y borrar plantillas de rostros para su uso."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"usar el hardware de autenticación facial"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Permite que la app use el hardware de autenticación facial para reconocerte"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Error al procesar el rostro. Vuelve a intentarlo."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"El rostro se ve muy claro. Prueba con menos luz."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"El rostro se ve muy oscuro. Prueba con más luz."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Aleja el sensor del rostro."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Acerca el sensor al rostro."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Coloca el sensor más arriba."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Coloca el sensor más abajo."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Mueve el sensor hacia la derecha."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Mueve el sensor hacia la izquierda."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Mira al sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"No se detectó ningún rostro."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Te estás moviendo demasiado."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Vuelve a registrar tu cara."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Se detectó otra cara."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Es muy similar a la anterior. Haz otra pose."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Mira directamente a la cámara."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Mira directamente a la cámara."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Mantén la cabeza en posición vertical."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"No te tapes la cara."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardware de reconocimiento facial no disponible"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Se agotó el tiempo. Vuelve a intentarlo."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"No se puede almacenar el rostro."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Se canceló el reconocimiento facial."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"El usuario canceló la autenticación de rostro."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiados intentos. Inténtalo de nuevo más tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Demasiados intentos. Autent. facial inhabilitada."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Vuelve a intentarlo."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"No registraste ningún rostro."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Este dispositivo no tiene sensor de autenticación facial."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Rostro <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Abrir <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> se cerrará sin guardar"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> superó el límite de memoria."</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Se recopiló el volcado de pila. Toca para compartir."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"¿Compartir volcado de pila?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"El proceso <xliff:g id="PROC">%1$s</xliff:g> superó el límite de memoria de proceso de <xliff:g id="SIZE">%2$s</xliff:g>. Hay un volcado de pila disponible para que puedas compartirlo con el programador. Ten cuidado, este volcado de pila puede contener información personal a la que la aplicación tiene acceso."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Seleccionar una acción para el texto"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volumen del timbre"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volumen de los medios"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Presiona para ver todas las redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas las redes"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Está disponible una red Wi‑Fi sugerida por <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"¿Deseas conectarte a las redes sugeridas por <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sí"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Se activará la conexión Wi-Fi automáticamente"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Acceder a la red"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"La red Wi-Fi no tiene acceso a Internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Presiona para ver opciones"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Se estableció conexión"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Cambios en la configuración de tu hotspot"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Cambió la banda de tu hotspot."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Si bien este dispositivo no admite la opción para conectarse exclusivamente a bandas de 5 GHz, las usará cuando estén disponibles."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Presiona para desactivar la depuración USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para desactivar la depuración por USB"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hay líquido o suciedad en el puerto USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El puerto USB se inhabilitó automáticamente. Presiona para obtener más información."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Es seguro usar el puerto USB"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Presiona para desbloquear"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Presiona para ver archivos"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Fijar"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"No fijar"</string>
     <string name="app_info" msgid="6856026610594615344">"Información de apps"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demostración…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notificación de información del modo de Rutinas"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Es posible que la batería se agote antes de la carga habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Se activó el Ahorro de batería para extender la duración de la batería"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Carpeta"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplicación de Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Archivo"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index f87743a..6e212d7 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WiFi-kõned"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Väljas"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"WiFi eelistusega"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Eelistatud on mobiilne andmeside"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Ainult WiFi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: pole suunatud"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Veaaruanne"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Seansi lõpp"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekraanipilt"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Veaaruande võtmine"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Nii kogutakse teavet teie seadme praeguse oleku kohta, et saata see meilisõnumina. Enne kui saate veaaruande ära saata, võtab selle loomine natuke aega; varuge kannatust."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interakt. aruanne"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Kasutage seda enamikul juhtudel. See võimaldab jälgida aruande edenemist, sisestada probleemi kohta täpsemat teavet ja jäädvustada ekraanipilte. Vahele võivad jääda mõned vähem kasutatud jaotised, millest teavitamine võtab rohkem aega."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Asukoht"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"pääseda juurde selle seadme asukohale"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Kas lubada rakendusele &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; juurdepääs selle seadme asukohale?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Rakendusel on juurdepääs asukohale vaid siis, kui rakendust kasutate."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Kas lubada rak. &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; alati juurdepääs seadme asukohale?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Rakendusel on alati juurdepääs asukohale isegi siis, kui te rakendust ei kasuta."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"juurdepääs kalendrile"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Kas lubada rakendusele &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; juurdepääs teie kalendrile?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Kas lubada rakendusele &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; juurdepääs teie muusikale?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotod ja videod"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"Pääseda juurde teie fotodele ja videotele"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Kas lubada rakendusel &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; teie fotodele ja videotele, sh märgistatud asukohtadele, juurde pääseda?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Akna sisu toomine"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kasutatava akna sisu kontrollimine."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Puudutusega sirvimise sisselülitamine"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Võimaldab rakendusel suhelda lähiväljaside (NFC) märgendite, kaartide ja lugeritega."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"keelake ekraanilukk"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Võimaldab rakendusel keelata klahviluku ja muu seotud parooli turvalisuse. Näiteks keelab telefon klahviluku sissetuleva kõne vastuvõtmisel ja lubab klahviluku uuesti, kui kõne on lõpetatud."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"taotleda ekraaniluku keerukust"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Lubab rakendusel vaadata ekraaniluku keerukuse taset (kõrge, keskmine, madal või puudub), mis näitab ekraaniluku võimalikku pikkust ja tüüpi. Rakendus võib kasutajatele soovitada ka ekraaniluku viimist teatud tasemele, kuid kasutajad võivad seda eirata ja kuvalt lahkuda. Pange tähele, et ekraanilukku ei salvestata lihttekstina, seega ei tea rakendus täpset parooli."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"kasutada biomeetrilist riistvara"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Võimaldab rakendusel autentimiseks kasutada biomeetrilist riistvara"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"sõrmejälje riistvara haldamine"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Lubab rakendusel tühistada meetodid kasutatavate näomallide lisamiseks ja kustutamiseks."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"kasutada näo autentimise riistvara"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Võimaldab rakendusel autentimiseks kasutada näo autentimise riistvara"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Nägu ei õnnestunud töödelda. Proovige uuesti."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Nägu on liiga hele. Proovige hämaramas."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Nägu on liiga tume. Kasutage valgusallikat."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Liigutage andur näost kaugemale."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Liigutage andur näole lähemale."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Liigutage andurit kõrgemale."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Liigutage andurit madalamale."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Liigutage andurit paremale."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Liigutage andurit vasakule."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Vaadake andurit."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nägu ei tuvastatud."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Liiga palju liikumist."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registreerige oma nägu uuesti."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Tuvastati teine nägu."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Liiga sarnane, palun muutke oma asendit."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Vaadake otse kaamerasse."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Vaadake otse kaamerasse."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Pange pea vertikaalselt otseks."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Tooge oma nägu esile."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Näotuvastuse riistvara pole saadaval."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Näotuvastuse taimeri ajalõpp. Proovige uuesti."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Nägu ei saa salvestada."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Näotuvastuse toiming tühistati."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Kasutaja tühistas näo autentimise."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Liiga palju katseid. Proovige hiljem uuesti."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Liiga palju katseid. Näotuvastus on keelatud."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Proovige uuesti."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nägu pole registreeritud."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Sellel seadmel pole näotuvastuse andurit."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Nägu <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Ava rakendus <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"Rakendus <xliff:g id="OLD_APP">%1$s</xliff:g> suletakse salvestamata"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Protsess <xliff:g id="PROC">%1$s</xliff:g> ületas mälupiirangu"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Mälutõmmis salvestati. Puudutage jagamiseks."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Kas jagada mälutõmmist?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Protsess <xliff:g id="PROC">%1$s</xliff:g> ületas protsessi mälupiirangu <xliff:g id="SIZE">%2$s</xliff:g>. Saate mälutõmmist jagada selle arendajaga. Olge ettevaatlik: see mälutõmmis võib sisaldada teie isiklikke andmeid, millele rakendusel on juurdepääs."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Valige teksti jaoks toiming"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Helina helitugevus"</string>
     <string name="volume_music" msgid="5421651157138628171">"Meediumi helitugevus"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Puudutage kõikide võrkude nägemiseks"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ühenda"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Kõik võrgud"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Rakenduse <xliff:g id="NAME">%s</xliff:g> soovitatud WiFi-võrk on saadaval"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Kas soovite ühenduse luua rakenduse <xliff:g id="NAME">%s</xliff:g> soovitatud võrkudega?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Jah"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ei"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WiFi lülitub sisse automaatselt"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Võrku sisselogimine"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"WiFi-võrgul pole juurdepääsu Internetile"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Puudutage valikute nägemiseks"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Ühendatud"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Muudatused teie leviala seadetes"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Teie leviala riba on muutunud."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"See seade ei toeta teie eelistatud ainult 5 GHz riba. Seade kasutab 5 GHz riba ainult siis, kui see on saadaval."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Puudutage USB silumise väljalülitamiseks"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Valige USB silumise keelamiseks"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB-pordis on vedelik või mustus"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-port on automaatselt keelatud. Puudutage lisateabe saamiseks."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB-porti on ohutu kasutada"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Puudut. tööprofiili avamiseks"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Ühendatud seadmega <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Failide vaatamiseks puudutage"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Kinnita"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Vabasta"</string>
     <string name="app_info" msgid="6856026610594615344">"Rakenduse teave"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo käivitamine …"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Rutiinirežiimi teabe märguanne"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Aku võib enne tavapärast laadimist tühjaks saada"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Akusäästja aktiveeriti aku tööea pikendamiseks"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Kaust"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Androidi rakendus"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fail"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 7835cfe..43c9b983 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"‏تماس ازطریق WiFi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"خاموش"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"‏Wi-Fi ترجیحی"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"داده شبکه تلفن همراه ارجح است"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"‏فقط Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: هدایت نشده"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"گزارش اشکال"</string>
     <string name="global_action_logout" msgid="935179188218826050">"پایان جلسه"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"عکس صفحه‌نمایش"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"گرفتن گزارش اشکال"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"این گزارش اطلاعات مربوط به وضعیت دستگاه کنونی شما را جمع‌آوری می‌کند تا به صورت یک پیام ایمیل ارسال شود. از زمان شروع گزارش اشکال تا آماده شدن برای ارسال اندکی زمان می‌برد؛ لطفاً شکیبا باشید."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"گزارش تعاملی"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"در بیشتر شرایط از این گزینه استفاده کنید. به شما امکان ردیابی پیشرفت گزارش و وارد کردن جزئیات بیشتری درباره مشکل را می‌دهد. ممکن است برخی از بخش‌هایی را که کمتر استفاده شده و باعث افزایش طول زمان گزارش می‌شود حذف کند."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"مکان"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"دسترسی به موقعیت مکانی این دستگاه"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"‏به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه داده شود به مکان این دستگاه دسترسی پیدا کند؟"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"این برنامه تنها هنگامی که از آن استفاده می‌کنید، به مکان دسترسی خواهد داشت."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"‏همیشه به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه داده شود به مکان این دستگاه دسترسی داشته باشد؟"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"این برنامه همیشه به مکان دسترسی خواهد داشت، حتی اگر از آن استفاده نکنید."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"تقویم"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"دسترسی به تقویم شما"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‏به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه داده شود به تقویم شما دسترسی پیدا کند؟"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"‏به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه داده شود به موسیقی شما دسترسی پیدا کند؟"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"عکس و ویدیو"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"دسترسی به عکس‌ها و ویدیوهایتان"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"‏به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه می‌دهید به عکس‌ها و ویدیوهاتان، ازجمله مکان‌های برچسب‌گذاری‌شده، دسترسی داشته باشد؟"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"محتوای پنجره را بازیابی کند"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"محتوای پنجره‌ای را که درحال تعامل با آن هستید بررسی می‌کند."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"فعال‌سازی کاوش لمسی"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"‏به برنامه اجازه می‎دهد تا با تگهای ارتباط میدان نزدیک (NFC)، کارتها و فایل خوان ارتباط برقرار کند."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"غیرفعال کردن قفل صفحه شما"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"به برنامه امکان می‌دهد قفل کلید و هر گونه امنیت گذرواژه مرتبط را غیرفعال کند. به‌عنوان مثال تلفن هنگام دریافت یک تماس تلفنی ورودی قفل کلید را غیرفعال می‌کند و بعد از پایان تماس، قفل کلید را دوباره فعال می‌کند."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"درخواست پیچیدگی قفل صفحه"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"به برنامه اجازه می‌دهد سطح پیچیدگی قفل صفحه (بالا، متوسط، پایین یا هیچ‌کدام) را بیاموزد که نشانگر طیف طول مدت و نوع قفل صفحه است. همچنین برنامه می‌تواند به کاربران پیشنهاد دهد قفل صفحه را به سطح خاصی به‌روزرسانی کنند، اما کاربران می‌توانند آزادانه این پیشنهاد را نادیده بگیرند و به سطح دیگری بروند. توجه داشته باشید که قفل صفحه در قالب نوشتار ساده ذخیره نمی‌شود، بنابراین برنامه گذرواژه دقیق را نمی‌داند."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"استفاده از سخت‌افزار بیومتریک"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"به برنامه امکان می‌دهد از سخت‌افزار بیومتریک برای احراز هویت استفاده کند"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"مدیریت سخت‌افزار اثر انگشت"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"به برنامه امکان می‌دهد روش‌هایی را برای افزودن و حذف الگوهای چهره جهت استفاده فرابخواند."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"استفاده از سخت‌افزار احراز هویت با چهره"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"به برنامه امکان می‌دهد از سخت‌افزار احراز هویت با چهره برای احراز هویت استفاده کند"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"چهره پردازش نشد. لطفاً دوباره امتحان کنید."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"چهره خیلی روشن است. لطفاً در نور کمتری دوباره امتحان کنید."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"چهره خیلی تاریک است. لطفاً منبع نور را نپوشانید."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"لطفاً حسگر را از صورتتان دورتر کنید."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"لطفاً حسگر را به صورتتان نزدیک‌تر کنید."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"لطفاً حسگر را بالاتر ببرید."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"لطفاً حسگر را پایین‌تر بیاورید."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"لطفاً حسگر را به راست حرکت دهید."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"لطفاً حسگر را به چپ حرکت دهید."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"لطفاً به حسگر نگاه کنید."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"چهره‌ای شناسایی نشد."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"حرکت خیلی زیاد است."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"لطفاً چهره‌تان را مجدداً ثبت کنید."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"چهره دیگری شناسایی شد."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"بسیار شبیه قبلی است، لطفاً قیافه دیگری بگیرید."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"لطفاً مستقیم به دوربین نگاه کنید."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"لطفاً مستقیم به دوربین نگاه کنید."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"لطفاً سرتان را به‌صورت عمود نگه دارید."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"لطفاً چهره‌تان را نپوشانید."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"سخت‌افزار چهره دردسترس نیست."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"مهلت زمانی شناسایی چهره تمام شد. دوباره امتحان کنید"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"نمی‌توان چهره را ذخیره کرد."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"عملیات شناسایی چهره لغو شد."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"احراز هویت چهره توسط کاربر لغو شد."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"تعداد زیادی تلاش ناموفق. بعداً دوباره امتحان کنید."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"چندین تلاش ناموفق. احراز هویت با چهره غیرفعال شد."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"دوباره امتحان کنید."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"هیچ چهره‌ای ثبت نشده است."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"این دستگاه حسگر احراز هویت با چهره ندارد."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"چهره <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> را باز کنید"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> بدون ذخیره شدن بسته می‌شود"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> از حد مجاز حافظه فراتر رفت"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"رونوشت حافظه جمع‌آوری شد. برای هم‌رسانی ضربه بزنید."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"رونوشت حافظه آزاد به اشتراک گذاشته شود؟"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"فرآیند <xliff:g id="PROC">%1$s</xliff:g> از حد مجاز حافظه پردازش خود <xliff:g id="SIZE">%2$s</xliff:g> فراتر رفته است. یک رونوشت حافظه آزاد برای شما در دسترس است که با برنامه‌نویس به اشتراک بگذارید. مواظب باشید: این رونوشت حافظه آزاد می‌تواند حاوی هر نوع اطلاعات شخصی شما باشد که برنامه به آن دسترسی دارد."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"انتخاب یک عملکرد برای نوشتار"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"میزان صدای زنگ"</string>
     <string name="volume_music" msgid="5421651157138628171">"میزان صدای رسانه"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"برای دیدن همه شبکه‌ها ضربه بزنید"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"همه شبکه‌ها"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"‏شبکه Wi-Fi پیشنهادی <xliff:g id="NAME">%s</xliff:g> دردسترس است"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"مایلید به شبکه‌های پیشنهادی <xliff:g id="NAME">%s</xliff:g> متصل شوید؟"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"بله"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"خیر"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‏Wi‑Fi به‌طور خودکار روشن خواهد شد"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ورود به سیستم شبکه"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"‏Wi-Fi به اینترنت دسترسی ندارد"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"برای گزینه‌ها ضربه بزنید"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"متصل"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"تغییرات در تنظیمات نقطه اتصال"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"نوار نقطه اتصال شما تغییر کرد."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"این دستگاه از اولویت فقط ۵ گیگاهرتز شما پشتیبانی نمی‌کند. هرزمان نوار ۵ گیگاهرتزی دردسترس باشد این دستگاه از آن استفاده خواهد کرد."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏اشکال‌زدایی USB متصل شد"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"‏برای خاموش کردن اشکال‌زدایی USB ضربه بزنید"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏مایعات یا خاکروبه در درگاه USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏درگاه USB به‌طور خودکار غیرفعال شده است. برای اطلاعات بیشتر، ضربه بزنید."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"‏ایمن برای استفاده از درگاه USB"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"برای باز کردن قفل ضربه بزنید"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"به <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> متصل شد"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"برای دیدن فایل‌ها، ضربه بزنید"</string>
-    <string name="pin_target" msgid="3052256031352291362">"پین کردن"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"برداشتن پین"</string>
     <string name="app_info" msgid="6856026610594615344">"اطلاعات برنامه"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"در حال شروع نسخه نمایشی…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"اعلان اطلاعات حالت روال معمول"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ممکن است شارژ باتری قبل از شارژ معمول تمام شود"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"جهت افزایش عمر باتری، بهینه‌سازی باتری فعال شد"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"پوشه"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"‏برنامه Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"فایل"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 6efc8be..1b2d533 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi-puhelut"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Ei käytössä"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ensisijainen"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobiiliverkko ensisijainen"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Vain Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ei siirretty"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Virheraportti"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Lopeta käyttökerta"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Kuvakaappaus"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Luo virheraportti"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Toiminto kerää tietoja laitteen tilasta ja lähettää ne sähköpostitse. Virheraportti on valmis lähetettäväksi hetken kuluttua - kiitos kärsivällisyydestäsi."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiivinen"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Valitse tämä vaihtoehto useimmissa tapauksissa. Voit seurata raportin etenemistä, antaa lisätietoja ongelmasta ja tallentaa kuvakaappauksia. Tämä vaihtoehto saattaa ohittaa joitakin harvoin käytettyjä osioita, joiden käsittely raportissa kestää kauan."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Sijainti"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"käyttää laitteen sijaintia"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tämän laitteen sijainnin käyttöoikeuden?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Sovellus saa sijainnin käyttöoikeuden vain jos käytät sovellusta."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tämän laitteen sijainnin käyttöoikeuden?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Sovellus saa sijainnin käyttöoikeuden aina, vaikka et käyttäisi sovellusta."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenteri"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"käyttää kalenteria"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; kalenterisi käyttöoikeuden?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; käyttää musiikkiasi?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Kuvat ja videot"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"käyttää kuvia ja videoita"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pääsyn kuviin ja videoihin, mukaan lukien tagattuihin sijainteihin?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Noutaa ikkunan sisältöä"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tarkistaa käyttämäsi ikkunan sisältö."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ottaa kosketuksella tutkimisen käyttöön"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Antaa sovelluksen kommunikoida NFC (Near Field Communication) -tagien, -korttien ja -lukijoiden kanssa."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"poista näytön lukitus käytöstä"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Antaa sovelluksen ottaa näppäinlukon ja siihen liittyvän salasanasuojauksen pois käytöstä. Esimerkki: puhelin poistaa näppäinlukon käytöstä puhelun saapuessa ja asettaa lukon takaisin käyttöön puhelun päättyessä."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"pyytää näytön lukituksen monimutkaisuutta"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Sovellus saa luvan selvittää näytön lukituksen monimutkaisuuden (korkea, keskitaso tai matala) eli sen pituusluokan ja tyypin. Sovellus voi myös ehdottaa käyttäjille näytön lukituksen vaihtamista tietylle tasolle, mutta he voivat ohittaa tämän ja poistua. Itse näytön lukitusta ei säilytetä tekstimuodossa, joten sovellus ei tiedä sitä tarkalleen."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"käytä biometristä laitteistoa"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Sallii sovelluksen käyttää biometristä laitteistoa todennukseen"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"sormenjälkilaitteiston hallinnointi"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Sallii sovelluksen käyttää menetelmiä, joilla voidaan lisätä tai poistaa kasvomalleja."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"käyttää kasvojentodennuslaitteistoa"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Sallii sovelluksen käyttää todennuslaitteistoa todennukseen"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Kasvojen käsittely epäonnistui. Yritä uudelleen."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Kasvokuva on liian kirkas. Kokeile hämärää valoa."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Kasvokuva on liian tumma. Älä peitä valonlähdettä."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Siirrä anturia kauemmas kasvoista."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Tuo anturi lähemmäs kasvoja."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Siirrä anturia korkeammalle."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Siirrä anturia alemmas."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Siirrä anturia oikealle."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Siirrä anturia vasemmalle."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Katso anturia."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Kasvoja ei havaittu."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Laite liikkui liikaa."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Rekisteröi kasvot uudelleen."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Toiset kasvot havaittu."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Liian samanlainen, vaihda asentoa."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Katso suoremmin kameraan."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Katso suoremmin kameraan."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Suorista pää pystysuunnassa."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Älä peitä kasvojasi."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Kasvolaitteisto ei ole käytettävissä."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Kasvotoiminto aikakatkaistiin. Yritä uudelleen."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Kasvoja ei voi tallentaa."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Kasvotoiminto peruutettu"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Käyttäjä peruutti kasvojentunnistuksen."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Liian monta yritystä. Yritä myöhemmin uudelleen."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Liikaa yrityksiä. Kasvojentodennus ei käytössä."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Yritä uudelleen."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Kasvoja ei ole otettu käyttöön."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Laitteessa ei ole kasvojentunnistusanturia."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Kasvot <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Avaa <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> suljetaan tallentamatta tietoja"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ylitti muistirajan."</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Keon vedos on kerätty, jaa se napauttamalla."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Jaetaanko keon vedos?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Prosessi <xliff:g id="PROC">%1$s</xliff:g> on ylittänyt muistirajan (<xliff:g id="SIZE">%2$s</xliff:g>). Keon vedos on jaettavissa kehittäjän kanssa. Ole varovainen: tämä keon vedos voi sisältää sellaisia henkilötietojasi, joihin sovelluksella on käyttöoikeus."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Valitse tekstille toiminto"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Soittoäänen voimakkuus"</string>
     <string name="volume_music" msgid="5421651157138628171">"Median äänenvoimakkuus"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Napauta, niin näet kaikki verkot."</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Yhdistä"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Kaikki verkot"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Wi-Fi-verkko, jota <xliff:g id="NAME">%s</xliff:g> ehdotti, on käytettävissä"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Haluatko muodostaa yhteyden verkkoihin, joita <xliff:g id="NAME">%s</xliff:g> ehdottaa?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Kyllä"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ei"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi käynnistyy automaattisesti"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Kirjaudu verkkoon"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi ei ole yhteydessä internetiin"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Näytä vaihtoehdot napauttamalla."</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Yhdistetty"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Hotspot-asetustesi muutokset"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Hotspot-taajuutesi on muuttunut."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Tämä laite ei tue asetustasi (vain 5 GHz). Sen sijaan laite käyttää 5 GHz:n taajuutta sen ollessa käytettävissä."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Poista USB-virheenkorjaus käytöstä napauttamalla."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Nestettä tai likaa USB-portissa"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-portti poistetaan käytöstä automaattisesti. Napauta nähdäksesi lisätietoja."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB-portin käyttö on turvallista"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Avaa profiili koskettamalla."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> yhdistetty"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Näytä tiedostot koskettamalla"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Kiinnitä"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Irrota"</string>
     <string name="app_info" msgid="6856026610594615344">"Sovelluksen tiedot"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Aloitetaan esittelyä…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Ohjelmatilan tietoilmoitus"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Akku saattaa loppua ennen normaalia latausaikaa"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Virransäästö otettu käyttöön akunkeston pidentämiseksi"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Kansio"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android-sovellus"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Tiedosto"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 78f6ecc..36a47fb 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Chamadas por wifi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivado"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wifi preferida"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Datos móbiles preferidos"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Só por wifi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: non desviada"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de erros"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Finalizar a sesión"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Crear informe de erros"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Este informe recompilará información acerca do estado actual do teu dispositivo para enviala en forma de mensaxe de correo electrónico. O informe de erros tardará un pouco en completarse desde o seu inicio ata que estea preparado para enviarse, polo que che recomendamos que teñas paciencia."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Informe interactivo"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Usa esta opción na maioría das circunstancias. Permíteche realizar un seguimento do progreso do informe, introducir máis detalles sobre o problema e facer capturas de pantalla. É posible que omita algunhas seccións menos usadas para as que se tarda máis en facer o informe."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Localización"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"acceder á localización deste dispositivo"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Queres permitir que a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda á localización deste dispositivo?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"A aplicación só terá acceso á localización mentres a esteas utilizando."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Queres permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda á localización?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"A aplicación sempre terá acceso á localización, aínda que non a esteas utilizando."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder ao teu calendario"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Queres permitir que a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda ao teu calendario?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Queres permitir que a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda á túa música?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotos e vídeos"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"acceder ás fotos e aos vídeos"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Queres permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda ás túas fotos e vídeos, incluídas as localizacións etiquetadas?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar contido da ventá"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona o contido dunha ventá coa que estás interactuando."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar a exploración táctil"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Permite á aplicación comunicarse con etiquetas, tarxetas e lectores Near Field Communication (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivar o bloqueo da pantalla"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite á aplicación desactivar o bloqueo do teclado e calquera seguranza dos contrasinais asociada. Por exemplo, o teléfono desactiva o bloqueo do teclado ao recibir unha chamada telefónica entrante e, a continuación, volve activar o bloqueo do teclado unha vez finalizada a chamada."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"solicitar o nivel de complexidade do bloqueo de pantalla"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Permite que a aplicación consulte o nivel (alto, medio, baixo ou inexistente) de complexidade do bloqueo de pantalla para saber a lonxitude aproximada do contrasinal e o tipo de bloqueo de pantalla. A aplicación tamén pode suxerirlles aos usuarios que aumenten o nivel de complexidade do bloqueo de pantalla, aínda que poden ignorar a suxestión e seguir navegando. Ten en conta que o bloqueo de pantalla non se almacena como texto sen formato, polo que a aplicación non pode consultar o contrasinal exacto."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"utilizar hardware biométrico"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que a aplicación utilice hardware biométrico para a autenticación"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"xestionar hardware de impresión dixital"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que a aplicación invoque métodos para engadir e eliminar modelos faciais de uso."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"usar hardware de autenticación facial"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Permite que a aplicación utilice hardware facial para a autenticación"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Non se puido procesar a cara. Téntao de novo."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"A cara vese demasiado brillante. Proba con menos luz."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"A cara vese demasiado escura. Proba con máis luz."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Afasta o sensor da cara."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Achega o sensor á cara."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Sube máis o sensor."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Baixa o sensor."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Move o sensor cara á dereita."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Move o sensor cara á esquerda."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Mira ao sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Non se detectou ningunha cara."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Demasiado movemento."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Volve rexistrar a túa cara."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Detectouse unha cara diferente."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"É moi similar. Cambia a pose."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Mira máis directamente á cámara."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Mira máis directamente á cámara."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Endereita a cabeza."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Descubre a cara."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"O hardware facial non está dispoñible."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Esgotouse o tempo de espera. Téntao de novo."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Non se puido almacenar a cara."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Cancelouse a operación relacionada coa cara"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"O usuario cancelou a autenticación da cara."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiados intentos. Téntao de novo máis tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Demasiados intentos. Autenticación desactivada."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Téntao de novo."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Non se rexistrou ningunha cara."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Este dispositivo non ten sensor de autenticación de caras."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Abrir a aplicación <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"A aplicación <xliff:g id="OLD_APP">%1$s</xliff:g> pecharase sen gardar o contido"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> superou o límite de memoria"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Recompilouse un baleirado de montóns. Toca para compartilo."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Queres compartir o baleirado de montóns?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"O proceso <xliff:g id="PROC">%1$s</xliff:g> superou o seu límite de memoria de proceso de <xliff:g id="SIZE">%2$s</xliff:g>. Tes dispoñible un baleirado de montóns para compartir co seu programador. Debes ter coidado, pois este baleirado de montóns pode conter información persoal á que ten acceso a aplicación."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Seleccionar unha acción para o texto"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volume do timbre"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volume dos elementos multimedia"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas as redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Hai unha rede wifi dispoñible proposta por <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Queres conectarte ás redes propostas por <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Si"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"A wifi activarase automaticamente"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inicia sesión na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"A wifi non ten acceso a Internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Toca para ver opcións."</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Estableceuse conexión"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Cambios na configuración da zona wifi"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Modificouse a banda da zona wifi."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Este dispositivo non admite a opción de conectarse só a bandas de 5 GHz, pero usaraas se están dispoñibles."</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Toca para desactivar a depuración por USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona a opción para desactivar a depuración por USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hai líquido ou residuos no porto USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"O porto USB desactivouse automaticamente. Toca para obter máis información."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"É seguro usar o porto USB"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Toca para desbloquear o perfil"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toca para ver os ficheiros"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Fixar"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Soltar"</string>
     <string name="app_info" msgid="6856026610594615344">"Info. da aplicación"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demostración…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notificación da información do modo de rutina"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"A batería pode esgotarse antes do habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Para ampliar a duración da batería activouse a función Aforro de batería"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Cartafol"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplicación Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Ficheiro"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 8131c0d..b8e2612 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"વાઇ-ફાઇ કૉલિંગ"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"બંધ"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"વાઇ-ફાઇ પસંદ કર્યું"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"મોબાઇલને પસંદગી"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"ફક્ત વાઇ-ફાઇ"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ફોરવર્ડ કર્યો નથી"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"બગ રિપોર્ટ"</string>
     <string name="global_action_logout" msgid="935179188218826050">"સત્ર સમાપ્ત કરો"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"સ્ક્રીનશૉટ"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"બગ રિપોર્ટ લો"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"આ, એક ઇ-મેઇલ સંદેશ તરીકે મોકલવા માટે, તમારા વર્તમાન ઉપકરણ સ્થિતિ વિશેની માહિતી એકત્રિત કરશે. એક બગ રિપોર્ટ પ્રારંભ કરીને તે મોકલવા માટે તૈયાર ન થઈ જાય ત્યાં સુધી તેમાં થોડો સમય લાગશે; કૃપા કરીને ધીરજ રાખો."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ક્રિયાપ્રતિક્રિયાત્મક રિપોર્ટ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"મોટાભાગના સંજોગોમાં આનો ઉપયોગ કરો. તે રિપોર્ટની પ્રગતિને ટ્રૅક કરવા, સમસ્યા વિશે વધુ વિગતો દાખલ કરવાની અને સ્ક્રીનશૉટ્સ લેવાની મંજૂરી આપે છે. તે કેટલાક ઓછા ઉપયોગમાં આવતાં વિભાગો કે જે જાણ કરવામાં વધુ સમય લેતાં હોય તેને છોડી દઈ શકે છે."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"સ્થાન"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"આ ઉપકરણના સ્થાનને ઍક્સેસ કરવાની"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને આ ઉપકરણના સ્થાનને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"માત્ર જ્યારે તમે ઍપનો ઉપયોગ કરી રહ્યાં હોય ત્યારે જ ઍપ સ્થાનને ઍક્સેસ કરી શકશે."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને હંમેશાં આ ઉપકરણના સ્થાનને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"તમે ઍપનો ઉપયોગ કરી રહ્યાં ન હોય, તો પણ ઍપ હંમેશાં સ્થાનને ઍક્સેસ કરી શકશે."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"કૅલેન્ડર"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"તમારા કેલેન્ડરને ઍક્સેસ કરવાની"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને તમારા કૅલેન્ડરને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને તમારા સંગીતમાં ઍક્સેસ કરવાની મંજૂરી આપવી છે?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ફોટા અને વીડિયો"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"તમારા ફોટો &amp; વિડિઓ ઍક્સેસ કરો"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને તમારા ટૅગ કરેલાં સ્થાનો સહિત ફોટા અને વીડિયો ઍક્સેસ કરવાની મંજૂરી આપવી છે?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"વિંડો કન્ટેન્ટ પુનઃપ્રાપ્ત કરો"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"તમે જેની સાથે ક્રિયા-પ્રતિક્રિયા કરી રહ્યાં છો તે વિંડોનું કન્ટેન્ટ તપાસો."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"સ્પર્શ કરીને શોધખોળ કરવું ચાલુ કરો"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"ઍપ્લિકેશનને નિઅર ફીલ્ડ કમ્યુનિકેશન (NFC) ટૅગ, કાર્ડ અને રીડર સાથે સંચાર કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"તમારું સ્ક્રીન લૉક અક્ષમ કરો"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"એપ્લિકેશનને કીલૉક અને કોઈપણ સંકળાયેલ પાસવર્ડ સુરક્ષા અક્ષમ કરવાની મંજૂરી આપે છે. ઉદાહરણ તરીકે, ઇનકમિંગ ફોન કૉલ પ્રાપ્ત કરતી વખતે ફોન, કીલૉકને અક્ષમ કરે છે, પછી કૉલ સમાપ્ત થઈ જવા પર કીલૉક ફરીથી સક્ષમ કરે છે."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"સ્ક્રીન લૉકની જટિલતા જાણવા માટે વિનંતી કરો"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"ઍપને સ્ક્રીન લૉકની જટિલતાનું લેવલ (ઊંચું, મધ્યમ, નીચું અથવા કોઈ નહીં) જાણવાની મંજૂરી આપે છે, જે સ્ક્રીન લૉકના પ્રકાર અને લંબાઈની સંભવિત શ્રેણી સૂચવે છે. ઍપ વપરાશકર્તાઓને સ્ક્રીન લૉકને ચોક્કસ લેવલ સુધી અપડેટ કરવાનું સૂચન પણ કરી શકે છે, પરંતુ વપરાશકર્તાઓ મુક્ત રીતે તેને અવગણીને નૅવિગેટ કરી શકે છે. એ વાતની નોંધ કરજો કે સ્ક્રીન લૉકનો સાદા ટેક્સ્ટમાં સંગ્રહ કરવામાં આવતો નથી, તેથી ઍપને ચોક્કસ પાસવર્ડની જાણ હોતી નથી."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરો"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"ઍપને પ્રમાણીકરણ માટે બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ફિંગરપ્રિન્ટ હાર્ડવેરને સંચાલિત કરો"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ઍપને ઉપયોગ માટે ચહેરાના નમૂના ઉમેરવા અને ડિલીટ કરવાની પદ્ધતિને રદ કરવાની મંજૂરી આપે છે."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"ચહેરા પ્રમાણીકરણના હાર્ડવેરનો ઉપયોગ કરો"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"ઍપને પ્રમાણીકરણ માટે ચહેરા પ્રમાણીકરણના હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"ચહેરાની પ્રક્રિયા કરી શકાઈ નથી. ફરી પ્રયાસ કરો."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"ચહેરો ખૂબ ચળકે છે. કૃપા કરીને ઓછા પ્રકાશવાળા સ્થાનમાં પ્રયાસ કરો."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"ચહેરો ખૂબ શ્યામ છે. કૃપા કરીને પ્રકાશના સૉર્સ ઉઘાડો."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"કૃપા કરીને સેન્સરને ચહેરાથી દૂર ખસેડો."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"કૃપા કરીને સેન્સરને ચહેરાની નજીક ખસેડો."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"કૃપા કરીને સેન્સરને ઉપર ખસેડો."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"કૃપા કરીને સેન્સર નીચે ખસેડો."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"કૃપા કરીને સેન્સરને જમણી બાજુ ખસેડો."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"કૃપા કરીને સેન્સરને ડાબી બાજુ ખસેડો."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"કૃપા કરીને સેન્સરની સામે જુઓ."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"કોઈ ચહેરો મળ્યો નથી."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"ડિવાઇસ ઘણો હલી રહ્યો છે."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"કૃપા કરીને તમારા ચહેરાની ફરી નોંધણી કરાવો."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"અલગ ચહેરાની ઓળખ થઈ."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ઘણી સમાનતા ધરાવે છે, કૃપા કરીને તમારો પોઝ બદલો."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"કૃપા કરીને કૅમેરા તરફ સીધું જુઓ."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"કૃપા કરીને કૅમેરા તરફ સીધું જુઓ."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"કૃપા કરીને તમારું માથું સીધું ઊભું રાખો."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"કૃપા કરીને તમારો ચહેરો ઢાંકો નહીં."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"ચહેરા માટેનું હાર્ડવેર ઉપલબ્ધ નથી."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"ચહેરા માટેનો સમય સમાપ્ત થયો. ફરી પ્રયાસ કરો."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"ચહેરો સંગ્રહિત કરી શકાશે નહીં."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ચહેરા સંબંધિત કાર્યવાહી રદ કરવામાં આવી છે."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"વપરાશકર્તાએ ચહેરા પ્રમાણીકરણ રદ કર્યુ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ઘણા બધા પ્રયત્નો. થોડા સમય પછી ફરી પ્રયાસ કરો."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ઘણા બધા પ્રયત્નો. ચહેરાનું પ્રમાણીકરણ બંધ કરવામાં આવ્યું છે."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"ફરી પ્રયાસ કરો."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"કોઈ ચહેરાની નોંધણી કરવામાં આવી નથી."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"આ ડિવાઇસમાં ચહેરાના પ્રમાણીકરણ માટે કોઈ સેન્સર નથી."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"ચહેરાનું <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> ખોલો"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> ફેરફારો સાચવ્યા વિના બંધ થશે"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> એ મેમરી સીમા વટાવી"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"હીપ ડમ્પ એકત્રિત કરવામાં આવ્યો છે. શેર કરવા માટે ટૅપ કરો."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"હીપ ડમ્પ શેર કરીએ?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"પ્રક્રિયા <xliff:g id="PROC">%1$s</xliff:g> એ તેની <xliff:g id="SIZE">%2$s</xliff:g> ની પ્રક્રિયા મેમરી મર્યાદા ઓળંગી. તેના વિકાસકર્તા સાથે શેર કરવા તમારી માટે એક હીપ ડમ્પ ઉપલબ્ધ છે. સાવચેત રહો: આ હીપ ડમ્પમાં તમારી વ્યક્તિગત માહિતી શામેલ હોઈ શકે છે કે જેની એપ્લિકેશનને ઍક્સેસ છે."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"ટેક્સ્ટ માટે ક્રિયા પસંદ કરો"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"રિંગર વૉલ્યૂમ"</string>
     <string name="volume_music" msgid="5421651157138628171">"મીડિયા વૉલ્યૂમ"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"બધા નેટવર્ક જોવા ટૅપ કરો"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"કનેક્ટ કરો"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"બધા નેટવર્કો"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> દ્વારા સૂચિત કરવામાં આવેલ વાઇ-ફાઇ નેટવર્ક ઉપલબ્ધ છે"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"તમે <xliff:g id="NAME">%s</xliff:g> દ્વારા સૂચવવામાં આવેલાં નેટવર્ક સાથે કનેક્ટ કરવા માગો છો?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"હા"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ના"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"વાઇ-ફાઇ આપમેળે ચાલુ થઈ જશે"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"નેટવર્ક પર સાઇન ઇન કરો"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"વાઇ-ફાઇને કોઈ ઇન્ટરનેટ ઍક્સેસ નથી"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"વિકલ્પો માટે ટૅપ કરો"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"કનેક્ટેડ"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"તમારી હૉટસ્પૉટ સેટિંગને બદલે છે"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"તમારું હૉટસ્પૉટ બેન્ડ બદલાયેલ છે."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"આ ઉપકરણ તમારી ફક્ત 5GHz માટેની પસંદગીને સમર્થન આપતું નથી. તેના બદલે, જ્યારે આ ઉપકરણ જ્યારે 5GHz બેન્ડ ઉપલબ્ધ હશે ત્યારે તેનો ઉપયોગ કરશે."</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ડીબગિંગ કનેક્ટ થયું."</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB ડિબગીંગ બંધ કરવા માટે ટૅપ કરો"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ડિબગીંગને અક્ષમ કરવા માટે પસંદ કરો."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB પોર્ટમાં પ્રવાહી કે ધૂળ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB પોર્ટ ઑટોમૅટિક રીતે બંધ કરવામાં આવ્યો છે. વધુ જાણવા માટે ટૅપ કરો."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB પોર્ટનો ઉપયોગ કરવો સુરક્ષિત છે"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"કાર્યાલયની પ્રોફાઇલ અનલૉક કરવા ટૅપ કરો"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> થી કનેક્ટ કરેલું છે"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ફાઇલો જોવા માટે ટૅપ કરો"</string>
-    <string name="pin_target" msgid="3052256031352291362">"પિન"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"અનપિન કરો"</string>
     <string name="app_info" msgid="6856026610594615344">"ઍપ્લિકેશન માહિતી"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ડેમો પ્રારંભ કરી રહ્યાં છે…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"રૂટિન મોડની માહિતીનું નોટિફિકેશન"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"સામાન્ય રીતે ચાર્જ કરવાના સમય પહેલાં બૅટરી સમાપ્ત થઈ શકે છે"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"બૅટરી આવરદા વધારવા માટે બૅટરી સેવર ચાલુ કર્યું"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ફોલ્ડર"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android ઍપ"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ફાઇલ"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2fd884e..dca9f86 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"वाई-फ़ाई कॉलिंग"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"बंद"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"वाई-फ़ाई को प्राथमिकता"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"मोबाइल को प्राथमिकता"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"केवल वाई-फ़ाई"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अग्रेषित नहीं किया गया"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"गड़बड़ी की रिपोर्ट"</string>
     <string name="global_action_logout" msgid="935179188218826050">"सत्र खत्म करें"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"स्क्रीनशॉट"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"गड़बड़ी की रिपोर्ट लें"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"इससे ईमेल भेजने के लिए, आपके डिवाइस की मौजूदा स्थिति से जुड़ी जानकारी इकट्ठा की जाएगी. गड़बड़ी की रिपोर्ट बनना शुरू होने से लेकर भेजने के लिए तैयार होने तक कुछ समय लगेगा; कृपया इंतज़ार करें."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"सहभागी रिपोर्ट"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"अधिकांश परिस्थितियों में इसका उपयोग करें. यह आपको रिपोर्ट की प्रगति ट्रैक करने देता है, समस्या के बारे में अधिक विवरण डालने देता है और स्क्रीनशॉट लेने देता है. यह आपको ऐसे कम उपयोग किए गए अनुभाग मिटाने दे सकता है जिनकी रिपोर्ट करने में अधिक समय लगता है."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"जगह"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"इस डिवाइस की जगह तक पहुंचने दें"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को इस डिवाइस की \'जगह की जानकारी\' ऐक्सेस करने की अनुमति देना चाहते हैं?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"ऐप्लिकेशन, डिवाइस की \'जगह की जानकारी\' सिर्फ़ तभी देख पाएगा जब आप इसका इस्तेमाल कर रहे हों."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को हमेशा डिवाइस की \'जगह की जानकारी\' एक्सेस करने दें?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"ऐप्लिकेशन के पास हमेशा डिवाइस की \'जगह की जानकारी\' देखने की मंज़ूरी होगी, तब भी जब आप इसका इस्तेमाल न कर रहे हों."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"कैलेंडर"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"अपने कैलेंडर को ऐक्सेस करने"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को अपना कैलेंडर देखने की अनुमति देना चाहते हैं?"</string>
@@ -308,17 +314,17 @@
     <string name="permgrouplab_phone" msgid="5229115638567440675">"फ़ोन"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"फ़ोन कॉल करने और उन्हें प्रबंधित करने की अनुमति दें"</string>
     <string name="permgrouprequest_phone" msgid="9166979577750581037">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को फ़ोन कॉल करने और उन्हें प्रबंधित करने की अनुमति दें?"</string>
-    <!-- no translation found for permgrouplab_sensors (4838614103153567532) -->
-    <skip />
+    <string name="permgrouplab_sensors" msgid="4838614103153567532">"बॉडी सेंसर"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"अपने महत्वपूर्ण संकेतों के बारे में सेंसर डेटा को ऐक्सेस करें"</string>
     <string name="permgrouprequest_sensors" msgid="6349806962814556786">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को अपने स्वास्थ्य से जुड़ी ज़रूरी जानकारी इस्तेमाल करने की अनुमति देना चाहते हैं?"</string>
     <string name="permgrouplab_aural" msgid="965607064083134896">"संगीत"</string>
     <string name="permgroupdesc_aural" msgid="4870189506255958055">"अपना संगीत संग्रह एक्सेस करने दें"</string>
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को अपना संगीत एक्सेस करने दें?"</string>
-    <!-- no translation found for permgrouplab_visual (6477382108771145134) -->
-    <skip />
+    <string name="permgrouplab_visual" msgid="6477382108771145134">"फ़ोटो और वीडियो"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"अपने फ़ोटो और वीडियो एक्सेस करने दें"</string>
-    <!-- no translation found for permgrouprequest_visual (3043752127595243314) -->
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
     <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडो की सामग्री वापस पाएं"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"उस विंडो की सामग्री की जाँच करें, जिसका आप इस्तेमाल कर रहे हैं."</string>
@@ -512,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"ऐप्स  को नियर फ़ील्ड कम्यूनिकेशन (NFC) टैग, कार्ड, और रीडर के साथ संचार करने देता है."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"अपना स्‍क्रीन लॉक अक्षम करें"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ऐप्स को कीलॉक और कोई भी संबद्ध पासवर्ड सुरक्षा अक्षम करने देता है. उदाहरण के लिए, इनकमिंग फ़ोन कॉल प्राप्त करते समय फ़ोन, कीलॉक को अक्षम कर देता है, फिर कॉल समाप्त होने पर कीलॉक को पुन: सक्षम कर देता है."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"जानें कि स्क्रीन लॉक कितना मुश्किल है"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"यह मंज़ूरी मिलने के बाद ऐप्लिकेशन जान पाता है कि स्क्रीन लॉक कितना मुश्किल (बहुत ज़्यादा, मध्यम, कम या बिल्कुल नहीं) है. इस स्तर से यह पता चलता है कि स्क्रीन लॉक कितना लंबा या किस तरह का है. ऐप्लिकेशन उपयोगकर्ताओं को यह सुझाव भी दे सकता है कि वे स्क्रीन लॉक को एक तय स्तर तक अपडेट करें. हालांकि, उपयोगकर्ता बेझिझक इसे अनदेखा करके आगे बढ़ सकते हैं. ध्यान दें कि स्क्रीन लॉक को सादे टेक्स्ट में सेव नहीं किया जाता है इसलिए ऐप्लिकेशन को बिल्कुल सही पासवर्ड पता नहीं होता."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"बायोमीट्रिक हार्डवेयर इस्तेमाल करने दें"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"पुष्टि के लिए, ऐप्लिकेशन को बायोमीट्रिक हार्डवेयर इस्तेमाल करने की मंज़ूरी दें"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"उंगली की छाप के लिए हार्डवेयर को प्रबंधित करें"</string>
@@ -568,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ऐप्लिकेशन को चेहरे के टेम्पलेट इस्तेमाल के तरीके जोड़ने और मिटाने की मंज़ूरी मिलती है."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"चेहरे की पुष्टि करने वाला हार्डवेयर इस्तेमाल करें"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"ऐप्लिकेशन को चेहरे की पुष्टि करने वाले हार्डवेयर का इस्तेमाल करने की मंज़ूरी मिलती है"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"चेहरे की पहचान नहीं हो पाई. कृपया फिर कोशिश करें."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"चेहरे पर रोशनी ज़्यादा है. कृपया कम रोशनी में कोशिश करें."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"चेहरे पर रोशनी बहुत कम है. कृपया रोशनी बढ़ाएं."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"कृपया डिवाइस को चेहरे से दूर ले जाएं."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"कृपया डिवाइस को चेहरे के करीब लाएं."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"कृपया डिवाइस को ऊपर करें."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"कृपया डिवाइस को नीचे की ओर ले जाएं."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"कृपया डिवाइस को चेहरे की दाईं ओर ले जाएं."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"कृपया डिवाइस को चेहरे के बाईं ओर ले जाएं."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"कृपया सेंसर की ओर देखें."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"चेहरे की पहचान नहीं हो पाई."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"डिवाइस बहुत ज़्यादा हिल रहा है."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"कृपया फिर से अपने चेहरे की पहचान कराएं."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"यह चेहरा किसी और का है."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"चेहरा काफ़ी मिलता-जुलता है, कृपया अपना पोज़ बदलें."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"कृपया कैमरे की तरफ़ सीधा देखें."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"कृपया कैमरे की तरफ़ सीधा देखें."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"कृपया अपना सिर सीधा करें, दाएं-बाएं न झुकाएं"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"चेहरा साफ़ नहीं दिख रहा. कृपया रोशनी बढ़ाएं."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"चेहरे की पहचान करने वाला हार्डवेयर मौजूद नहीं है."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"चेहरे की पहचान का समय खत्म हुआ. फिर से कोशिश करें."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"चेहरा सेव करने की सीमा पूरी हो गई है."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"चेहरा पहचानने की कार्रवाई रद्द की गई."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"उपयोगकर्ता ने चेहरे की पहचान रद्द कर दी."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"कई बार कोशिश की गई. बाद में कोशिश करें."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"कई बार कोशिश की. चेहरा पहचानने की सुविधा बंद हुई."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"फिर से कोशिश करें."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"कोई चेहरा रजिस्टर नहीं किया गया है."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"इस डिवाइस में चेहरे की पहचान करने वाला सेंसर नहीं है."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1216,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> खोलें"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> बिना सेव किए बंद हो जाएगा"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> मेमोरी सीमा को पार कर गई है"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"हीप डंप (Java™ प्रोसेस मेमोरी का स्नैपशॉट) ले लिया गया है. शेयर करने के लिए टैप करें."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"हीप डंप शेयर करें?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"यह प्रक्रिया <xliff:g id="PROC">%1$s</xliff:g> इसकी <xliff:g id="SIZE">%2$s</xliff:g> की मेमोरी की सीमा को पार कर गई है. एक हीप डंप मौजूद है जिसे आप इसके डेवलपर से शेयर कर सकते हैं. सावधान रहें: इस हीप डंप में आपकी ऐसी कोई भी निजी जानकारी हो सकती है जिस पर ऐप्लिकेशन की पहुंच हो."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"मैसेज करने के लिए कोई कार्रवाई चुनें"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"रिंगर वॉल्‍यूम"</string>
     <string name="volume_music" msgid="5421651157138628171">"मीडिया वॉल्‍यूम"</string>
@@ -1257,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सभी नेटवर्क देखने के लिए यहां पर टैप करें"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करें"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"सभी नेटवर्क"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> का बताया हुआ वाई-फ़ाई नेटवर्क उपलब्ध नहीं है"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"क्या आप <xliff:g id="NAME">%s</xliff:g> के बताए हुए नेटवर्क से कनेक्ट करना चाहते हैं?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"हां"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"नहीं"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"वाई-फ़ाई अपने आप चालू हो जाएगा"</string>
@@ -1270,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"नेटवर्क में साइन इन करें"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"वाई-फ़ाई के लिए इंटरनेट नहीं मिल रहा है"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"विकल्पों के लिए टैप करें"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"जुड़ गया है"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"आपकी हॉटस्पॉट सेटिंग के हिसाब से बदलाव हो गए हैं"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"आपका हॉटस्पॉट बैंड बदल गया है."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"यह डिवाइस सिर्फ़ 5 गीगाहर्ट्ज़ की आपकी पसंद की सेटिंग पर काम नहीं करता, लेकिन जब भी 5 गीगाहर्ट्ज़ बैंड मौजूद होगा, डिवाइस उसका इस्तेमाल करने लगेगा."</string>
@@ -1357,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"डीबग करने के लिए एडीबी कनेक्ट किया गया"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"यूएसबी को डीबग करने की सुविधा बंद करने के लिए टैप करें"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबग करना अक्षम करने के लिए चुनें."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"यूएसबी पोर्ट में तरल चीज़ या कचरा है"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"यूएसबी पोर्ट अपने आप बंद हो गया है. ज़्यादा जानने के लिए टैप करें."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"यूएसबी पोर्ट का इस्तेमाल करना सुरक्षित है"</string>
@@ -1908,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"कार्य प्रोफाइल अनलॉक करने हेतु टैप करें"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> से कनेक्ट किया गया"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"फ़ाइलें देखने के लिए टैप करें"</string>
-    <string name="pin_target" msgid="3052256031352291362">"पिन करें"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"अनपिन करें"</string>
     <string name="app_info" msgid="6856026610594615344">"ऐप्लिकेशन की जानकारी"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"डेमो प्रारंभ हो रहा है…"</string>
@@ -2000,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"रूटीन मोड जानकारी की सूचना"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"बैटरी आम तौर पर जितने समय चलती है, उससे पहले खत्म हो सकती है"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"बैटरी लाइफ़ बढ़ाने के लिए \'बैटरी सेवर\' चालू हो गया है"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"फ़ोल्डर"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android ऐप्लिकेशन"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"फ़ाइल"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index d50fda6..478fdad 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -142,8 +142,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi pozivi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi mreža"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Za mobilne uređaje"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije proslijeđeno"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -230,7 +232,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izvješće o bugovima"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Završi sesiju"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snimka zaslona"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Izvješće o programskoj pogrešci"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Time će se prikupiti podaci o trenutačnom stanju vašeg uređaja koje ćete nam poslati u e-poruci. Za pripremu izvješća o programskoj pogrešci potrebno je nešto vremena pa vas molimo za strpljenje."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktivno izvješće"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"To možete upotrebljavati u većini slučajeva. Moći ćete pratiti izradu izvješća, unijeti više pojedinosti o problemu i izraditi snimke zaslona. Mogu se izostaviti neki odjeljci koji se upotrebljavaju rjeđe i produljuju izradu izvješća."</string>
@@ -284,9 +287,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"pristupiti lokaciji ovog uređaja"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Želite li dopustiti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupa lokaciji ovog uređaja?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplikacija će imati pristup lokaciji samo dok upotrebljavate aplikaciju."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Želite li dopustiti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupa lokaciji ovog uređaja?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplikacija će uvijek imati pristup lokaciji, čak i dok ne upotrebljavate aplikaciju."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupati kalendaru"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Želite li dopustiti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupa vašem kalendaru?"</string>
@@ -319,7 +325,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Želite li dopustiti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da pristupa vašoj glazbi?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotografije i videozapisi"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"pristup fotografijama i &amp; videozapisima"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Želite li dopustiti da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pristupa vašim fotografijama i videozapisima, uključujući označene lokacije?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Dohvaćati sadržaj prozora"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Pregledat će sadržaj prozora koji upotrebljavate."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključiti značajku Istraži dodirom"</string>
@@ -512,8 +521,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Aplikaciji omogućuje komunikaciju s oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogućavanje zaključavanja zaslona"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Aplikaciji omogućuje onemogućavanje zaključavanja tipkovnice i svih pripadajućih sigurnosnih zaporki. Na primjer, telefon onemogućuje zaključavanje tipkovnice kod primanja dolaznog telefonskog poziva, nakon kojeg se zaključavanje tipkovnice ponovo omogućuje."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"zahtijevati složenost zaključavanja zaslona"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Omogućuje aplikaciji da sazna razinu složenosti zaključavanja zaslona (visoka, srednja, niska ili nijedna), što upućuje na mogući raspon duljine i vrstu zaključavanja zaslona. Aplikacija također korisnicima može predložiti da ažuriraju zaključavanje zaslona na određenu razinu, no korisnici to mogu slobodno zanemariti i nastaviti dalje. Napominjemo da se zaključavanje zaslona ne pohranjuje u običnom tekstu, pa aplikacija ne zna točnu zaporku."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"koristiti biometrijski hardver"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Aplikaciji omogućuje upotrebu biometrijskog hardvera radi autentifikacije"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljanje hardverom za čitanje otisaka prstiju"</string>
@@ -568,37 +579,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Aplikaciji omogućuje pozivanje načina za dodavanje i brisanje predložaka lica za upotrebu."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"upotrebljavati hardver za autentifikaciju lica"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Aplikaciji omogućuje upotrebu hardvera za autentifikaciju lica radi autentifikacije"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Obrada lica nije uspjela. Pokušajte ponovo."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Lice je presvijetlo. Smanjite osvjetljenje."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Lice je pretamno. Otkrijte izvor svjetlosti."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Odmaknite senzor od lica."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Približite senzor licu."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Podignite senzor."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Spustite senzor."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Pomaknite senzor udesno."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Pomaknite senzor ulijevo."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Gledajte senzor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Lice nije otkriveno."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Previše kretanja."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Ponovo registrirajte svoje lice."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Otkriveno je neko drugo lice."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Previše slično, promijenite pozu."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Gledajte izravnije u kameru."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Gledajte izravnije u kameru."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Izravnajte glavu okomito."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Otkrijte lice."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardver za lice nije dostupan."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Isteklo je vrijeme čekanja za lice. Pokušajte opet"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Nije moguće pohraniti lice."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Otkazana je radnja s licem."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Autentifikaciju lica otkazao je korisnik."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Previše pokušaja. Autentifikacija lica onemogućena"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Pokušajte ponovo."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nije registrirano nijedno lice."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Ovaj uređaj nema senzor za autentifikaciju lica."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1233,9 +1266,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Otvori aplikaciju <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"Aplikacija <xliff:g id="OLD_APP">%1$s</xliff:g> zatvorit će se bez spremanja"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> premašio je ograničenje memorije"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Generirana je snimka memorije. Dodirnite za dijeljenje."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Žalite li dijeliti snimku memorije procesa?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> premašio je ograničenje memorije od <xliff:g id="SIZE">%2$s</xliff:g>. Dostupna vam je snimka memorije procesa koju možete podijeliti s razvojnim programerom. Budite oprezni: ta snimka memorije može sadržavati vaše osobne podatke kojoj aplikacija ima pristup."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Izaberite radnju za tekst"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Glasnoća zvona"</string>
     <string name="volume_music" msgid="5421651157138628171">"Glasnoća medija"</string>
@@ -1276,8 +1316,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite za prikaz svih mreža"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Dostupna je Wi‑Fi mreža koju predlaže <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Želite li se povezati s mrežama koje predlaže <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi će se uključiti automatski"</string>
@@ -1289,9 +1331,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi nema pristup internetu"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Dodirnite za opcije"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Povezano"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Promjene postavki vaše žarišne točke"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Promijenila se frekvencija vaše žarišne točke."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Ovaj uređaj ne podržava vašu postavku za upotrebu samo 5 GHz. Upotrebljavat će frekvenciju od 5 GHz kada je dostupna."</string>
@@ -1376,6 +1423,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za otklanjanje pogrešaka putem USB-a"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Dodirnite da biste isključili otklanjanje pogrešaka putem USB-a"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tekućina ili prljavština u USB priključku"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB priključak automatski je onemogućen. Dodirnite da biste saznali više."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Upotreba USB priključka ponovo je sigurna"</string>
@@ -1939,8 +1990,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Dodirnite za otključavanje"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> – veza je uspostavljena"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dodirnite da biste pregledali datoteke"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Prikvači"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Otkvači"</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Pokretanje demo-načina..."</string>
@@ -2032,6 +2081,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Obavještavanje o informacijama u Rutinskom načinu rada"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Baterija se može isprazniti prije uobičajenog vremena punjenja"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Štednja baterije aktivirana je kako bi se produljilo trajanje baterije"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Mapa"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android aplikacija"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Datoteka"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 5d0086b..2632482 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi-hívás"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Ki"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi előnyben részesítve"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferált: mobil"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Csak Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: nincs átirányítva"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Programhiba bejelentése"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Munkamenet befejezése"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Képernyőkép"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Hibajelentés készítése"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Ezzel információt fog gyűjteni az eszköz jelenlegi állapotáról, amelyet a rendszer e-mailben fog elküldeni. Kérjük, legyen türelemmel, amíg a hibajelentés elkészül, és küldhető állapotba kerül."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktív jelentés"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Ezt használja a legtöbb esetben. Segítségével nyomon követheti a jelentés folyamatát, további részleteket adhat meg a problémáról, illetve képernyőképeket készíthet. A folyamat során kimaradhatnak az olyan kevésbé használt részek, amelyek jelentése túl sok időt igényel."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Helyadatok"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"hozzáférés az eszköz földrajzi helyéhez"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Engedélyezi a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; számára, hogy hozzáférjen az eszköz helyadataihoz?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Az alkalmazás csak akkor férhet hozzá a helyadatokhoz, amikor használja az alkalmazást."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Engedélyezi, hogy a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; hozzáférjen a helyadatokhoz?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Az alkalmazás bármikor hozzáférhet majd a helyadatokhoz, akkor is, amikor nem használja az alkalmazást."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Naptár"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"hozzáférés a naptárhoz"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Engedélyezi a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; számára, hogy hozzáférjen a naptárhoz?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Engedélyezi a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&amp;gt számára, hogy hozzáférjen az Ön zenéihez?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotók és videók"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"hozzáférés a fényképekhez és videókhoz"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Engedélyezi a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; számára a fotókhoz és videókhoz (köztük a címkézett helyekhez) való hozzáférést?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ablaktartalom lekérdezése"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"A használt ablak tartalmának vizsgálata."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Felfedezés érintéssel bekapcsolása"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Lehetővé teszi az alkalmazás számára, hogy NFC (Near Field Communication - kis hatósugarú vezeték nélküli kommunikáció) technológiát használó címkékkel, kártyákkal és leolvasókkal kommunikáljon."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"képernyőzár kikapcsolása"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Lehetővé teszi az alkalmazás számára a billentyűzár és bármely kapcsolódó jelszavas védelem kikapcsolását. Például a telefon feloldja a billentyűzárat bejövő hívás esetén, majd újra bekapcsolja azt a hívás végeztével."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"képernyőzár összetettségi szintjének lekérése"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Lehetővé teszi az alkalmazás számára, hogy megismerje a képernyőzár összetettségi szintjét (magas, közepes, alacsony vagy nincs), amely jelzi a képernyőzár lehetséges típusát és hosszát. Az alkalmazás ezenkívül javaslatot tehet a felhasználóknak a képernyőzár bizonyos szintre való frissítésére, de ezt a javaslatot a felhasználók figyelmen kívül hagyhatják. A képernyőzárat nem egyszerű szöveges formátumban tárolja a rendszer, ezért az alkalmazás nem fogja tudni a pontos jelszót."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"biometrikus hardver használata"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Lehetővé teszi az alkalmazás számára a biometrikus hardver hitelesítésre való használatát"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ujjlenyomat-olvasó hardver kezelése"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Engedélyezi, hogy az alkalmazás arcsablon-hozzáadási és -törlési metódusokat hívjon."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"arcfelismerő hardver használata"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Engedélyezi, hogy az alkalmazás hitelesítésre használja az arcfelismerő hardvert"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Nem sikerült feldolgozni az arcot. Próbálja újra."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Az arc túl világos. Kevesebb fény szükséges."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Az arc túl sötét. Több fény szükséges."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Tartsa az érzékelőt távolabb az arctól."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Tartsa az érzékelőt közelebb az archoz."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Emelje magasabbra az érzékelőt."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Engedje lejjebb az érzékelőt."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Mozdítsa el jobbra az érzékelőt."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Mozdítsa el balra az érzékelőt."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Nézzen az érzékelőbe."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nem észlelhető arc."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Túlságosan sok a mozgás."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Rögzítsen újra képet az arcáról."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Másik arcot észleltünk."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Túlságosan hasonló, változtasson a pózon."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Nézzen szemből a kamerába."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Nézzen szemből a kamerába."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Fejét tartsa egyenesen, függőleges irányban."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Ne takarja el az arcát."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Az arcfelismerő hardver nem áll rendelkezésre."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Időtúllépés az arcbeolvasásnál. Próbálja újra."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Az arc nem tárolható."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Az arccal kapcsolatos művelet törölve."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Az arc hitelesítését a felhasználó visszavonta."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Túl sok próbálkozás. Próbálja újra később."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Túl sok próbálkozás. Arcfelismerés letiltva."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Próbálkozzon újra."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nincs regisztrált arc."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Ez az eszköz nem rendelkezik arcfelismerő érzékelővel."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> arc"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> megnyitása"</string>
     <string name="new_app_description" msgid="5894852887817332322">"A(z) <xliff:g id="OLD_APP">%1$s</xliff:g> mentés nélkül bezáródik"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"A(z) <xliff:g id="PROC">%1$s</xliff:g> túllépte a memóriakorlátot"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Elkészült a memória-pillanatfelvétel (heap dump). A megosztáshoz koppintson rá."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Megosztja a memória-pillanatfelvételt?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"A(z) <xliff:g id="PROC">%1$s</xliff:g> folyamat túllépte a(z) <xliff:g id="SIZE">%2$s</xliff:g> méretű memóriakorlátot. Elérhető a memória-pillanatfelvétel (heap dump), hogy megossza a fejlesztővel. Figyelem: ez a felvétel tartalmazhatja az Ön olyan személyes adatait, amelyekhez az alkalmazásnak hozzáférése van."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Válasszon ki egy műveletet a szöveghez"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Csengetés hangereje"</string>
     <string name="volume_music" msgid="5421651157138628171">"Média hangereje"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Koppintással megjelenítheti az összes hálózatot"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kapcsolódás"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Összes hálózat"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Rendelkezésre áll egy <xliff:g id="NAME">%s</xliff:g> által javasolt Wi-Fi-hálózat"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Szeretne csatlakozni a(z) <xliff:g id="NAME">%s</xliff:g> által javasolt hálózatokhoz?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Igen"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nem"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"A Wi-Fi automatikusan bekapcsol"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Bejelentkezés a hálózatba"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"A Wi-Fi-hálózaton nincs internetkapcsolat"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Koppintson a beállítások megjelenítéséhez"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Csatlakozva"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"A hotspot beállításainak módosítása"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"A hotspot sávja megváltozott."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Ez az eszköz nem támogatja a csak 5 GHz-es sávra vonatkozó beállítást. Az eszköz akkor használ 5 GHz-es sávot, ha a sáv rendelkezésre áll."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Koppintson az USB-hibakeresés kikapcsolásához"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Folyadék vagy szennyeződés az USB-portban"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-port automatikusan letiltva. Koppintson, ha további információra van szüksége."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Az USB-port biztonságosan használható"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"A feloldáshoz koppintson rá"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Csatlakoztatva a(z) <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> eszközhöz"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Koppintson ide a fájlok megtekintéséhez"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Rögzítés"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Feloldás"</string>
     <string name="app_info" msgid="6856026610594615344">"Alkalmazásinformáció"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Bemutató indítása…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Információs értesítés a rutinmódról"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Előfordulhat, hogy az akkumulátor lemerül a szokásos töltési időszak előtt"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Akkumulátorkímélő mód aktiválva az akkumulátor üzemidejének növelése érdekében"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Mappa"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android-alkalmazás"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fájl"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 6432e37..dc77319 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Panggilan WiFi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Nonaktif"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi dipilih"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Seluler dipilih"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Khusus Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Tidak diteruskan"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Laporan bug"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Akhiri sesi"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan bug"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpulkan informasi status perangkat Anda saat ini, untuk dikirimkan sebagai pesan email. Harap bersabar, mungkin perlu waktu untuk memulai laporan bug hingga siap dikirim."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Laporan interaktif"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Gunakan ini di berbagai keadaan. Ini memungkinkan Anda melacak kemajuan laporan, memasukkan detail masalah selengkapnya, dan mengambil screenshot. Mungkin menghilangkan beberapa bagian yang jarang digunakan dan yang perlu waktu lama untuk dilaporkan."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokasi"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"mengakses lokasi perangkat ini"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses lokasi perangkat ini?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplikasi ini hanya akan memiliki akses ke lokasi saat Anda sedang menggunakan aplikasi."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Selalu izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses lokasi perangkat ini?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplikasi ini akan selalu memiliki akses ke lokasi, bahkan saat Anda sedang tidak menggunakan aplikasi."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"mengakses kalender"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses kalender?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; untuk mengakses musik?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Foto &amp; video"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"mengakses foto &amp; video Anda"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses foto dan video Anda, termasuk lokasi yang diberi tag?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Mengambil konten jendela"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Memeriksa konten jendela tempat Anda berinteraksi."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Mengaktifkan Jelajahi dengan Sentuhan"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Mengizinkan apl berkomunikasi dengan tag, kartu, dan alat pembaca Komunikasi Nirkabel Jarak Dekat (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"nonaktifkan kunci layar Anda"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Memungkinkan aplikasi menonaktifkan kunci tombol dan keamanan sandi apa pun yang terkait. Misalnya, ponsel menonaktifkan kunci tombol saat menerima panggilan telepon masuk, kemudian mengaktifkan kembali kunci tombol ketika panggilan selesai."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"meminta kompleksitas kunci layar"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Mengizinkan aplikasi mempelajari tingkat kompleksitas kunci layar (tinggi, sedang, rendah, atau tidak ada), yang menunjukkan kemungkinan rentang durasi dan jenis kunci layar. Aplikasi juga dapat menyarankan agar pengguna memperbarui kunci layar ke tingkat tertentu, namun pengguna dapat mengabaikan dan keluar dengan bebas. Perlu diperhatikan bahwa kunci layar tidak disimpan dalam teks biasa, sehingga aplikasi tidak mengetahui sandi yang sebenarnya."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"gunakan hardware biometrik"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Mengizinkan aplikasi menggunakan hardware biometrik untuk autentikasi"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"kelola hardware sidik jari"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Mengizinkan apl memicu metode untuk menambah &amp; menghapus template wajah untuk digunakan."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"gunakan hardware autentikasi wajah"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Mengizinkan aplikasi untuk menggunakan hardware autentikasi wajah untuk autentikasi"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Tidak dapat memproses wajah. Harap coba lagi."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Wajah terlalu cerah. Coba dengan cahaya lebih redup."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Wajah terlalu gelap. Buka sumber cahaya."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Jauhkan sensor dari wajah."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Dekatkan sensor ke wajah."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Naikkan sensor."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Turunkan sensor."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Gerakkan sensor ke kanan."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Gerakkan sensor ke kiri."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Lihat sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Tidak ada wajah yang terdeteksi"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Terlalu banyak gerakan."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Daftarkan ulang wajah Anda."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Wajah yang berbeda terdeteksi."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Terlalu mirip, ubah pose Anda."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Lihat langsung ke kamera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Lihat langsung ke kamera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Luruskan kepala secara vertikal."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Tunjukkan wajah Anda."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardware pemrosesan wajah tidak tersedia."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Waktu tunggu wajah habis. Harap coba lagi."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Wajah tidak dapat disimpan."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Pemrosesan wajah dibatalkan."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Autentikasi wajah dibatalkan oleh pengguna."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Terlalu banyak percobaan. Coba lagi nanti."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Terlalu sering dicoba. Autentikasi wajah dinonaktifkan."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Coba lagi."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Tidak ada wajah yang didaftarkan."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Perangkat ini tidak memiliki sensor autentikasi wajah."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> wajah"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Buka <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> akan ditutup tanpa menyimpan"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> melampaui batas memori"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Informasi memori dikumpulkan. Tap untuk membagikan."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share tumpukan membuang?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Proses <xliff:g id="PROC">%1$s</xliff:g> telah melampaui batas memori proses <xliff:g id="SIZE">%2$s</xliff:g>. Tumpukan sampah tersedia untuk Anda bagikan kepada pengembangnya. Hati-hati, tumpukan sampah ini hanya dapat memuat informasi pribadi yang dapat diakses oleh aplikasi."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Pilih tindakan untuk teks"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volume dering"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volume media"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap untuk melihat semua jaringan"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Hubungkan"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Semua jaringan"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Jaringan Wi‑Fi yang diusulkan oleh <xliff:g id="NAME">%s</xliff:g> tersedia"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Sambungkan ke jaringan yang diusulkan oleh <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ya"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Tidak"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi akan aktif otomatis"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Login ke jaringan"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi tidak memiliki akses internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tap untuk melihat opsi"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Tersambung"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Perubahan pada setelan hotspot Anda"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Pita hotspot Anda telah berubah."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Perangkat ini tidak mendukung preferensi Anda, yaitu hanya 5GHz. Sebagai gantinya, perangkat ini akan menggunakan pita frekuensi 5GHz jika tersedia."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tap untuk menonaktifkan debug USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Cairan atau kotoran di port USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB otomatis dinonaktifkan. Tap untuk mempelajari lebih lanjut."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Port USB aman digunakan"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap untuk membuka kunci profil kerja"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Tersambung ke <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tap untuk melihat file"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Pasang pin"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Lepas pin"</string>
     <string name="app_info" msgid="6856026610594615344">"Info aplikasi"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Memulai demo..."</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notifikasi info Mode Rutinitas"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Baterai mungkin habis sebelum pengisian daya biasanya"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Penghemat Baterai diaktifkan untuk memperpanjang masa pakai baterai"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folder"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplikasi Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"File"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index d27d8b5..3f8c960 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WiFi símtöl"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Slökkt"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi í forgangi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Farsímakerfi í forgangi"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi eingöngu"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Ekki áframsent"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Villutilkynning"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Ljúka lotu"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skjámynd"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Útbúa villutilkynningu"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Þetta safnar upplýsingum um núverandi stöðu tækisins til að senda með tölvupósti. Það tekur smástund frá því villutilkynningin er ræst og þar til hún er tilbúin til sendingar – sýndu biðlund."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Gagnvirk skýrsla"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Þú getur notað þetta í flestum tilvikum. Með þessu móti geturðu fylgst með framgangi tilkynningarinnar og slegið inn viðbótarupplýsingar um vandamálið. Hugsanlegt er að lítið notuðum hlutum verði sleppt til að spara tíma."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Staðsetning"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"fá aðgang að staðsetningu þessa tækis"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Viltu veita &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aðgang að staðsetningu þessa tækis?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Forritið hefur aðeins aðgang að staðsetningunni á meðan þú notar forritið."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Viltu alltaf veita &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aðgang að staðsetningu þessa tækis?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Forritið hefur alltaf aðgang að staðsetningunni, jafnvel þegar þú ert ekki að nota forritið."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Dagatal"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"fá aðgang að dagatalinu þínu"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Viltu veita &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aðgang að dagatalinu þínu?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Viltu veita &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aðgang að tónlistinni þinni?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Myndir og myndskeið"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"fá aðgang að myndunum og myndskeiðunum þínum"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Viltu veita &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aðgang að myndunum þínum og myndskeiðum, þ.m.t. merktum staðsetningum?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Sækja innihald glugga"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kanna innihald glugga sem þú ert að nota."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Kveikja á snertikönnun"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Leyfir forriti að eiga samskipti við NFC-merki, -spjöld og -lesara (nándarsamskipti)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"slökkva á skjálásnum"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Leyfir forriti að slökkva á símalásnum og öðrum öryggisaðgerðum tengdum aðgangsorði. Til dæmis gerir síminn lásinn óvirkan þegar símtal berst og læsist svo aftur að símtali loknu."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"biðja um flókinn skjálás"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Leyfir forritinu að læra hversu flókinn skjálásinn er (erfiður, miðlungs, léttur eða enginn), sem gefur til kynna lengd og tegund skjálássins. Forritið getur einnig lagt til að notendur geri skjálásinn flóknari upp að tilteknu marki, en notendur geta valið að hunsa það og halda áfram að vafra. Hafðu í huga að skjálásinn er ekki geymdur í ódulkóðuðum texta svo forritið veit ekki nákvæmt aðgangsorð."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"nota búnað fyrir líffræðileg gögn"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Leyfir forritinu að nota búnað fyrir líffræðileg gögn til auðkenningar"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"stjórna fingrafarabúnaði"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Leyfir forritinu að beita aðferðum til að bæta við og eyða andlitssniðmátum til notkunar."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"nota vélbúnað andlitsgreiningar"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Leyfir forritinu að nota andlitsgreiningarvélbúnað til auðkenningar"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Ekki tókst að vinna úr andlitinu. Reyndu aftur."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Andlitið er of bjart. Prófaðu í minni birtu."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Andlitið er of dökkt. Finndu betri lýsingu."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Færðu skynjarann lengra frá andlitinu."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Færðu skynjarann nær andlitinu."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Færðu skynjarann ofar."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Færðu skynjarann neðar."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Færðu skynjarann til hægri."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Færðu skynjarann til vinstri."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Horfðu á skynjarann."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Ekkert andlit fannst."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Of mikil hreyfing."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Skráðu nafnið þitt aftur."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Annað andlit greint."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Of svipað. Stilltu þér öðruvísi upp."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Líttu beint í myndavélina."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Líttu beint í myndavélina."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Vinsamlega réttu úr höfðinu."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Ekki hylja andlitið."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Andlitsvélbúnaður ekki til staðar."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Tímamörk runnu út fyrir andlit. Reyndu aftur."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Ekki tókst að geyma andlit."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Hætt við andlitsgreiningu."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Notandi hætti við andlitsgreiningu."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Of margar tilraunir. Reyndu aftur síðar."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Of margar tilraunir. Slökkt á andlitsgreiningu."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Reyndu aftur."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Ekkert andlit skráð."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Þetta tæki er ekki með skynjara fyrir andlitsgreiningu."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Andlit <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Opna <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> verður lokað án þess að vista"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> er yfir minnishámarki"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Minnisgögnum hefur verið safnað. Ýttu til að deila."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Deila minnisgögnum?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Ferlið <xliff:g id="PROC">%1$s</xliff:g> er komið yfir <xliff:g id="SIZE">%2$s</xliff:g> minnishámark sitt. Þú getur deilt minnisgögnum (heap dump) með þróunaraðilanum. Athugaðu að minnisgögnin kunna að innihalda allar þær persónuupplýsingar sem forritið hefur aðgang að um þig."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Veldu aðgerð fyrir texta"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Hljóðstyrkur hringingar"</string>
     <string name="volume_music" msgid="5421651157138628171">"Hljóðstyrkur efnisspilunar"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ýttu til að sjá öll netkerfi"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Tengjast"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Öll netkerfi"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Wi‑Fi net sem <xliff:g id="NAME">%s</xliff:g> stakk upp á er í boði"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Viltu tengjast netum sem <xliff:g id="NAME">%s</xliff:g> stakk upp á?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Já"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nei"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Kveikt verður sjálfkrafa á Wi‑Fi"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Skrá inn á net"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi er ekki með tengingu við internetið"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Ýttu til að sjá valkosti"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Tengt"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Breytingar á stillingum heits reits"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Tíðnisvið heita reitsins hefur breyst."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Þetta tæki styður ekki val þitt fyrir aðeins 5 GHz. Í staðinn mun þetta tæki nota 5 GHz tíðnisvið þegar það er í boði."</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-villuleit tengd"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Ýttu til að slökkva á USB-villuleit"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Veldu til að gera USB-villuleit óvirka."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vökvi eða óhreinindi í USB-tengi"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-tengi er gert óvirkt sjálfkrafa. Ýttu til að fá frekari upplýsingar."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Óhætt að nota USB-tengi"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Ýttu til að opna vinnusnið"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Tengt við <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Ýttu til að skoða skrárnar"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Festa"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Losa"</string>
     <string name="app_info" msgid="6856026610594615344">"Forritsupplýsingar"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Byrjar kynningu…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Upplýsingatilkynning aðgerðastillingar"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Rafhlaðan kann að tæmast áður en hún kemst í hleðslu"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Kveikt á rafhlöðusparnaði til að lengja endingu rafhlöðunnar"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Mappa"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android forrit"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Skrá"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index c5592b6..255510a 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Chiamate Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Non attiva"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Rete preferita: Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Rete preferita: dati mobili"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Solo Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: inoltro non effettuato"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Segnalazione di bug"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Termina sessione"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Apri segnalazione bug"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Verranno raccolte informazioni sullo stato corrente del dispositivo che saranno inviate sotto forma di messaggio email. Passerà un po\' di tempo prima che la segnalazione di bug aperta sia pronta per essere inviata; ti preghiamo di avere pazienza."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Rapporto interattivo"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Utilizza questa opzione nella maggior parte dei casi. Ti consente di monitorare l\'avanzamento della segnalazione, di inserire maggiori dettagli relativi al problema e di acquisire screenshot. Potrebbero essere omesse alcune sezioni meno utilizzate il cui inserimento nella segnalazione richiede molto tempo."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Geolocalizzazione"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"accedere alla posizione di questo dispositivo"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Consentire all\'app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere alla posizione di questo dispositivo?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"L\'app avrà accesso alla posizione soltanto quando la usi."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Vuoi consentire sempre a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere alla posizione di questo dispositivo?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"L\'app avrà sempre accesso alla posizione, anche quando non la usi."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accedere al calendario"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Consentire all\'app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere al tuo calendario?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Vuoi consentire all\'app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere alla tua musica?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Foto e video"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"Accesso alle tue foto e ai tuoi video"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Vuoi consentire a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di accedere alle tue foto e ai tuoi video, incluse le località taggate?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperare contenuti della finestra"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Esaminare i contenuti di una finestra con cui interagisci."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Attivare Esplora al tocco"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Consente all\'applicazione di comunicare con tag, schede e lettori NFC (Near Field Communication)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disattivazione blocco schermo"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Consente all\'applicazione di disattivare il blocco tastiera ed eventuali protezioni tramite password associate. Ad esempio, il telefono disattiva il blocco tastiera quando riceve una telefonata in arrivo e lo riattiva al termine della chiamata."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"richiedi complessità del blocco schermo"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Consente all\'app di conoscere il livello di complessità del blocco schermo (alto, medio, basso o nessuno), che indica l\'intervallo di caratteri possibile e il tipo di blocco schermo. L\'app può inoltre suggerire agli utenti di aggiornare il blocco schermo a un livello specifico di complessità, ma gli utenti possono ignorare liberamente il suggerimento e uscire. Tieni presente che il blocco schermo non viene memorizzato come testo non crittografato, quindi l\'app non conosce la password esatta."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"Utilizzo di hardware biometrico"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Consente all\'app di utilizzare hardware biometrico per eseguire l\'autenticazione"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gestisci hardware per il riconoscimento delle impronte digitali"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Consente all\'app di richiamare i metodi per aggiungere e rimuovere i modelli di volti."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"utilizza l\'hardware per l\'autenticazione dei volti"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Consente all\'app di utilizzare hardware per l\'autenticazione dei volti"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Impossibile elaborare il volto. Riprova."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Volto troppo luminoso. Prova dove c\'è meno luce."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Volto troppo scuro. Non coprire la fonte di luce."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Allontana il sensore dal volto."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Avvicina il sensore al volto."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Sposta il sensore verso l\'alto."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Sposta il sensore verso il basso."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Sposta il sensore verso destra."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Sposta il sensore verso sinistra."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Guarda il sensore."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nessun volto rilevato."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Troppo movimento."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Ripeti l\'acquisizione del volto."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"È stato rilevato un volto diverso."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Troppo simile; cambia posa."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Guarda più direttamente verso la fotocamera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Guarda più direttamente verso la fotocamera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Raddrizza la testa in verticale."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Scopri il volto."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardware per il volto non disponibile."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Timeout operazione associata al volto. Riprova."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Il volto non può essere memorizzato."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operazione associata al volto annullata."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticazione del volto annullata dall\'utente."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Troppi tentativi. Riprova più tardi."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Troppi tentativi. Autenticazione disattivata."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Riprova."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nessun volto registrato."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Questo dispositivo non dispone di sensore di autenticazione."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Volto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Apri <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> si chiuderà senza salvare"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ha superato il limite di memoria"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Dump dell\'heap raccolto. Tocca per condividere."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Condividere il dump dell\'heap?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Il processo <xliff:g id="PROC">%1$s</xliff:g> ha superato il suo limite di memoria pari a <xliff:g id="SIZE">%2$s</xliff:g>. È disponibile un dump dell\'heap che puoi condividere con lo sviluppatore. Presta attenzione: questo dump dell\'heap può contenere tue informazioni personali a cui l\'applicazione ha accesso."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Scegli un\'azione per il testo"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volume suoneria"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volume contenuti multimediali"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tocca per vedere tutte le reti"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connetti"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tutte le reti"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"È disponibile una rete Wi-Fi suggerita da <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Vuoi collegarti alle reti suggerite da <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sì"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Il Wi‑Fi verrà attivato automaticamente"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Accedi alla rete"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"La rete Wi-Fi non ha accesso a Internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tocca per le opzioni"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Connesso"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Modifiche alle tue impostazioni dell\'hotspot"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"La tua banda di hotspot è cambiata."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Questo dispositivo non supporta la tua preferenza esclusiva per 5 GHz. Utilizzerà invece la banda a 5 GHz solo quando è disponibile."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tocca per disattivare il debug USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquidi o detriti nella porta USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"La porta USB viene disattivata automaticamente. Tocca per avere ulteriori informazioni."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Puoi usare la porta USB in sicurezza"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Tocca per sbloc. prof. di lav."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connesso a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tocca per visualizzare i file"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Blocca"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Sgancia"</string>
     <string name="app_info" msgid="6856026610594615344">"Informazioni app"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Avvio della demo…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notifica di informazioni sulla modalità Routine"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"La batteria potrebbe esaurirsi prima della ricarica abituale"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Risparmio energetico attivo per far durare di più la batteria"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Cartella"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Applicazione Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"File"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 89813a7..a42f6cc 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -143,8 +143,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"‏שיחות Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"כבוי"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"‏Wi-Fi מועדף"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"מצב מועדף: רשת סלולרית"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"‏Wi-Fi בלבד"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ללא העברה"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -232,7 +234,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"דיווח על באג"</string>
     <string name="global_action_logout" msgid="935179188218826050">"סיום הפעלה"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"צילום מסך"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"שלח דיווח על באג"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"פעולה זו תאסוף מידע על מצב המכשיר הנוכחי שלך על מנת לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת דיווח הבאג ועד לשליחת ההודעה בפועל. אנא המתן בסבלנות."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"דוח אינטראקטיבי"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"השתמש באפשרות זו ברוב המקרים. היא מאפשרת לך לעקוב אחר התקדמות הדוח, להזין פרטים נוספים על הבעיה וליצור צילומי מסך. היא עשויה להשמיט כמה קטעים שנמצאים פחות בשימוש ואשר יצירת הדיווח עליהם נמשכת זמן רב."</string>
@@ -287,9 +290,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"מיקום"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"גישה אל מיקום המכשיר הזה"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"‏לתת לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; הרשאת גישה למיקום המכשיר?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"לאפליקציה תהיה גישה אל נתוני המיקום רק במהלך השימוש באפליקציה."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"‏תמיד לתת לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; הרשאת גישה למיקום המכשיר?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"לאפליקציה תמיד תהיה גישה לנתוני המיקום, גם כשהאפליקציה אינה בשימוש."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"יומן"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"גישה אל היומן"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‏לתת לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; הרשאת גישה ליומן?"</string>
@@ -322,7 +328,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"‏האם לתת לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; הרשאת גישה למוזיקה שלך?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"תמונות וסרטונים"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"גישה לתמונות ולסרטונים שלך"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"‏האם לאפשר ל-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; לקבל גישה לתמונות ולסרטונים שלך, כולל מיקומים מתויגים?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"אחזור תוכן של חלון"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"בדוק את התוכן של חלון שאיתו אתה מבצע אינטראקציה."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"הפעלה של \'גילוי באמצעות מגע\'"</string>
@@ -515,8 +524,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"מאפשר לאפליקציה נהל תקשורת עם תגים, כרטיסים וקוראים מסוג \'תקשורת מטווח קצר\'."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ביטול נעילת המסך שלך"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"מאפשר לאפליקציה להשבית את נעילת המקשים וכל אמצעי אבטחה משויך המבוסס על סיסמה. לדוגמה, הטלפון משבית את נעילת המקשים בעת קבלה של שיחת טלפון נכנסת, ולאחר מכן מפעיל מחדש את נעילת המקשים עם סיום השיחה."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"בקשה לפרטי המורכבות של נעילת מסך"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"‏מאפשרת לאפליקציה ללמוד את רמת המורכבות של נעילת המסך (גבוהה, בינונית, נמוכה או ללא). רמה זו מציינת את הטווח האפשרי לאורך ולסוג של נעילת המסך. האפליקציה יכולה גם להציע למשתמשים שיעדכנו את נעילת המסך ברמה מסוימת, אבל המשתמשים יכולים להתעלם מההצעה ולנווט לפריט אחר כרצונם. יש לשים לב שנעילת המסך לא מאוחסנת ב-plaintext, ולכן האפליקציה לא יודעת מה הסיסמה המדויקת."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"שימוש בחומרה ביומטרית"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"מאפשרת לאפליקציה להשתמש בחומרה ביומטרית לצורך אימות"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ניהול חומרה של טביעות אצבעות"</string>
@@ -571,37 +582,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"מאפשרת לאפליקציה להפעיל שיטות להוספה ומחיקה של תבניות פנים שבהן ייעשה שימוש."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"שימוש בחומרה של זיהוי פנים לצורך אימות"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"מאפשרת לאפליקציה להשתמש בחומרה של זיהוי פנים לצורך אימות"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"לא ניתן היה לעבד את הפנים. יש לנסות שוב."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"הפנים בהירים מדי. יש לנסות באור עמום יותר."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"הפנים כהים מדי. יש להוסיף מקור אור."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"יש להרחיק את החיישן מהפנים."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"יש לקרב את החיישן לפנים."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"יש להזיז את החיישן גבוה יותר."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"יש להזיז את החיישן נמוך יותר."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"יש להזיז את החיישן ימינה."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"יש להזיז את החיישן שמאלה."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"יש להסתכל על החיישן."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"לא זוהו פנים."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"יש יותר מדי תנועה."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"יש לרשום מחדש את הפנים."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"זוהו פנים שונות."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"דומה מדי, יש לשנות תנוחה."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"יש להביט ישירות אל המצלמה."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"יש להביט ישירות אל המצלמה."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"יש ליישר את הראש במאונך."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"יש להסיר את הכיסוי מהפנים."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"החומרה לזיהוי הפנים לא זמינה."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"חלף הזמן הקצוב לזיהוי הפנים. יש לנסות שוב."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"לא ניתן לשמור את הפנים."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"פעולת הפנים בוטלה."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"זיהוי הפנים בוטל על ידי המשתמש."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"יותר מדי ניסיונות. יש לנסות שוב מאוחר יותר."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"יותר מדי ניסיונות. אימות הפנים הושבת."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"יש לנסות שוב."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"לא נרשמו פנים."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"במכשיר זה אין חיישן לאימות פנים."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"פנים <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1253,9 +1286,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"פתיחת <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> האפליקציה תיסגר ללא שמירה"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> חורג מהגבלת הזיכרון"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"‏Dump של ערימה נאסף. יש להקיש כדי לשתף."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"‏האם לשתף את נתוני ה-Dump של הערימה?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"‏התהליך <xliff:g id="PROC">%1$s</xliff:g> חרג ממגבלת זיכרון התהליך שלו, בגודל <xliff:g id="SIZE">%2$s</xliff:g>. נתונים על Dump של ערימה זמינים לך לשיתוף עם המפתח של התהליך. זהירות: ה-Dump של הערימה יכול להכיל מידע אישי הזמין לאפליקציה."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"בחירת פעולה לביצוע עם טקסט"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"עוצמת קול של צלצול"</string>
     <string name="volume_music" msgid="5421651157138628171">"עוצמת קול של מדיה"</string>
@@ -1298,8 +1338,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"יש להקיש כדי לראות את כל הרשתות"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"התחבר"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"כל הרשתות"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"‏רשת ה-Wi‑Fi שהוצעה על ידי <xliff:g id="NAME">%s</xliff:g> לא זמינה"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"רוצה להתחבר לרשתות שהוצעו על ידי <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"כן"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"לא"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‏ה-Wi-Fi יופעל אוטומטית"</string>
@@ -1311,9 +1353,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"היכנס לרשת"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"‏לרשת ה-Wi-Fi אין גישה לאינטרנט"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"הקש לקבלת אפשרויות"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"הרשת מחוברת"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"שינויים להגדרות של הנקודה לשיתוף אינטרנט"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"התדר של הנקודה לשיתוף אינטרנט השתנה."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"‏מכשיר זה לא תומך בהעדפות שלך ל-5GHz בלבד. במקום זאת, מכשיר זה ישתמש בתדר 5GHz כשיהיה זמין."</string>
@@ -1398,6 +1445,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏ניפוי באגים של USB מחובר"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"‏יש להקיש כדי לכבות את ניפוי הבאגים ב-USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏בחר להשבית ניפוי באגים ב-USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏יש נוזלים או חלקיקים ביציאת ה-USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏יציאת ה-USB הושבתה באופן אוטומטי. יש להקיש לקבלת מידע נוסף."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"‏יציאת ה-USB בטוחה לשימוש"</string>
@@ -1973,8 +2024,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"הקש לביטול נעילת פרופיל העבודה"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"מחובר אל <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"הקש כדי להציג קבצים"</string>
-    <string name="pin_target" msgid="3052256031352291362">"הצמד"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"בטל הצמדה"</string>
     <string name="app_info" msgid="6856026610594615344">"פרטי אפליקציה"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"מתחיל בהדגמה…"</string>
@@ -2067,6 +2116,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"התראת מידע לגבי מצב שגרתי"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"הסוללה עלולה להתרוקן לפני המועד הרגיל של הטעינה"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"תכונת החיסכון בסוללה הופעלה כדי להאריך את חיי הסוללה"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"תיקייה"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"‏אפליקציית Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"קובץ"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 79e2f09..9e466cb 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi 通話"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"OFF"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi優先"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"モバイル優先"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fiのみ"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:転送できません"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:<xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"バグレポート"</string>
     <string name="global_action_logout" msgid="935179188218826050">"セッションを終了"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"スクリーンショット"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"バグレポートを取得"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"現在の端末の状態に関する情報が収集され、その内容がメールで送信されます。バグレポートが開始してから送信可能な状態となるまでには多少の時間がかかりますのでご了承ください。"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"対話型レポート"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ほとんどの場合はこのオプションを使用します。レポートの進行状況を追跡し、問題についての詳細情報の確認やスクリーンショットの作成が可能です。レポート作成に時間がかかる、あまり使用されない項目は省略されることがあります。"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"位置情報"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"この端末の位置情報へのアクセス"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"この端末の位置情報へのアクセスを &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に許可しますか?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"このアプリは、使用時のみ、位置情報にアクセスできるようになります。"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"この端末の位置情報へのアクセスを &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に常に許可しますか?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"このアプリは、未使用時も含め、常に位置情報にアクセスできるようになります。"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"カレンダー"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"カレンダーへのアクセス"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"カレンダーへのアクセスを &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に許可しますか?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"音楽へのアクセスを &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に許可しますか?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"写真と動画"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"写真と動画へのアクセス"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"タグ付けされた場所を含め、写真と動画へのアクセスを &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に許可しますか?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ウィンドウコンテンツの取得"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ユーザーがアクセスしているウィンドウのコンテンツを検査します。"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"タッチガイドの有効化"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"NFCタグ、カード、リーダーとの通信をアプリに許可します。"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"画面ロックの無効化"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"キーロックとキーロックに関連付けられたパスワードのセキュリティを無効にすることをアプリに許可します。たとえば、かかってきた電話を受ける際にキーロックを無効にし、通話が終了したらキーロックを再度有効にする場合などに使用します。"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"画面ロックの複雑さのリクエスト"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"このアプリに画面ロックの複雑さレベル(高、中、低、なし)を認識することを許可します。複雑さレベルは、画面ロックの文字数の範囲やタイプを示すものです。アプリから一定レベルまで画面ロックを更新するよう推奨されることもありますが、ユーザーは無視したり別の操作を行ったりできます。画面ロックは平文で保存されないため、アプリが正確なパスワードを知ることはありません。"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"生体認証ハードウェアの使用"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"生体認証ハードウェアを認証に使用することをアプリに許可します"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"指紋ハードウェアの管理"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"使用する顔テンプレートの追加や削除を行うメソッドの呼び出しをアプリに許可します。"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"顔認証ハードウェアの使用"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"顔認証ハードウェアを認証に使用することをアプリに許可します"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"顔を認識できませんでした。もう一度お試しください。"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"顔が明るすぎます。照明を暗くしてみてください。"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"顔が暗すぎます。光源のカバーを外してください。"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"センサーを顔から遠ざけてください。"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"センサーを顔に近づけてください。"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"センサーを上に動かしてください。"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"センサーを下に動かしてください。"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"センサーを右に動かしてください。"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"センサーを左に動かしてください。"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"センサーを見てください。"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"顔を検出できません。"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"あまり動かさないでください。"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"顔を登録し直してください。"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"別の顔が検出されました。"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"似すぎています。ポーズを変えてください。"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"もっとまっすぐ顔をカメラに向けてください。"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"もっとまっすぐカメラに顔を向けてください。"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"頭を左右に傾けず、まっすぐにしてください。"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"顔を隠さないでください。"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"顔認証ハードウェアが使用できません。"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"読み取りのタイムアウトです。もう一度お試しください。"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"顔の情報を保存できません。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"顔の操作をキャンセルしました。"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"顔の認証がユーザーによりキャンセルされました。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"試行回数の上限です。後でもう一度お試しください。"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"試行回数の上限です。顔認証は無効になりました。"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"もう一度お試しください。"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"顔の情報が登録されていません。"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"このデバイスには顔認証センサーがありません。"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"顔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> を開く"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> を保存せずに閉じます"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g>はメモリの上限を超えました"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"ヒープダンプを収集しました。共有するにはタップしてください。"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ヒープダンプを共有しますか?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"プロセス<xliff:g id="PROC">%1$s</xliff:g>はプロセスメモリの上限<xliff:g id="SIZE">%2$s</xliff:g>を超えました。ヒープダンプをデベロッパーと共有できます。このヒープダンプには、アプリがアクセスできる個人情報が含まれている可能性があるのでご注意ください。"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"アプリケーションを選択"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"着信音量"</string>
     <string name="volume_music" msgid="5421651157138628171">"メディアの音量"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"すべてのネットワークを表示するにはタップします"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"接続"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"すべてのネットワーク"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> でおすすめの Wi-Fi ネットワークが利用可能です"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> でおすすめのネットワークに接続してもよろしいですか?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"はい"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"いいえ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi は自動的にオンになります"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ネットワークにログインしてください"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi‑Fi はインターネットに接続していません"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"タップしてその他のオプションを表示"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"接続しました"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"アクセス ポイントの設定の変更"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"アクセス ポイントの帯域幅が変更されました。"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"この端末は 5 GHz のみという設定に対応していません。ただし、5 GHz 周波数帯が利用できるときには利用します。"</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"タップして USB デバッグを無効にしてください"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ポート内の液体やゴミ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ポートが自動的に無効になりました。タップして詳細をご確認ください。"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB ポートを安全に使用できます"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"タップしてプロファイルをロック解除"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> に接続しました"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"タップしてファイルを表示"</string>
-    <string name="pin_target" msgid="3052256031352291362">"固定"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"固定を解除"</string>
     <string name="app_info" msgid="6856026610594615344">"アプリ情報"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"デモを開始しています…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"ルーティン モード情報の通知"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"通常の充電を行う前に電池が切れる可能性があります"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"電池を長持ちさせるため、バッテリー セーバーが有効になりました"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"フォルダ"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android アプリ"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ファイル"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 4a3cb8b..c6e636d 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WiFi დარეკვა"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"გამორთული"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"სასურველია Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"უპირატესობა მიენიჭოს მობილურს"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"მხოლოდ Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: არ არის გადამისამართებული"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ხარვეზის შესახებ ანგარიში"</string>
     <string name="global_action_logout" msgid="935179188218826050">"სესიის დასრულება"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ეკრანის ანაბეჭდი"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"შექმენით შეცდომის ანგარიში"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"იგი შეაგროვებს ინფორმაციას თქვენი მოწყობილობის ამჟამინდელი მდგომარეობის შესახებ, რათა ის ელფოსტის შეტყობინების სახით გააგზავნოს. ხარვეზის ანგარიშის მომზადებასა და შეტყობინების გაგზავნას გარკვეული დრო სჭირდება. გთხოვთ, მოითმინოთ."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ინტერაქტიული ანგარიში"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"გამოიყენეთ ეს ვარიანტი შემთხვევათა უმეტესობაში. ის საშუალებას მოგცემთ, თვალი მიადევნოთ ანგარიშის პროგრესს, პრობლემის შესახებ მეტი დეტალი შეიყვანოთ და გადაიღოთ ეკრანის ანაბეჭდები. ამ ვარიანტის არჩევის შემთხვევაში, შეიძლება მოხდეს ზოგიერთი ნაკლებად გამოყენებადი სექციის გამოტოვება, რომელთა შესახებ მოხსენებასაც დიდი დრო სჭირდება."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"მდებარეობა"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"მოწყობილობის მდებარეობაზე წვდომა"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"გსურთ, მიანიჭოთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ს&lt;/b&gt; ამ მოწყობილობის მდებარეობაზე წვდომის ნებართვა?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"ამ აპს მდებარეობაზე წვდომა მხოლოდ მაშინ ექნება, როცა თქვენ მას გამოიყენებთ."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"გსურთ, მიანიჭოთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ს&lt;/b&gt; ამ მოწყობილობის მდებარეობაზე წვდომის ნებართვა?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"ამ აპს ყოველთვის ექნება მდებარეობაზე წვდომა, მაშინაც კი, როცა თქვენ მას არ იყენებთ."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"კალენდარი"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"თქვენს კალენდარზე წვდომა"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"გსურთ, მიანიჭოთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ს&lt;/b&gt; თქვენს კალენდარზე წვდომის ნებართვა?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"გსურთ, მიანიჭოთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-ს თქვენს მუსიკაზე წვდომა?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ფოტოები და ვიდეოები"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"თქვენს ფოტოებსა და ვიდეოებზე წვდომა"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"გსურთ, მიანიჭოთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-ს წვდომა თქვენს ფოტოებსა და ვიდეოებზე, მათ შორის, თეგებით მონიშნულ მდებარეობებზე?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ფანჯრის კონტენტის მოძიება"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"იმ ფანჯრის კონტენტის შემოწმება, რომელშიც მუშაობთ."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"„შეხებით აღმოჩენის“ ჩართვა"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"აპს შეეძლება ახლო მოქმედების რადიოკავშირის (NFC) მეშვეობით ტეგების, ბარათებისა და წამკითხველების შემცველი მონაცემების მიმოცვლა."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"თქვენი ეკრანის ბლოკის გათიშვა"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"შეეძლება კლავიატურის დაბლოკვისა და პაროლით უზრუნველყოფილი ნებისმიერი უსაფრთხოების ფუნქციის დეაქტივაცია. მაგალითად, ტელეფონი შემომავალი ზარის დროს აუქმებს კლავიატურის დაბლოკვას და კვლავ ააქტიურებს მას, როგორც კი ზარი დასრულდება."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ეკრანის დაბლოკვის მეთოდის სირთულის შესახებ ინფორმაციის მოთხოვნა"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"საშუალებას აძლევს აპს, შეიტყოს ეკრანის დაბლოკვის მეთოდის სირთულე (მაღალი, საშუალო, დაბალი ან არანაირი), რისი მეშვეობითაც შესაძლებელია ეკრანის დაბლოკვის მეთოდის სიგრძის შესაძლო დიაპაზონისა და ტიპის განსაზღვრა. გარდა ამისა, აპს შეუძლია მომხმარებლებისთვის ეკრანის დაბლოკვის მეთოდის გარკვეულ დონემდე გაძლიერების შეთავაზება, თუმცა მომხმარებლებს შეეძლებათ აღნიშნული შეტყობინების უგულებელყოფა და სხვა ეკრანზე გადასვლა. გაითვალისწინეთ, რომ ეკრანის დაბლოკვის მეთოდი არ ინახება ჩვეულებრივი ტექსტის სახით, ამიტომ აპს არ ეცოდინება ზუსტი პაროლი."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ბიომეტრიული აპარატის გამოყენება"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"საშუალებას აძლევს აპს, ავტორიზაციისთვის გამოიყენოს ბიომეტრიული აპარატი"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"თითის ანაბეჭდის აპარატის მართვა"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"საშუალებას აძლევს აპს, დაამატოს და წაშალოს სახეების შაბლონები."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"სახის ამოცნობის აპარატურის გამოყენება"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"საშუალებას აძლევს აპს, ავტორიზაციისთვის გამოიყენოს სახის ამოცნობის აპარატურა"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"სახე ვერ მუშავდება. გთხოვთ, ცადოთ ხელახლა."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"სახე გადანათებულია. დაუკელით განათებას."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"სახე ჩაბნელებულია. მოუმატეთ განათებას."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"დააშორეთ მოწყობილობის სენსორი სახეს."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"მიუახლოვეთ მოწყობილობის სენსორი სახეს."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"ასწიეთ მოწყობილობის სენსორი ოდნავ ზემოთ."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"ჩასწიეთ მოწყობილობის სენსორი ოდნავ ქვემოთ."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"გასწიეთ მოწყობილობის სენსორი ოდნავ მარჯვნივ."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"გასწიეთ მოწყობილობის სენსორი ოდნავ მარცხნივ."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"შეხედეთ სენსორს."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"სახის ამოცნობა ვერ მოხერხდა."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"დაფიქსირდა მეტისმეტად ბევრი მოძრაობა."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"გთხოვთ, ხელახლა დაარეგისტრიროთ თქვენი სახე."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"ამოცნობილია განსხვავებული სახე."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"მეტისმეტად მსგავსია. გთხოვთ, შეცვალოთ პოზა."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"გთხოვთ, უფრო პირდაპირ შეხედოთ კამერას."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"გთხოვთ, უფრო პირდაპირ შეხედოთ კამერას."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"გთხოვთ, ვერტიკალურად გაასწოროთ თავი."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"გთხოვთ, გამოაჩინოს სახე."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"სახის ამოცნობის აპარატურა მიუწვდომელია."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"სახის ამოცნობის დრო ამოიწურა. ცადეთ ხელახლა."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"სახის შენახვა ვერ მოხერხდა."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"სახის ამოცნობა გაუქმდა."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"სახის ავტორიზაცია გაუქმდა მომხმარებლის მიერ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"დაფიქსირდა ბევრი მცდელობა. ცადეთ მოგვიანებით."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"დაფიქსირდა ბევრი მცდელობა. სახის ამოცნობა გაითიშა."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"ცადეთ ხელახლა."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"სახე რეგისტრირებული არ არის."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"ამ მოწყობილობას არ აქვს სახის ამოცნობის სენსორი."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"სახე <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"გახსენით <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> დაიხურება მონაცემთა შენახვის გარეშე"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g>-მა გადააჭარბა მეხსიერების ლიმიტს"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"გროვის ამონაწერი მომზადდა, შეეხეთ გასაზიარებლად."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"გავაზიაროთ გროვის ამონაწერი?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"პროცესმა <xliff:g id="PROC">%1$s</xliff:g> გადააჭარბა საპროცესო მეხსიერების <xliff:g id="SIZE">%2$s</xliff:g>-იან ლიმიტს. გროვის ამონაწერი ხელმისაწვდომია მის დეველოპერთან გასაზიარებლად. ფრთხილად: გროვის ამონაწერი შეიძლება შეიცავდეს ნებისმიერ თქვენს პირად ინფორმაციას, რომელზეც ამ აპლიკაციას წვდომა აქვს."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"შეარჩიეთ ქმედება ტექსტისთვის."</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"მრეკავის ხმა"</string>
     <string name="volume_music" msgid="5421651157138628171">"მედიის ხმა"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"შეეხეთ ყველა ქსელის სანახავად"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"დაკავშირება"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ყველა ქსელი"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"ხელმისაწვდომია <xliff:g id="NAME">%s</xliff:g>-ის მიერ შემოთავაზებული Wi‑Fi ქსელი"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"გსურთ <xliff:g id="NAME">%s</xliff:g>-ის მიერ შემოთავაზებულ ქსელებთან დაკავშირება?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"დიახ"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"არა"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi ავტომატურად ჩაირთვება"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ქსელში შესვლა"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi‑Fi ქსელს ინტერნეტზე წვდომა არ აქვს"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"შეეხეთ ვარიანტების სანახავად"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"დაკავშირებულია"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"თქვენი უსადენო ქსელის პარამეტრების ცვლილება"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"თქვენი უსადენო ქსელის დიაპაზონი შეიცვალა."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"ამ მოწყობილობას არ შეუძლია მხოლოდ 5 გჰც სიხშირეზე მუშაობა. აღნიშნული სიხშირის გამოყენება მოხდება მაშინ, როცა ეს შესაძლებელია."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"შეეხეთ, რათა გამორთოთ USB შეცდომების გამართვა"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"მონიშნეთ რათა შეწყვიტოთ USB-ის გამართვა"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB პორტში აღმოჩენილია სითხე ან ჭუჭყი"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB პორტი ავტომატურად გათიშულია. შეეხეთ დამატებითი ინფორმაციისთვის."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB პორტის გამოყენება ახლა უსაფრთხოა"</string>
@@ -1396,8 +1447,7 @@
     <string name="ext_media_init_action" msgid="7952885510091978278">"დაყენება"</string>
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"გამოღება"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"დათვალიერება"</string>
-    <!-- no translation found for ext_media_seamless_action (6575980560886881233) -->
-    <skip />
+    <string name="ext_media_seamless_action" msgid="6575980560886881233">"გამომავალი სიგნალის გადართვა"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> აკლია"</string>
     <string name="ext_media_missing_message" msgid="4012389235250987930">"ისევ მიუერთეთ მოწყობილობა"</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"მიმდინარეობს <xliff:g id="NAME">%s</xliff:g>-ის გადატანა"</string>
@@ -1906,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"შეეხეთ პროფილის განსაბლოკად"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"დაკავშირებულია <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-თან"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"შეეხეთ ფაილების სანახავად"</string>
-    <string name="pin_target" msgid="3052256031352291362">"ჩამაგრება"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"ჩამაგრების მოხსნა"</string>
     <string name="app_info" msgid="6856026610594615344">"აპის შესახებ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"მიმდინარეობს დემონსტრაციის დაწყება…"</string>
@@ -1998,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"რუტინის რეჟიმის საინფორმაციო შეტყობინება"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ბატარეა შეიძლება დაჯდეს დატენის ჩვეულ დრომდე"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"ბატარეის დამზოგი გააქტიურდა ბატარეის მუშაობის გასახანგრძლივლებლად"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"საქაღალდე"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android-ის აპლიკაცია"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ფაილი"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index cb38ea1..494f26a 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"ការហៅតាម Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"បិទ"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ជាអាទិភាព"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ទិន្នន័យទូរសព្ទចល័តជាអាទិភាព"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi តែប៉ុណ្ណោះ"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> ៖ មិន​បាន​បញ្ជូន​បន្ត"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"របាយការណ៍​កំហុស"</string>
     <string name="global_action_logout" msgid="935179188218826050">"បញ្ចប់​សម័យ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"រូបថតអេក្រង់"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"យក​របាយការណ៍​កំហុស"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"វា​នឹង​​ប្រមូល​ព័ត៌មាន​អំពី​ស្ថានភាព​ឧបករណ៍​របស់​អ្នក ដើម្បី​ផ្ញើ​ជា​សារ​អ៊ីមែល។ វា​នឹង​ចំណាយ​ពេល​តិច​ពី​ពេល​ចាប់ផ្ដើម​របាយការណ៍​រហូត​ដល់​ពេល​វា​រួចរាល់​ដើម្បី​ផ្ញើ សូម​អត់ធ្មត់។"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"របាយការណ៍អន្តរកម្ម"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ប្រើក្នុងកាលៈទេសៈភាគច្រើន។ វាអនុញ្ញាតឲ្យអ្នកតាមដានដំណើរការនៃរបាយការណ៍ និងបញ្ចូលព័ត៌មានលម្អិតបន្ថែមអំពីបញ្ហា និងថតរូបអេក្រង់។ វាអាចនឹងរំលងផ្នែកមួយចំនួនដែលមិនសូវប្រើ ដែលធ្វើឲ្យចំណាយពេលយូរក្នុងការរាយការណ៍។"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"ទីតាំង"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"ចូលដំណើរការទីតាំងរបស់ឧបករណ៍នេះ"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"អនុញ្ញាតឱ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ចូលប្រើ​ទីតាំងរបស់ឧបករណ៍នេះ?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"កម្មវិធីនេះ​នឹងមាន​សិទ្ធិ​ចូលប្រើ​ទីតាំង នៅពេល​អ្នកប្រើ​កម្មវិធីនេះ​តែ​ប៉ុណ្ណោះ។"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"អនុញ្ញាត​ឱ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ចូលប្រើ​ទីតាំង​របស់ឧបករណ៍​នេះ​ជានិច្ច​មែនទេ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"កម្មវិធីនេះ​នឹងមាន​សិទ្ធិ​ចូលប្រើ​ទីតាំង​ជានិច្ច ទោះបីជា​នៅពេល​អ្នក​មិនប្រើ​កម្មវិធីនេះ​ក៏​ដោយ។"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ប្រតិទិន"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ចូលប្រើប្រិតិទិនរបស់អ្នក"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"អនុញ្ញាតឱ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ចូលប្រើ​ប្រតិទិនរបស់អ្នក?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"អនុញ្ញាត​ឱ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ចូលប្រើ​តន្រ្តី​របស់​អ្នក?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"​រូបថត និង​វីដេអូ"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"ចូលប្រើ​រូបថត និង​វីដេអូ​របស់អ្នក"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"អនុញ្ញាត​ឱ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ចូលប្រើ​រូបថត និង​វីដេអូ​របស់អ្នក រួមទាំង​ទីតាំង​ដែលបានដាក់ស្លាក?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ទាញយក​ខ្លឹមសារ​វិនដូ"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ពិនិត្យ​ខ្លឹមសារវិនដូ​ដែល​អ្នក​កំពុង​ទាក់ទង​ជា​មួយ។"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"បើក​ការ​រក​មើល​​ដោយ​ប៉ះ"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"ឲ្យ​កម្មវិធី​ទាក់ទង​ជា​មួយ​ស្លាក (NFC) កាត និង​កម្មវិធី​អាន។"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"បិទ​ការ​ចាក់​សោ​អេក្រង់​របស់​អ្នក"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ឲ្យ​កម្មវិធី​បិទ​ការ​ចាក់សោ​សុវត្ថិភាព​ពាក្យ​សម្ងាត់​ដែល​បាន​ភ្ជាប់​ណា​មួយ។ ​ឧទាហរណ៍​ត្រឹមត្រូវ​​​នៃ​ការ​បិទ​ទូរស័ព្ទ​ពេល​ទទួលការ​ហៅ​ចូល បន្ទាប់​ម​បើក​សោ​ពេល​ការ​ហៅ​បាន​បញ្ចប់។"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ស្នើ​សុំកម្រិត​​ស្មុគស្មាញ​នៃការចាក់សោអេក្រង់"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"អនុញ្ញាតឱ្យ​កម្មវិធី​រៀនអំពី​កម្រិតស្មុគស្មាញ​នៃការចាក់សោអេក្រង់ (ខ្ពស់ មធ្យម​ ទាប ឬគ្មាន) ដែល​បញ្ជាក់អំពី​​ចន្លោះប្រវែងដែលអាចមាន និងប្រភេទ​នៃការចាក់សោអេក្រង់។ កម្មវិធី​នេះ​ក៏​អាច​ណែនាំឱ្យ​អ្នកប្រើប្រាស់​ធ្វើបច្ចុប្បន្នភាព​ការចាក់សោ​អេក្រង់​ទៅកម្រិតជាក់លាក់​ផងដែរ ប៉ុន្តែ​អ្នកប្រើប្រាស់​អាច​មិនអើពើនឹង​ការណែនាំនេះ​ដោយសេរី។ សូម​ចំណាំថា ការចាក់សោអេក្រង់​មិន​ត្រូវបាន​រក្សាទុក​ជាអត្ថបទ​ធម្មតាទេ ដូច្នេះ​កម្មវិធីនេះ​មិន​ស្គាល់​ពាក្យសម្ងាត់​ពិតប្រាកដ​ឡើយ។"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ប្រើ​ឧបករណ៍​ស្កេន​ស្នាមម្រាមដៃ"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"អនុញ្ញាត​ឱ្យ​កម្មវិធី​ប្រើ​ឧបករណ៍​ស្កេន​ស្នាមម្រាមដៃ​សម្រាប់​ការផ្ទៀងផ្ទាត់"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"គ្រប់គ្រងផ្នែករឹងស្នាមម្រាមដៃ"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"អនុញ្ញាតឱ្យកម្មវិធីប្រើវិធីសាស្ត្រដើម្បី​បញ្ចូល និងលុបទម្រង់​គំរូ​ផ្ទៃមុខសម្រាប់ប្រើប្រាស់។"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"ប្រើ​ផ្នែករឹង​ផ្ទៀងផ្ទាត់​ផ្ទៃ​មុខ"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"អនុញ្ញាត​ឱ្យ​កម្មវិធី​ប្រើ​ផ្នែករឹង​ផ្ទៀងផ្ទាត់​ផ្ទៃមុខ​សម្រាប់​ការផ្ទៀងផ្ទាត់"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"មិនអាចដំណើរការ​ផ្ទៃមុខបានទេ។ សូមព្យាយាមម្តងទៀត។"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"ផ្ទៃ​មុខ​ចាំង​ពេក។ សូម​សាកល្បង​នៅកន្លែងដែលមាន​ពន្លឺ​ទាប​ជាងនេះ។"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"ផ្ទៃ​មុខ​ងងឹត​ពេក។ សូមរកកន្លែង​ដែលមាន​ប្រភពពន្លឺ។"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"សូម​ផ្លាស់ទីឧបករណ៍​ចាប់សញ្ញា​ឱ្យ​ឆ្ងាយ​ពី​មុខ​។"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"សូម​ដាក់​ឧបករណ៍​ចាប់សញ្ញា​ឱ្យនៅជិតមុខ​ជាងនេះ។"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"សូម​ផ្លាស់ទី​ឧបករណ៍​ចាប់សញ្ញា​ឱ្យខ្ពស់​ជាងនេះ។"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"សូម​ផ្លាស់ទី​ឧបករណ៍ចាប់សញ្ញា​ឱ្យ​ទាបជាងនេះ។"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"សូម​ផ្លាស់ទី​ឧបករណ៍ចាប់សញ្ញា​ទៅ​ស្ដាំ។"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"សូម​ផ្លាស់ទី​ឧបករណ៍ចាប់សញ្ញា​ទៅឆ្វេង។"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"សូម​មើល​ទៅ​ឧបករណ៍​ចាប់សញ្ញា។"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"រកមិន​ឃើញ​មុខទេ។"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"មាន​ចលនា​ខ្លាំងពេក។"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"សូម​​ស្កេន​បញ្ចូល​មុខរបស់អ្នក​ម្ដងទៀត។"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"បាន​រកឃើញ​មុខផ្សេង។"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ស្រដៀងគ្នា​ពេក សូមផ្លាស់ប្ដូរ​កាយវិការ​របស់អ្នក។"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"សូម​មើល​ឱ្យចំកាមេរ៉ា​ជាងមុន។"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"សូម​មើល​ឱ្យចំកាមេរ៉ា​ជាងមុន។"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"សូម​ងើយ​ក្បាល​របស់អ្នកឱ្យត្រង់។"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"សូម​កុំបាំងមុខ​របស់អ្នក។"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"មិន​អាច​ប្រើ​ផ្នែករឹង​ចាប់ផ្ទៃ​មុខ​បានទេ។"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"ការសម្គាល់​ផ្ទៃមុខ​បាន​អស់ម៉ោង។ សូមព្យាយាមម្ដងទៀត។"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"មិន​អាច​រក្សាទុក​ផ្ទៃ​មុខ​បានទេ។"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"បាន​បោះបង់​ប្រតិបត្តិការចាប់​ផ្ទៃមុខ។"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"ការផ្ទៀងផ្ទាត់​មុខ​ត្រូវបានបោះបង់ដោយអ្នកប្រើប្រាស់។"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ព្យាយាមចូលច្រើនពេកហើយ។ សូមព្យាយាមម្តងទៀតពេលក្រោយ។"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ព្យាយាមចូលច្រើនពេកហើយ។ បាន​បិទការផ្ទៀងផ្ទាត់​ផ្ទៃ​មុខ។"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"សូមព្យាយាម​ម្ដងទៀត។"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"មិន​អាច​ថត​បញ្ចូលផ្ទៃ​មុខ​បានទេ។"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"ឧបករណ៍​នេះ​មិន​មាន​ឧបករណ៍​ផ្ទៀងផ្ទាត់​មុខ​ទេ។"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"ផ្ទៃមុខទី <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1215,9 +1248,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"បើក <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> នឹង​បិទ​ដោយ​មិន​រក្សាទុក"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> លើសពីកម្រិតកំណត់មេម៉ូរី"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"ព័ត៌មានកែបញ្ហាត្រូវបាន​ប្រមូល។ សូមចុចដើម្បីចែករំលែក។"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ចែករំលែក heap dump?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"ដំណើរការ <xliff:g id="PROC">%1$s</xliff:g> បានលើសកម្រិតកំណត់មេម៉ូរីរបស់វាដែលមានទំហំ <xliff:g id="SIZE">%2$s</xliff:g>។ Heap dump មានផ្តល់ជូនដល់អ្នកដើម្បីចែករំលែកជាមួយអ្នកអភិវឌ្ឍន៍របស់វា។ ត្រូវប្រុងប្រយ័ត្ន៖ Heap dump នេះអាចផ្ទុកព័ត៌មានផ្ទាល់ខ្លួនរបស់អ្នកណាមួយ ដែលកម្មវិធីអាចចូលប្រើបាន។"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"ជ្រើស​សកម្មភាព​សម្រាប់​អត្ថបទ"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"កម្រិត​សំឡេង​រោទ៍"</string>
     <string name="volume_music" msgid="5421651157138628171">"កម្រិត​សំឡេង​មេឌៀ"</string>
@@ -1256,8 +1296,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ចុចដើម្បីមើលបណ្តាញទាំងអស់"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"ភ្ជាប់"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"បណ្ដាញ​ទាំងអស់"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"អាចប្រើ​បណ្ដាញ Wi‑Fi ដែល​ណែនាំ​ដោយ <xliff:g id="NAME">%s</xliff:g> បាន"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"តើអ្នក​ចង់ភ្ជាប់​ទៅកាន់​បណ្ដាញ​ដែល​ណែនាំ​ដោយ <xliff:g id="NAME">%s</xliff:g> ដែរទេ?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"បាទ/ចាស"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ទេ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi នឹង​បើក​ដោយ​ស្វ័យប្រវត្តិ"</string>
@@ -1269,9 +1311,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ចូលទៅបណ្តាញ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi មិនមាន​ការតភ្ជាប់​អ៊ីនធឺណិតទេ"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ប៉ះសម្រាប់ជម្រើស"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"បានភ្ជាប់"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"ប្ដូរ​ទៅ​ការ​កំណត់​ហតស្ប៉ត​របស់អ្នក"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"រលកសញ្ញាហតស្ប៉តរបស់​អ្នកបាន​ផ្លាស់ប្ដូរ។"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"ឧបករណ៍​នេះ​មិន​អាច​ប្រើចំណូល​ចិត្ត​របស់អ្នកសម្រាប់តែ 5GHz ទេ។ ផ្ទុយ​មកវិញ ឧបករណ៍​នេះ​នឹង​ប្រើរលកសញ្ញា​ 5GHz នៅពេល​ដែលអាច​ប្រើបាន។"</string>
@@ -1356,6 +1403,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុសតាម​ USB"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"ចុច​ដើម្បី​បិទ​ការកែកំហុសតាម ​USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ជ្រើស​រើស ដើម្បី​បិទ​ការ​កែ​កំហុសតាម USB ។"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"មានទឹក ឬ​កម្ទេចផ្សេងៗ​នៅក្នុងរន្ធ USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"រន្ធ USB ត្រូវបាន​បិទ​ដោយ​ស្វ័យប្រវត្តិ។ សូមចុច​ដើម្បី​ស្វែងយល់​បន្ថែម។"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"អាច​ប្រើរន្ធ USB បានដោយ​សុវត្ថិភាព"</string>
@@ -1907,8 +1958,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"ប៉ះដើម្បីដោះសោប្រវត្តិរូបការងារ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"បានភ្ជាប់ទៅ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ប៉ះដើម្បីមើលឯកសារ"</string>
-    <string name="pin_target" msgid="3052256031352291362">"ខ្ទាស់"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"មិនខ្ទាស់"</string>
     <string name="app_info" msgid="6856026610594615344">"ព័ត៌មាន​កម្មវិធី"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"កំពុងចាប់ផ្តើមការបង្ហាញសាកល្បង…"</string>
@@ -1999,6 +2048,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"ការ​ជូនដំណឹង​ព័ត៌មាន​របស់​មុខងារ​ទម្លាប់"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ថ្ម​អាច​នឹង​អស់ មុនពេល​សាកថ្មធម្មតា"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"បាន​បើក​ដំណើរការកម្មវិធី​សន្សំ​ថ្ម ដើម្បីបង្កើនកម្រិត​ថាមពល​​ថ្ម"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ថត"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"​កម្មវិធី Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ឯកសារ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 69963ef05..1409e33 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi 통화"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"꺼짐"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi를 기본으로 설정"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"모바일에 최적화됨"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi에서만"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: 착신전환 안됨"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"버그 신고"</string>
     <string name="global_action_logout" msgid="935179188218826050">"세션 끝내기"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"스크린샷"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"버그 신고"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"현재 기기 상태에 대한 정보를 수집하여 이메일 메시지로 전송합니다. 버그 신고를 시작하여 전송할 준비가 되려면 약간 시간이 걸립니다."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"대화형 보고서"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"대부분의 경우 이 옵션을 사용합니다. 신고 진행 상황을 추적하고 문제에 대한 세부정보를 입력하고 스크린샷을 찍을 수 있습니다. 신고하기에 시간이 너무 오래 걸리고 사용 빈도가 낮은 일부 섹션을 생략할 수 있습니다."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"위치"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"이 기기의 위치정보에 액세스"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;에서 내 기기 위치에 액세스하도록 허용하시겠습니까?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"앱을 사용할 때만 앱에서 위치에 액세스합니다."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;에서 내 기기 위치에 액세스하도록 허용하시겠습니까?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"앱을 사용하지 않을 때에도 앱에서 항상 위치에 액세스합니다."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"캘린더"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"캘린더에 액세스"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;에서 내 캘린더에 액세스하도록 허용하시겠습니까?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;에서 내 음악에 액세스하도록 허용하시겠습니까?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"사진 및 동영상"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"사진 및 동영상에 액세스"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;에서 태그가 지정된 위치를 포함한 내 사진과 동영상에 액세스하도록 허용하시겠습니까?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"창 콘텐츠 가져오기"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"상호작용 중인 창의 콘텐츠를 검사합니다."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"터치하여 탐색 사용"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"앱이 NFC(근거리 무선 통신) 태그, 카드 및 리더와 통신할 수 있도록 허용합니다."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"화면 잠금 사용 중지"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"앱이 키 잠금 및 관련 비밀번호 보안을 사용중지할 수 있도록 허용합니다. 예를 들어, 휴대전화가 수신전화를 받을 때 키 잠금을 사용중지했다가 통화가 끝나면 키 잠금을 다시 사용할 수 있습니다."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"화면 잠금 복잡도 요청"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"앱이 화면 잠금 길이와 유형의 가능한 범위를 나타내는 잠금 화면 복잡도 수준(높음, 보통, 낮음 또는 없음)을 파악하도록 허용합니다. 앱이 사용자에게 화면 잠금을 특정 수준으로 업데이트할 것을 제안할 수도 있지만, 사용자는 자유롭게 이를 무시하고 다른 곳으로 이동할 수 있습니다. 화면 잠금은 일반 텍스트로 저장되지 않으므로 앱에서 정확한 비밀번호를 알 수 없습니다."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"생체 인식 하드웨어 사용"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"앱에서 생체 인식 하드웨어를 인증에 사용하도록 허용합니다."</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"지문 하드웨어 관리"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"사용할 얼굴 템플릿의 추가 및 삭제 메서드를 앱에서 호출하도록 허용합니다."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"얼굴 인증 하드웨어 사용"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"앱에서 얼굴 인증 하드웨어를 인증에 사용하도록 허용합니다."</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"얼굴을 인식할 수 없습니다. 다시 시도해 주세요."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"얼굴이 너무 밝습니다. 조명을 더 어둡게 해 보세요."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"얼굴이 너무 어둡습니다. 조명을 더 밝게 해 보세요."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"센서를 얼굴에서 더 멀리 떨어뜨려 주세요."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"센서를 얼굴에 더 가까이 대 주세요."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"센서를 위쪽으로 옮겨 주세요."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"센서를 아래쪽으로 옮겨 주세요."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"센서를 오른쪽으로 옮겨 주세요."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"센서를 왼쪽으로 옮겨 주세요."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"센서를 바라보세요."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"얼굴을 감지할 수 없습니다."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"너무 많이 움직였습니다."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"얼굴을 다시 등록해 주세요."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"다른 얼굴이 감지되었습니다."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"너무 비슷합니다. 다른 포즈를 취해 보세요."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"카메라를 더 똑바로 바라보세요."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"카메라를 더 똑바로 바라보세요."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"고개를 똑바로 세워 주세요."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"얼굴이 보이게 해 주세요."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"얼굴 인식 하드웨어를 사용할 수 없습니다."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"얼굴 인식 시간이 초과되었습니다. 다시 시도하세요."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"얼굴을 저장할 수 없습니다."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"얼굴 인식 작업이 취소되었습니다."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"사용자가 얼굴 인증을 취소했습니다."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"시도 횟수가 너무 많습니다. 나중에 다시 시도하세요."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"시도 횟수가 너무 많아 얼굴 인증이 사용 중지되었습니다."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"다시 시도해 보세요."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"등록된 얼굴이 없습니다."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"이 기기에는 얼굴 인증 센서가 없습니다."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"얼굴 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> 열기"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g>이(가) 저장되지 않고 종료됩니다."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g>에서 메모리 제한을 초과했습니다."</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"힙 덤프가 수집되었습니다. 공유하려면 탭하세요."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"힙 덤프를 공유할까요?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"프로세스 <xliff:g id="PROC">%1$s</xliff:g>에서 프로세스 메모리 한도(<xliff:g id="SIZE">%2$s</xliff:g>)를 초과했습니다. 힙 덤프를 개발자와 공유할 수 있습니다. 주의: 애플리케이션이 액세스할 수 있는 개인 정보가 이 힙 덤프에 포함되어 있을 수 있습니다."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"텍스트에 대한 작업 선택"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"벨소리 볼륨"</string>
     <string name="volume_music" msgid="5421651157138628171">"미디어 볼륨"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"모든 네트워크를 보려면 탭하세요."</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"연결"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"모든 네트워크"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g>에서 제안한 Wi‑Fi 네트워크를 사용할 수 있습니다"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g>이(가) 제안한 네트워크에 연결하시겠습니까?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"예"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"아니요"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi가 자동으로 사용 설정됨"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"네트워크에 로그인"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi가 인터넷에 연결되어 있지 않습니다"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"탭하여 옵션 보기"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"연결되었습니다."</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"핫스팟 설정 변경"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"핫스팟 대역이 변경되었습니다."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"이 기기에서는 5GHz 전용 환경설정이 지원되지 않습니다. 대신 가능할 때만 기기에서 5GHz 대역이 사용됩니다."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB 디버깅을 사용 중지하려면 탭하세요."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 포트에서 액체 또는 이물질 감지됨"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 포트가 자동으로 사용 중지되었습니다. 자세한 내용을 보려면 탭하세요."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB 포트를 사용해도 좋음"</string>
@@ -1396,8 +1447,7 @@
     <string name="ext_media_init_action" msgid="7952885510091978278">"설정"</string>
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"마운트 해제"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"둘러보기"</string>
-    <!-- no translation found for ext_media_seamless_action (6575980560886881233) -->
-    <skip />
+    <string name="ext_media_seamless_action" msgid="6575980560886881233">"출력 전환"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> 없음"</string>
     <string name="ext_media_missing_message" msgid="4012389235250987930">"기기를 다시 삽입하세요."</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> 이동 중"</string>
@@ -1906,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"탭하여 직장 프로필 잠금 해제"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>에 연결됨"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"파일을 확인하려면 탭하세요."</string>
-    <string name="pin_target" msgid="3052256031352291362">"고정"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"고정 해제"</string>
     <string name="app_info" msgid="6856026610594615344">"앱 정보"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"데모 시작 중..."</string>
@@ -1998,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"루틴 모드 정보 알림"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"평소에 충전하는 시간 전에 배터리가 소진될 수 있습니다."</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"배터리 수명을 연장하기 위해 배터리 세이버가 활성화되었습니다."</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"폴더"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android 애플리케이션"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"파일"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 95e85c6..b66ec15 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi аркылуу чалынууда"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Өчүк"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi тандалган"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Тандалган мобилдик түзмөк"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi гана"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Багытталган эмес"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ката тууралуу билдирүү"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Сеансты бүтүрүү"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Скриншот"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Ката тууралуу билдирүү түзүү"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Ушуну менен түзмөгүңүздүн учурдагы абалы тууралуу маалымат топтолуп, электрондук почта аркылуу жөнөтүлөт. Отчет даяр болгуча бир аз күтө туруңуз."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивдүү кабар"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Ката жөнүндө кабардын абалын жана көйгөй тууралуу кошумча маалыматты көрсөтүү үчүн ушул функцияны колдонууну сунуштайбыз. Ката жөнүндө кабар жөнөтүлүп жатканда көп убакыт талап кылынбашы үчүн негизги бөлүмдөр гана көрүнөт."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Жайгашкан жер"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"түзмөктүн жайгашкан жерин аныктоого"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосу бул түзмөктүн кайда жүргөнүн көрүп турганга уруксат бересизби?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Сиз бул колдонмону пайдаланып жатканда гана ал жайгашкан жериңизди көрө алат."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна бул түзмөктүн жайгашкан жерин пайдаланууга дайыма уруксат берилсинби?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Сиз бул колдонмону пайдаланбай турганда да ал жайгашкан жериңизди көрүп турат."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Жылнаама"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"жылнаамаңызды пайдалануу"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна жылнаамаңызды пайдаланууга уруксат берилсинби?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна музыканы пайдаланууга уруксат берилсинби?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Сүрөттөр жана видеолор"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"сүрөттөр менен видеолорго кирүү мүмкүнчүлүгү"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна сүрөттөрүңүздү, видеолоруңузду, анын ичинде тегделген жайгашкан жерлериңизди көрүүгө уруксат бересизби?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Терезедеги мазмунду алып турат"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Учурда ачылып турган терезедеги маалыматты талдайт."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\"Сыйпалап изилдөө\" мүмкүнчүлүгүн иштетет"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Колдонмого Жакынкы аралыкта байланышуу (NFC) белгилери, карталары жана окугучтары менен байланышуу мүмкүнчүлүгүн берет."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"экранды бөгөттөөнү өчүрүү"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Колдонмого экрандын бөгөттөөчү жана ага байланыштуу сырсөз коргоосун өчүрүү уруксатын берет. Мисалы, чалуу келгенде экрандын бөгөтүн алып салат, чалуу бүткөндө кайрадан орнотот."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"экранды бөгөттөөнүн татаалдык деңгээлин суроо"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Колдонмого экранды бөгөттөөнүн татаалдыгын (татаал, орточо, оңой же такыр жок) үйрөнүүгө мүмкүнчүлүк берет. Татаалдык деңгээли сырсөздүн узундугу жана экранды бөгөттөөнүн түрү боюнча айырмаланат. Колдонмо экранды бөгөттөөнү белгилүү деңгээлге тууралоону колдонуучуларга сунуштай да алат, бирок колдонуучулар ага көңүл бурбай койсо болот. Сырсөздү колдонмо билбеши үчүн, экранды бөгөттөө сырсөзүн кадимки текстте сактоого болбойт."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"биометрикалык аппаратты колдонуу"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Колдонмого аныктыгын текшерүү үчүн биометрикалык аппаратты пайдалануу мүмкүндүгүн берет"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"манжа изинин аппараттык камсыздоосун башкаруу"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Колдонмого пайдалануу үчүн жүздүн үлгүлөрүн кошуу жана жок кылуу мүмкүндүгүн берет."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"жүздүн аныктыгын текшерүүчү аппараттык камсыздоону колдонуу"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Колдонмого аныктыгын текшерүү үчүн жүздүн аныктыгын текшерүүчү аппараттык камсыздоону пайдалануу мүмкүндүгүн берет"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Жүзүңүз таанылбай койду. Кайра аракет кылыңыз."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Өтө жарык болуп жатат. Жаракты азайтып көрүңүз."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Өтө караңгы болуп жатат. Жарыкты ачып коюңуз."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Сенсорду бетиңизден алысыраак жылдырыңыз."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Сенсорду бетиңизге жакыныраак жылдырыңыз."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Сенсорду жогору жакка жылдырыңыз."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Сенсорду төмөн жакка жылдырыңыз."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Сенсорду оң жакка жылдырыңыз."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Сенсорду сол жакка жылдырыңыз."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Сенсорду караңыз."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Жүзүңүз табылган жок."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Кыймылдап жибердиңиз."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Жүзүңүздү кайра таанытыңыз."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Башка жүз аныкталды."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Мурункуга окшош болуп калды, башкача туруңуз."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Камерага түз караңыз."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Камерага түз караңыз."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Башыңызды түз кармаңыз."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Жүзүңүздү ачыңыз."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Жүздү аныктоочу аппараттык камсыздоо жеткиликсиз."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Жүздүн аныктыгын текшерүүнү күтүү мөөнөтү бүттү. Кайра аракет кылыңыз."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Жүздү сактоо мүмкүн эмес."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Жүздүн аныктыгын текшерүү жокко чыгарылды."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Жүздүн аныктыгын текшерүү колдонуучу аркылуу жокко чыгарылды."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Өтө көп жолу аракет жасадыңыз. Кийинчерээк кайра аракет кылыңыз."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Өтө көп жолу аракет жасадыңыз. Жүздүн аныктыгын текшерүү сенсору өчүрүлдү."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Кайра аракет кылыңыз."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Бир да жүз катталган жок."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Бул түзмөктө жүздүн аныктыгын текшерүү сенсору жок."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Жүз <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> колдонмосун ачуу"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> сакталбастан жабылат"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> эстутум чегинен ашып кетти"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Үймө дамп топтолду. Бөлүшүү үчүн таптап коюңуз."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Үймө дамп бөлүшүлсүнбү?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> процесси өзүнүн <xliff:g id="SIZE">%2$s</xliff:g> процесс чегинен ашып кетти. Үймө дамп сиз үчүн иштеп чыгуучу менен бөлүшүүгө даяр. Абайлаңыз: бул үймө дампта колдонмонун уруксаты бар жеке маалыматыңыз камтылышы мүмкүн."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Текст үчүн аракет тандаңыз"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Коңгуроонун үн көлөмү"</string>
     <string name="volume_music" msgid="5421651157138628171">"Мультимедианын үнү"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бардык тармактарды көрүү үчүн басыңыз"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Туташуу"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Бардык тармактар"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> сунуштаган Wi‑Fi тармагы жеткиликтүү"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> сунуштаган тармактарга туташкыңыз келеби?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ооба"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Жок"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi автоматтык түрдө күйөт"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Тармакка кирүү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi тармагы Интернетке туташпай турат"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Параметрлерди ачуу үчүн таптап коюңуз"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Туташты"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Туташуу түйүнүңүздүн жөндөөлөрүнө өзгөртүүлөр киргизилди"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Туташуу түйүнүңүздүн жыштыгы өзгөрдү."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Бул түзмөк 5ГГцти гана колдонуу жөндөөсүн колдоого албайт. Анын ордуна, бул түзмөк 5ГГц жыштыгын ал жеткиликтүү болгондо колдонот."</string>
@@ -1356,6 +1403,10 @@
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB аркылуу мүчүлүштүктөрдү оңдоону өчүрүү үчүн таптаңыз"</string>
     <!-- no translation found for adb_active_notification_message (8470296818270110396) -->
     <skip />
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портунда суюктук же урандылар бар"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт автоматтык түрдө өчүрүлдү. Кененирээк маалымат алуу үчүн таптап коюңуз."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB портун колдонууга болот"</string>
@@ -1907,8 +1958,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Таптап жумуш профилин ачыңыз"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> менен туташты"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Файлдарды көрүү үчүн таптап коюңуз"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Кадоо"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Кадоодон алып коюу"</string>
     <string name="app_info" msgid="6856026610594615344">"Колдонмо тууралуу"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Демо режим башталууда…"</string>
@@ -1999,6 +2048,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Режимдин адаттагы билдирмеси"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Батарея кубаттоого чейин отуруп калышы мүмкүн"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Батареянын отуруп калбашы үчүн Батареяны үнөмдөгүч режими иштетилди"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Папка"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android колдонмосу"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Файл"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 1e76147..84c4000 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"ການໂທ Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ປິດ"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ເລືອກໃຊ້ Wi​-Fi ກ່ອນ"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ຕ້ອງການໃຊ້ມືຖື"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi​-Fi ເທົ່າ​ນັ້ນ"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ບໍ່ຖືກສົ່ງຕໍ່"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ລາຍງານຂໍ້ຜິດພາດ"</string>
     <string name="global_action_logout" msgid="935179188218826050">"ສິ້ນສຸດເຊດຊັນ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ພາບໜ້າຈໍ"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"ໃຊ້ລາຍງານຂໍ້ບົກພ່ອງ"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"ນີ້ຈະເປັນການເກັບກຳຂໍ້ມູນກ່ຽວກັບ ສະຖານະປັດຈຸບັນຂອງອຸປະກອນທ່ານ ເພື່ອສົ່ງເປັນຂໍ້ຄວາມທາງອີເມວ. ມັນຈະໃຊ້ເວລາໜ້ອຍນຶ່ງ ໃນການເລີ່ມຕົ້ນການລາຍງານຂໍ້ຜິດພາດ ຈົນກວ່າຈະພ້ອມທີ່ຈະສົ່ງໄດ້, ກະລຸນາລໍຖ້າ."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ລາຍງານແບບໂຕ້ຕອບ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ໃຊ້ພາຍໃຕ້ສະຖານະການສ່ວນໃຫຍ່. ມັນອະນຸຍາດໃຫ້ທ່ານສາມາດຕິດຕາມສະຖານະລາຍງານ, ປ້ອນລາຍລະອຽດເພີ່ມເຕີມກ່ຽວກັບບັນຫາ ແລະ ຖ່າຍຮູບໜ້າຈໍໄດ້. ມັນອາດລະເລີຍພາກສ່ວນທີ່ບໍ່ຄ່ອຍໃຊ້ທີ່ໃຊ້ເວລາລາຍງານດົນອອກໄປ."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"ສະ​ຖານ​ທີ່"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"ເຂົ້າເຖິງຂໍ້ມູນສະຖານທີ່ຂອງອຸປະກອນນີ້"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"ອະນຸຍາດ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ໃຫ້ເຂົ້າເຖິງສະຖານທີ່ຂອງອຸປະກອນບໍ?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"ແອັບຈະມີສິດເຂົ້າເຖິງສະຖານທີ່ໃນເວລາທີ່ທ່ານກຳລັງໃຊ້ແອັບຢູ່ເທົ່ານັ້ນ."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"ອະນຸຍາດໃຫ້ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ເຂົ້າເຖິງສະຖານທີ່ຂອງອຸປະກອນນີ້ບໍ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"ແອັບຈະມີສິດເຂົ້າເຖິງສະຖານທີ່ທຸກເທື່ອ ເຖິງແມ່ນໃນເວລາທ່ານບໍ່ໃຊ້ແອັບຢູ່ກໍຕາມ."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ປະຕິທິນ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ເຂົ້າ​ຫາ​ປະ​ຕິ​ທິນ​ຂອງ​ທ່ານ"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"ອະນຸຍາດ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ໃຫ້ເຂົ້າເຖິງປະຕິທິນຂອງທ່ານບໍ?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"ອະນຸຍາດ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ໃຫ້ເຂົ້າເຖິງເພງຂອງທ່ານບໍ?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ຮູບພາບ ແລະ ວິດີໂອ"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"ເຂົ້າເຖິງຮູບພາບ ແລະ ວິດີໂອຂອງທ່ານ"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"ອະນຸຍາດໃຫ້ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ເຂົ້າເຖິງຮູບພາບ ແລະ ວິດີໂອຂອງທ່ານ, ຮວມທັງສະຖານທີ່ທີ່ຖືກແທັກນຳບໍ?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ດຶງຂໍ້ມູນເນື້ອຫາໃນໜ້າຈໍ"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ກວດກາເນື້ອຫາຂອງໜ້າຈໍທີ່ທ່ານກຳລັງມີປະຕິສຳພັນນຳ."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ເປີດໃຊ້ \"ການສຳຫຼວດໂດຍສຳຜັດ\""</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"ອະນຸຍາດໃຫ້ແອັບຯຕິດຕໍ່ສື່ສານກັບປ້າຍກຳກັບ, ບັດ ແລະໂຕອ່ານຂອງການສື່ສານໄລຍະສັ້ນ (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ປິດການລັອກໜ້າຈໍ"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ອະນຸຍາດໃຫ້ແອັບຯປິດການເຮັດວຽກຂອງປຸ່ມລັອກ ແລະລະບົບຄວາມປອດໄພຂອງລະຫັດຜ່ານທີ່ເຊື່ອມໂຍງກັນ. ໂຕຢ່າງ: ໂທລະສັບຈະປິດການເຮັດວຽກຂອງປຸ່ມລັອກເມື່ອມີສາຍໂທເຂົ້າ ຈາກນັ້ນຈຶ່ງເປີດໃຊ້ໄດ້ອີກເມື່ອວາງສາຍແລ້ວ."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ຮ້ອງຂໍຄວາມຊັບຊ້ອນການລັອກໜ້າຈໍ"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"ອະນຸຍາດໃຫ້ແອັບສຶກສາລະດັບຄວາມຊັບຊ້ອນຂອງໜ້າຈໍລັອກ (ສູງ, ກາງ, ຕ່ຳ ຫຼື ບໍ່ມີ), ເຊິ່ງລະບຸຂອບເຂດຄວາມເປັນໄປໄດ້ຂອງຄວາມຍາວ ແລະ ປະເພດຂອງການລັອກໜ້າຈໍ. ແອັບນີ້ສາມາດແນະນຳຜູ້ໃຊ້ວ່າເຂົາເຈົ້າສາມາດອັບເດດໜ້າຈໍລັອກເປັນລະດັບໃດໜຶ່ງເປັນການສະເພາະໄດ້, ແຕ່ຜູ້ໃຊ້ສາມາດທີ່ຈະບໍ່ສົນໃຈ ຫຼື ເປີດໄປອັນອື່ນໄດ້. ກະລຸນາຮັບຊາບວ່າການລັອກໜ້າຈໍບໍ່ໄດ້ບັນທຶກໃນແບບຂໍ້ຄວາມທຳມະດາ, ດັ່ງນັ້ນແອັບຈະບໍ່ຮູ້ລະຫັດຜ່ານທີ່ແນ່ນອນ."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ໃຊ້ຮາດແວຊີວະມິຕິ"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"ອະນຸຍາດໃຫ້ແອັບນຳໃຊ້ຮາດແວຊີວະມິຕິສຳລັບການພິສູດຢືນຢັນ"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ຈັດ​ການ​ຮາດ​ແວ​ລາຍ​ນີ້ວ​ມື"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ອະນຸຍາດໃຫ້ແອັບເປີດວິທີການຕ່າງໆເພື່ອເພີ່ມ ແລະ ລຶບແມ່ແບບໃບໜ້າສຳລັບການນຳໃຊ້."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"ໃຊ້ຮາດແວການກວດສອບຄວາມຖືກຕ້ອງດ້ວຍໃບໜ້າ"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ຮາດແວການກວດສອບຄວາມຖືກຕ້ອງດ້ວຍໃບໜ້າສຳລັບການກວດສອບຄວາມຖືກຕ້ອງ"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"ບໍ່ສາມາດປະມວນຜົນຂໍ້ມູນໃບໜ້າໄດ້. ກະລຸນາລອງອີກຄັ້ງ."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"ໃບໜ້າສະຫວ່າງເກີນໄປ. ກະລຸນາລອງໃນບ່ອນທີ່ແສງໜ້ອຍກວ່າ."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"ໃບໜ້າມືດເກີນໄປ. ກະລຸນາເປີດແຫຼ່ງກຳເນີດແສງ."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"ກະລຸນາຍ້າຍເຊັນເຊີອອກຫ່າງຈາກໃບໜ້າຕື່ມອີກ."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"ກະລຸນາຍ້າຍເຊັນເຊີເຂົ້າໃກ້ໃບໜ້າຕື່ມອີກ."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"ກະລຸນາຍ້າຍເຊັນເຊີໃຫ້ສູງຂຶ້ນອີກ."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"ກະລຸນາຍ້າຍເຊັນເຊີໃຫ້ຕໍ່າລົງອີກ."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"ກະລຸນາຍ້າຍເຊັນເຊີໄປເບື້ອງຂວາ."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"ກະລຸນາຍ້າຍເຊັນເຊີໄປເບື້ອງຊ້າຍ."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"ກະລຸນາແນມເບິ່ງເຊັນເຊີ."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"ກວດບໍ່ພົບໃບໜ້າ."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"ເຄື່ອນໄຫວຫຼາຍເກີນໄປ."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ກະລຸນາລົງທະບຽນອຸປະກອນຂອງທ່ານອີກເທື່ອໜຶ່ງ."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"ກວດພົບໃບໜ້າຕ່າງກັນ."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ຄ້າຍກັນເກີນໄປ, ກະລຸນາປ່ຽນທ່າຂອງທ່ານ."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"ກະລຸນາເບິ່ງຊື່ໆໄປທາງກ້ອງຫຼາຍຂຶ້ນ."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"ກະລຸນາເບິ່ງຊື່ໆໄປທາງກ້ອງຫຼາຍຂຶ້ນ."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"ກະລຸນາຍັບຫົວຂອງທ່ານໃຫ້ຊື່ຕາມລວງຕັ້ງ."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"ກະລຸນາຢ່າປິດບັງໃບໜ້າຂອງທ່ານ."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"ຮາດແວກວດໃບໜ້າບໍ່ສາມາດໃຊ້ໄດ້."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"ໝົດເວລາກວດໃບໜ້າແລ້ວ. ກະລຸນາລອງອີກຄັ້ງ."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"ບໍ່ສາມາດເກັບຮັກສາໃບໜ້າໄວ້ໄດ້."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ຍົກເລີກການດຳເນີນການກັບໃບໜ້າແລ້ວ."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"ຜູ້ໃຊ້ຍົກເລີກການພິສູດຢືນຢັນໃບໜ້າແລ້ວ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ມີຄວາມພະຍາຍາມຫຼາຍຄັ້ງເກີນໄປ. ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ມີຄວາມພະຍາຍາມຫຼາຍຄັ້ງເກີນໄປ. ປິດນຳໃຊ້ການກວດສອບຄວາມຖືກຕ້ອງດ້ວຍໃບໜ້າແລ້ວ."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"ລອງອີກຄັ້ງ."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"ບໍ່ໄດ້ລົງທະບຽນໃບໜ້າໃດ."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີກວດສອບຄວາມຖືກຕ້ອງດ້ວຍໃບໜ້າ."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"ໃບໜ້າ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Open <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> will close without saving"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ເກີນ​ຂີດ​ຄວາມ​ຈຳ​ແລ້ວ"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"ກວດພົບ Heap dump. ແຕະເພື່ອແບ່ງປັນ."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ແບ່ງ​ປັນ​ການ​ເທກອງ​ບໍ?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"ຂະ​ບວນ​ການ <xliff:g id="PROC">%1$s</xliff:g> ເກີນ​ຂີດ​ຈຳ​ກັດ​ຄວາມ​ຈຳ​ຂະ​ບວນ​ການ​ຂອງ​ມັນ​ຂອງ <xliff:g id="SIZE">%2$s</xliff:g> ແລ້ວ. ການ​ເທກອງ​ມີ​ໃຫ້​ສຳ​ລັບ​ທ່ານ ເພື່ອ​ແບ່ງ​ປັນ​ກັບ​ຜູ້​ພ​ັດ​ທະ​ນາ​ຂອງ​ມັນ. ລະ​ວັງ: ການ​ເທກອງ​ນີ້​ສາ​ມາດ​ມີ​ຂໍ້​ມູນ​ສ່ວນ​ຕົວ​ໃດ​ໜຶ່ງ​ຂອງ​ທ່ານ ທີ່​ແອັບ​ພ​ລິ​ເຄ​ຊັນ​ມີ​ການ​ເຂົ້າ​ຫາ."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"ເລືອກການເຮັດວຽກຂອງຂໍ້ຄວາມ"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"ລະດັບສຽງເອີ້ນເຂົ້າ"</string>
     <string name="volume_music" msgid="5421651157138628171">"ລະດັບສຽງຂອງສື່"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ແຕະເພື່ອເບິ່ງເຄືອຂ່າຍທັງໝົດ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"ເຊື່ອມ​ຕໍ່"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ເຄືອຂ່າຍທັງໝົດ"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"ສາມາດໃຊ້ເຄືອຂ່າຍ Wi‑Fi ທີ່ <xliff:g id="NAME">%s</xliff:g> ສະເໜີໄດ້"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"ທ່ານຕ້ອງການເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍທີ່ສະເໜີໂດຍ <xliff:g id="NAME">%s</xliff:g> ຫຼືບໍ່?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ແມ່ນ"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ບໍ່ແມ່ນ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ຈະມີການເປີດໃຊ້ Wi‑Fi ອັດຕະໂນມັດ"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi ບໍ່ມີສັນຍານອິນເຕີເນັດ"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ແຕະເພື່ອເບິ່ງຕົວເລືອກ"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"ເຊື່ອມຕໍ່ແລ້ວ"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"ການປ່ຽນແປງການຕັ້ງຄ່າຮັອດສະປອດຂອງທ່ານ"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"ຄື້ນຄວາມຖີ່ຮັອດສະປອດຂອງທ່ານປ່ຽນແປງແລ້ວ."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"ອຸປະກອນນີ້ບໍ່ຮອງຮັບການຕັ້ງຄ່າຂອງທ່ານສຳລັບ 5GHz ເທົ່ານັ້ນ. ແຕ່ວ່າອຸປະກອນນີ້ຈະໃຊ້ຄື້ນຄວາມຖີ່ 5GHz ເມື່ອສາມາດໃຊ້ໄດ້."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັກຜ່ານ USB ແລ້ວ"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"ແຕະເພື່ອປິດການດີບັກ USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ເລືອກເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ມີຂອງແຫລວ ຫຼື ເສດດິນໃນຜອດ USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ປິດຜອດ USB ໂດຍອັດຕະໂນມັດແລ້ວ. ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"ປອດໄພທີ່ຈະໃຊ້ຜອດ USB ແລ້ວ"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"ແຕະເພື່ອປົດລັອກໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"ເຊື່ອມຕໍ່ກັບ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ແລ້ວ"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ແຕະເພື່ອເບິ່ງໄຟລ໌"</string>
-    <string name="pin_target" msgid="3052256031352291362">"ປັກໝຸດ"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"ຖອນປັກໝຸດ"</string>
     <string name="app_info" msgid="6856026610594615344">"ຂໍ້ມູນແອັບ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ກຳລັງເລີ່ມເດໂມ…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"ການແຈ້ງເຕືອນຂໍ້ມູນໂໝດກິດຈະວັດປະຈຳວັນ"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ແບັດເຕີຣີອາດໝົດກ່ອນການສາກຕາມປົກກະຕິ"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"ເປີດຕົວປະຢັດແບັດເຕີຣີເພື່ອຂະຫຍາຍອາຍຸແບັດເຕີຣີ"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ໂຟນເດີ"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"ແອັບພລິເຄຊັນ Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ໄຟລ໌"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 94ab46c..2d6e4cb 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -143,8 +143,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"„Wi-Fi“ skambinimas"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Išjungta"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Pageidautinas „Wi-Fi“ ryšys"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Pirmenybė mobiliojo ryšio tinklui"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Tik „Wi-Fi“"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: neperadresuota"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -232,7 +234,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Pranešimas apie riktą"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Baigti seansą"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekrano kopija"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Pranešti apie riktą"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Bus surinkta informacija apie dabartinę įrenginio būseną ir išsiųsta el. pašto pranešimu. Šiek tiek užtruks, kol pranešimas apie riktą bus paruoštas siųsti; būkite kantrūs."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interakt. ataskaita"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Naudokite tai esant daugumai aplinkybių. Galite stebėti ataskaitos eigą, įvesti daugiau išsamios informacijos apie problemą ir padaryti ekrano kopijų. Gali būti praleidžiamos kelios rečiau naudojamos skiltys, kurių ataskaitų teikimas ilgai trunka."</string>
@@ -287,9 +290,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Vietovė"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"pasiekti įrenginio vietovės informaciją"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Suteikti &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; galimybę pasiekti įrenginio vietovę?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Programa galės pasiekti vietovę, tik kai ją naudosite."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Visada leisti programai &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pasiekti šio įrenginio vietovę?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Programa visada galės pasiekti vietovę, net kai jos nenaudosite."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendorius"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pasiekti kalendorių"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Suteikti &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; galimybę pasiekti kalendorių?"</string>
@@ -322,7 +328,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Suteikti programai &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; prieigą prie muzikos?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Nuotraukos ir vaizdo įrašai"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"pasiekti nuotraukas ir vaizdo įrašus"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Leisti programai &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pasiekti nuotraukas ir vaizdo įrašus, įskaitant pažymėtas vietoves?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Gauti lango turinį"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tikrinti lango, su kuriuo sąveikaujate, turinį."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Įjungti „Naršyti paliečiant“"</string>
@@ -515,8 +524,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Leidžiama programai perduoti artimojo lauko ryšių technologijos (ALR) žymas, korteles ir skaitymo programas."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"išjungti ekrano užraktą"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Leidžiama programai neleisti klavišo užrakto ir visos susijusios slaptažodžio apsaugos. Pvz., telefonas neleidžia klavišo užrakto priimant gaunamąjį skambutį ir pakartotinai jį įgalina, kai skambutis baigiamas."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"pateikti ekrano užrakto sudėtingumo užklausą"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Leidžiama programai sužinoti ekrano užrakto sudėtingumo lygį (aukštas, vidutinis, žemas arba nėra), nurodantį galimą ekrano užrakto trukmės diapazoną ir tipą. Be to, programa gali pasiūlyti naudotojams atnaujinti ekrano užraktą į tam tikrą lygį, bet naudotojai gali laisvai nepaisyti ir išeiti. Atminkite, kad ekrano užraktas nesaugomas kaip grynasis tekstas, todėl programa nežino tikslaus slaptažodžio."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"naudoti biometrinę aparatinę įrangą"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Leidžiama programai naudoti biometrinę aparatinę įrangą tapatybei nustatyti"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"tvarkyti piršto antspaudo aparatinę įrangą"</string>
@@ -571,37 +582,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Programai leidžiama aktyv. metodus, norint pridėti ir ištrinti naudojamus veidų šablonus."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"naudoti veido autentifikavimo aparatinę įrangą"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Programai leidžiama naudoti veido autentifikavimo aparatinę įrangą tapatybei nustatyti"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Nepavyko apdoroti veido. Bandykite dar kartą."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Veidas per šviesus. Band. sumažinti apšvietimą."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Veidas per tamsus. Atidenkite apšvietimo šaltinį."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Patraukite jutiklį toliau nuo veido."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Laikykite jutiklį arčiau veido."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Pakelkite jutiklį aukščiau."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Nuleiskite jutiklį žemiau."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Patraukite jutiklį dešinėn."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Patraukite jutiklį kairėn."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Žiūrėkite į jutiklį."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Neaptikta jokių veidų."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Įrenginys per daug judinamas."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Užregistruokite veidą iš naujo."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Aptiktas kitas veidas."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Per daug panašu, pakeiskite veido išraišką."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Žiūrėkite tiesiai į fotoaparatą."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Žiūrėkite tiesiai į fotoaparatą."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Laikykite galvą vertikaliai."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Atidenkite veidą."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Veido atpažinimo aparatinė įranga nepasiekiama."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Baigėsi veido atpaž. skirt. laik. Band. dar kartą."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Nepavyko išsaugoti veido duomenų."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Veido atpažinimo operacija atšaukta."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Veido autentifikavimą atšaukė naudotojas."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Per daug bandymų. Vėliau bandykite dar kartą."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Per daug bandymų. Veido autentifik. išjungtas."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Bandykite dar kartą."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Neužregistruota jokių veidų."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Šiame įrenginyje nėra veido autentifikavimo jutiklio."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> veidas"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1253,9 +1286,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Atidaryti „<xliff:g id="NEW_APP">%1$s</xliff:g>“"</string>
     <string name="new_app_description" msgid="5894852887817332322">"„<xliff:g id="OLD_APP">%1$s</xliff:g>“ bus uždaryta neišsaugojus duomenų"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"„<xliff:g id="PROC">%1$s</xliff:g>“ viršijo atminties limitą"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Atminties išklotinės duomenys surinkti. Palieskite, jei norite bendrinti."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Bendrinti atminties išklotinę?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Procesas „<xliff:g id="PROC">%1$s</xliff:g>“ viršijo atminties limitą <xliff:g id="SIZE">%2$s</xliff:g>. Atminties išklotinė pasiekiama, kad galėtumėte bendrinti su jos kūrėju. Būkite atsargūs: šioje atminties išklotinėje gali būti jūsų asmeninės informacijos, kurią gali pasiekti programa."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Pasirinkite teksto veiksmą"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Skambučio garsumas"</string>
     <string name="volume_music" msgid="5421651157138628171">"Medijos garsumas"</string>
@@ -1298,8 +1338,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Palieskite, jei norite matyti visus tinklus"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Prisijungti"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Visi tinklai"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Pasiekiamas „<xliff:g id="NAME">%s</xliff:g>“ siūlomas „Wi‑Fi“ tinklas"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Ar norite prisijungti prie „<xliff:g id="NAME">%s</xliff:g>“ siūlomų tinklų?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Taip"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"„Wi‑Fi“ bus įjungtas automatiškai"</string>
@@ -1311,9 +1353,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prisijungti prie tinklo"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"„Wi‑Fi“ tinkle nėra interneto ryšio"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Palieskite, kad būtų rodomos parinktys."</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Prisijungta"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Viešosios interneto prieigos taško nustatymų pakeitimai"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Viešosios prieigos taško dažnio juosta pasikeitė."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Šiame įrenginyje nepalaikoma tik 5 GHz nuostata. Vietoj to šiame įrenginyje bus naudojama 5 GHz dažnio juosta, kai bus pasiekiama."</string>
@@ -1398,6 +1445,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Palieskite, kad išjungtumėte USB derinimą"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB prievade yra skysčių ar smulkių dalelių"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB prievadas automatiškai išjungtas. Palieskite, kad sužinotumėte daugiau."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Saugu naudoti USB prievadą"</string>
@@ -1973,8 +2024,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Paliesk., kad atr. darbo prof."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Prisijungta prie „<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>“"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Palieskite, kad peržiūrėtumėte failus"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Prisegti"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Atsegti"</string>
     <string name="app_info" msgid="6856026610594615344">"Programos informacija"</string>
     <string name="negative_duration" msgid="5688706061127375131">"–<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Paleidžiama demonstracinė versija…"</string>
@@ -2067,6 +2116,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Veiksmų sekos režimo informacijos pranešimas"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Akumuliatoriaus energija gali išsekti prieš įprastą įkrovimą"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Akumuliatoriaus tausojimo priemonė suaktyvinta, kad akumuliatorius veiktų ilgiau"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Aplankas"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"„Android“ programa"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Failas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 53ab075..93f86e6 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -142,8 +142,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi zvani"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Izslēgts"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Vēlams Wi-Fi tīkls"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Vēlams mobilo datu savienojums"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Tikai Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: nav pāradresēts"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -230,7 +232,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Kļūdu ziņojums"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Beigt sesiju"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekrānuzņēmums"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Kļūdu ziņojuma sagatavošana"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Veicot šo darbību, tiks apkopota informācija par jūsu ierīces pašreizējo stāvokli un nosūtīta e-pasta ziņojuma veidā. Kļūdu ziņojuma pabeigšanai un nosūtīšanai var būt nepieciešams laiks. Lūdzu, esiet pacietīgs."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktīvs pārskats"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Izmantojiet lielākajā daļā gadījumu. Varat izsekot pārskata izveides norisi, ievadīt papildu informāciju par problēmu un izveidot ekrānuzņēmumus. Var tikt izlaistas dažas mazāk izmantotas sadaļas, kuru izveidei nepieciešams daudz laika."</string>
@@ -284,9 +287,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Atrašanās vieta"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"piekļūt ierīces atrašanās vietas informācijai"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vai atļaut lietotnei &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; piekļūt šīs ierīces atrašanās vietai?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Lietotne varēs piekļūt atrašanās vietai tikai tad, kad izmantosiet šo lietotni."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Vienmēr atļaut &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; piekļūt atrašanās vietai?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Lietotne vienmēr varēs piekļūt atrašanās vietai, pat ja neizmantosiet šo lietotni."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendārs"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"piekļūt jūsu kalendāram"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vai atļaut lietotnei &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; piekļūt jūsu kalendāram?"</string>
@@ -319,7 +325,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Vai atļaut lietotnei &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; piekļūt jūsu mūzikai?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotoattēli un videoklipi"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"Piekļūt jūsu fotoattēliem un videoklipiem"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Vai atļaut lietotnei &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; piekļūt jūsu fotoattēliem, videoklipiem, tostarp atzīmētajām atrašanās vietām?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Izgūt loga saturu."</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Skatīt tā loga saturu, ar kuru mijiedarbojaties."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivizēt funkciju “Pārlūkot pieskaroties”."</string>
@@ -512,8 +521,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Ļauj lietotnei sazināties ar tuva darbības lauka sakaru (Near Field Communication — NFC) atzīmēm, kartēm un lasītājiem."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"atspējot ekrāna bloķēšanu"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Ļauj lietotnei atspējot taustiņslēgu un visu saistīto paroļu drošību. Piemēram, tālrunis atspējo taustiņslēgu, saņemot ienākošu zvanu, un pēc zvana pabeigšanas atkārtoti iespējo taustiņslēgu."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"Ekrāna bloķēšanas sarežģītības pakāpes informācijas pieprasījums"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Atļauj lietotnei piekļūt informācijai par ekrāna bloķēšanas sarežģītības pakāpi (augsta, vidēja, zema, nav), kas apzīmē iespējamo paroles garumu un ekrāna bloķēšanas veidus. Lietotnē lietotājiem var tikt rādīts arī ieteikums ekrāna bloķēšanai iestatīt citu līmeni, taču šo ieteikumu var ignorēt un aizvērt. Ņemiet vērā, ka ekrāna bloķēšanas parole netiek glabāta vienkārša teksta formātā, tāpēc lietotnei nav piekļuves precīzai parolei."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"izmantot biometrisko datu aparatūru"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Atļauj lietotnei izmantot biometrisko datu aparatūru autentificēšanai"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"pārvaldīt pirkstu nospiedumu aparatūru"</string>
@@ -568,37 +579,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Atļauj lietotnei izsaukt metodes izmantojamo sejas veidņu pievienošanai un dzēšanai."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"izmantot sejas autentifikācijas aparatūru"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Atļauj lietotnei izmantot sejas autentifikācijas aparatūru autentificēšanai"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Nevarēja apstrādāt sejas datus. Mēģiniet vēlreiz."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Seja ir pārāk izgaismota. Mēģiniet tumšākā vidē."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Pārāk tumšs sejas attēls. Mēģiniet gaišākā vidē."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Pavirziet sensoru tālāk no sejas."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Pavirziet sensoru tuvāk sejai."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Pavirziet sensoru augstāk."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Pavirziet sensoru zemāk."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Pavirziet sensoru pa labi."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Pavirziet sensoru pa kreisi."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Lūdzu, paskatieties uz sensoru."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nav atrasta neviena seja."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Pārāk daudz kustību."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Lūdzu, atkārtoti reģistrējiet savu seju."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Tika noteikta cita seja."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Pārāk līdzīgi. Lūdzu, mainiet pozu."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Lūdzu, tiešāk skatieties uz kameru."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Lūdzu, tiešāk skatieties uz kameru."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Lūdzu, vertikāli iztaisnojiet galvu."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Lūdzu, atsedziet seju."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Sejas autentifikācijas aparatūra nav pieejama."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Sejas datu nolasīšanas noildze. Mēģiniet vēlreiz."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Sejas datus nevar saglabāt."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Darbība ar sejas datiem atcelta."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Lietotājs atcēla sejas autentificēšanu."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Pārāk daudz mēģinājumu. Vēlāk mēģiniet vēlreiz."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Par daudz mēģinājumu. Sejas atpazīšana atspējota."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Mēģiniet vēlreiz."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nav reģistrēti sejas dati."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Šai ierīcei nav sejas autentifikācijas sensora."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Seja <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1233,9 +1266,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Atvērt <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"Lietotne <xliff:g id="OLD_APP">%1$s</xliff:g> tiks aizvērta, neko nesaglabājot"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Process <xliff:g id="PROC">%1$s</xliff:g> pārsniedza atmiņas ierobežojumu."</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Apkopots kaudzes izraksts. Pieskarieties, lai kopīgotu."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vai kopīgot kaudzes izrakstu?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Process <xliff:g id="PROC">%1$s</xliff:g> pārsniedza procesu atmiņas ierobežojumu (<xliff:g id="SIZE">%2$s</xliff:g>). Tika apkopots kaudzes izraksts, ko varat kopīgot ar procesa izstrādātāju. Ņemiet vērā: kaudzes izrakstā var būt ietverta jūsu personas informācija, kurai var piekļūt lietojumprogramma."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Izvēlieties darbību tekstam"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Zvanītāja skaļums"</string>
     <string name="volume_music" msgid="5421651157138628171">"Multivides skaļums"</string>
@@ -1276,8 +1316,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Pieskarieties, lai skatītu visus tīklus"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Izveidot savienojumu"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Visi tīkli"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Ir pieejams Wi‑Fi tīkls, ko ieteica <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Vai vēlaties izveidot savienojumu ar tīkliem, ko ieteica <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Jā"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nē"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi tiks automātiski ieslēgts"</string>
@@ -1289,9 +1331,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Pierakstīšanās tīklā"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi tīklā nav piekļuves internetam."</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Pieskarieties, lai skatītu iespējas."</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Izveidots savienojums"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Izmaiņas tīklāja iestatījumos"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Ir mainīts tīklāja joslas platums."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Šajā ierīcē netiek atbalstīta jūsu preference par tikai 5 GHz joslu. 5 GHz josla ierīcē tiks izmantota, kad tā būs pieejama."</string>
@@ -1376,6 +1423,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Pieskarieties, lai izslēgtu USB atkļūdošanu"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB pieslēgvietā ir šķidrums vai daļiņas"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB pieslēgvieta ir automātiski atspējota. Pieskarieties, lai uzzinātu vairāk."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB pieslēgvietas izmantošana ir droša"</string>
@@ -1939,8 +1990,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Pieskarieties, lai atbloķētu."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Izveidots savienojums ar: <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Pieskarieties, lai skatītu failus."</string>
-    <string name="pin_target" msgid="3052256031352291362">"Piespraust"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Atspraust"</string>
     <string name="app_info" msgid="6856026610594615344">"Lietotnes informācija"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Notiek demonstrācijas palaišana..."</string>
@@ -2032,6 +2081,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Informatīvs paziņojums par akumulatoru"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Akumulators var izlādēties pirms parastā uzlādes laika"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Aktivizēts akumulatora jaudas taupīšanas režīms, lai palielinātu akumulatora darbības ilgumu"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Mape"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android lietojumprogramma"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fails"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 4e0b47a..20d42ad 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Повикување преку Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"Глас преку Wi-Fi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Исклучено"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Се претпочита Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Претпочитам мобилен интернет"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Само Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не е препратено"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Извештај за грешка"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Завршете ја сесијата"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Слика од екранот"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Направи извештај за грешки"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Ова ќе собира информации за моменталната состојба на вашиот уред, за да ги испрати како порака по е-пошта. Тоа ќе одземе малку време почнувајќи од извештајот за грешки додека не се подготви за праќање; бидете трпеливи."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивен извештај"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Користете го ова во повеќето ситуации. Ви дозволува да го следите напредокот на извештајот, да внесете повеќе детали во врска со проблемот и да сликате слики од екранот. Може да испушти некои помалку користени делови за коишто е потребно долго време за да се пријават."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"пристапува до локацијата на овој уред"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Дали да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до локацијата на уредот?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Апликацијата ќе има пристап до локацијата само додека ја користите."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Дозволете &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; секогаш да пристапува до локацијата?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Апликацијата секогаш ќе има пристап до локацијата, дури и кога не ја користите."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"пристапува до календарот"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Дали да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до календарот?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Дали да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до музиката?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Фотографии и видеа"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"пристапува до фотографиите и видеата"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Дали да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да пристапува до фотографиите и видеата, вклучувајќи означени локации?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Преземе содржина на прозорец"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ја следи содржината на прозорецот со кој се комуницира."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Вклучи „Истражувај со допир“"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Дозволува апликацијата да комуницира со ознаки, картички и читачи за Комуникација при непосредна близина (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"оневозможи заклучување на екран"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Овозможува апликацијата да го оневозможи заклучувањето и каква било безбедност поврзана со лозинка. На пример, телефонот го оневозможува заклучувањето при прием на телефонски повик, а потоа повторно го овозможува заклучувањето кога повикот ќе заврши."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"побарува сложеност за заклучувањето на екранот"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Дозволува апликацијата да го научи нивото на сложеност за заклучувањето на екранот (високо, средно, ниско или нема), коешто ги означува можниот опсег на должината и типот на заклучувањето на екранот. Апликацијата може и да им предлага на корисниците да го ажурираат заклучувањето на екранот на одредено ниво, но корисниците може слободно да го игнорираат тоа и да продолжат понатаму. Имајте предвид дека заклучувањето на екранот не се складира како обичен текст, па така апликацијата не ја знае точната лозинка."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"користи биометриски хардвер"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Дозволува апликацијата да користи биометриски хардвер за проверка"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управувај хардвер за отпечатоци"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Дозволува апликац. да повика начини за додавање и бришење шаблони на лице за користење."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"користи хардвер за проверка на лице"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Дозволува апликацијата да користи хардвер за лице за проверка"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Лицето не можеше да се обработи. Обидете се пак."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Лицето е пресветло. Пробајте на послаба светлина."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Лицето е претемно. Пробајте со поголема светлина."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Оддалечете го сензорот од лицето."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Доближете го сензорот до лицето."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Подигнете го сензорот."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Спуштете го сензорот."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Поместете го сензорот надесно."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Поместете го сензорот налево."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Погледнете во сензорот."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Не е откриено лице."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Премногу движење."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Повторно регистрирајте го лицето."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Откриено е друго лице."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Премногу слично, сменете ја позата."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Гледајте подиректно во камерата."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Гледајте подиректно во камерата."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Исправете ја главата вертикално."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Откријте го вашето лице."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Хардверот за лице не е достапен."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Истече времето за проверка на лице. Повторен обид."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Лицето не може да се чува."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Операцијата со лице се откажа."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Проверката на лицето е откажана од корисникот."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Премногу обиди. Обидете се повторно подоцна."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Премногу обиди. Проверката на лице е оневозможена."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Обидете се повторно."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Нема регистрирано лице."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Уредов нема сензор за проверка на лице."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Отвори ја <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> ќе се затвори без да се зачува"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> го надмина ограничувањето на меморијата"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Сликата од меморијата е собрана. Допрете за споделување."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Сподели слика од меморија?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Процесот <xliff:g id="PROC">%1$s</xliff:g> го надмина ограничувањето на меморијата на својот процес од <xliff:g id="SIZE">%2$s</xliff:g>. Достапна ви е слика од меморијата да ја споделите со неговиот програмер. Бидете внимателни: сликата од меморијата може да содржи кои било од вашите лични информации до кои апликацијата има пристап."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Избери дејство за текст"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Јачина на звук на ѕвонче"</string>
     <string name="volume_music" msgid="5421651157138628171">"Јачина на аудио/видео звук"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Допрете за да ги видите сите мрежи"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Поврзете се"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Сите мрежи"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Wi‑Fi мрежата предложена од <xliff:g id="NAME">%s</xliff:g> е достапна"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Дали сакате да се поврзувате на мрежите што ги предлага <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ќе се вклучи автоматски"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Најавете се на мрежа"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi нема пристап до интернет"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Допрете за опции"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Поврзано"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Промени на поставките за точка на пристап"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Појасот за точка на пристап е променет."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Уредов не ги поддржува вашите поставки за само 5 GHz. Наместо тоа, ќе го користи појасот од 5 GHz кога е достапен."</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку USB"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Допрете за да го исклучите отстранувањето грешки преку USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете за да се оневозможи отстранување грешки на USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистотија во USB-портата"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-портата е автоматски оневозможена. Допрете за да дознаете повеќе."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Безбедно е да се користи USB-портата"</string>
@@ -1908,8 +1959,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Допрете за да го отклучите"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Поврзан на <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Допрете за да ги погледнете датотеките"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Прикачете"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Откачете"</string>
     <string name="app_info" msgid="6856026610594615344">"Информации за апликација"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Се вклучува демонстрацијата…"</string>
@@ -2000,6 +2049,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Известување за информации за режимот за рутини"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Батеријата може да се потроши пред вообичаеното време за полнење"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Активиран е „Штедачот на батерија“ за да се продолжи траењето на батеријата"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Папка"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Апликација за Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Датотека"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 13ca198..ca82238 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"വൈഫൈ കോളിംഗ്"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"Voവൈഫൈ"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ഓഫ്"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"വൈഫൈ തിരഞ്ഞെടുത്തിരിക്കുന്നു"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"മൊബൈൽ ഡാറ്റ ഉപയോഗിക്കാൻ താൽപ്പര്യപ്പെടുന്നു"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"വൈഫൈ മാത്രം"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: കൈമാറിയില്ല"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ബഗ് റിപ്പോർട്ട്"</string>
     <string name="global_action_logout" msgid="935179188218826050">"സെഷൻ അവസാനിപ്പിക്കുക"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"സ്‌ക്രീൻഷോട്ട്"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"ബഗ് റിപ്പോർട്ട് എടുക്കുക"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"ഒരു ഇമെയിൽ സന്ദേശമായി അയയ്‌ക്കുന്നതിന്, ഇത് നിങ്ങളുടെ നിലവിലെ ഉപകരണ നിലയെക്കുറിച്ചുള്ള വിവരങ്ങൾ ശേഖരിക്കും. ബഗ് റിപ്പോർട്ട് ആരംഭിക്കുന്നതിൽ നിന്ന് ഇത് അയയ്‌ക്കാനായി തയ്യാറാകുന്നതുവരെ അൽപ്പസമയമെടുക്കും; ക്ഷമയോടെ കാത്തിരിക്കുക."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ഇന്റരാക്റ്റീവ് റിപ്പോർട്ട്"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"മിക്ക സാഹചര്യങ്ങളിലും ഇത് ഉപയോഗിക്കുക. റിപ്പോർട്ടിന്റെ പുരോഗതി കാണാനും പ്രശ്നത്തെ കുറിച്ചുള്ള കൂടുതൽ വിശദാംശങ്ങൾ നൽകാനും സ്ക്രീൻഷോട്ടുകൾ എടുക്കാനും ഇത് അനുവദിക്കുന്നു. റിപ്പോർട്ടുചെയ്യാൻ നീണ്ട സമയം എടുക്കുന്നതും നിങ്ങൾ കുറച്ച് ഉപയോഗിക്കുന്നതുമായ ചില വിഭാഗങ്ങളെ ഇത് വിട്ടുകളഞ്ഞേക്കാം."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"ലൊക്കേഷൻ"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"ഈ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ആക്സസ് ചെയ്യാൻ"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"ഈ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാൻ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ആപ്പിനെ അനുവദിക്കണോ?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"നിങ്ങൾ ഉപയോഗിക്കുമ്പോൾ മാത്രം ആപ്പ് ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യും."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"ഈ ഉപകരണത്തിന്റെ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാൻ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; എപ്പോഴും ആപ്പിനെ അനുവദിക്കണോ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"നിങ്ങൾ ആപ്പ് ഉപയോഗിക്കാത്തപ്പോൾ പോലും, ഏതുസമയത്തും ആപ്പ് ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യും."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"കലണ്ടർ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ്സ് ചെയ്യുക"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ് ചെയ്യാൻ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ആപ്പിനെ അനുവദിക്കണോ?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; എന്നതിനെ നിങ്ങളുടെ സംഗീതം ആക്‌സസ് ചെയ്യാൻ അനുവദിക്കണോ?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ഫോട്ടോകളും വീഡിയോകളും"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"നിങ്ങളുടെ ഫോട്ടോകളും &amp; വീഡിയോകളും"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"ടാഗ് ചെയ്‌ത ലൊക്കേഷനുകൾ ഉൾപ്പെടെ നിങ്ങളുടെ ഫോട്ടോകളും വീഡിയോകളും ആക്‌സസ് ചെയ്യാൻ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-നെ അനുവദിക്കണോ?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"വിൻഡോ ഉള്ളടക്കം വീണ്ടെടുക്കുക"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"നിങ്ങൾ സംവദിക്കുന്ന ഒരു വിൻഡോയുടെ ഉള്ളടക്കം പരിശോധിക്കുക."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"സ്‌പർശനം വഴി പര്യവേക്ഷണം ചെയ്യുക, ഓണാക്കുക"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"നിയർ ഫീൽഡ് കമ്മ്യൂണിക്കേഷൻ (NFC) ടാഗുകളുമായും കാർഡുകളുമായും റീഡറുകളുമായുള്ള ആശയവിനിമയത്തിന് അപ്ലിക്കേഷനുകളെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"നിങ്ങളുടെ സ്‌ക്രീൻ ലോക്ക് പ്രവർത്തനരഹിതമാക്കുക"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"കീലോക്കും ഏതെങ്കിലും അനുബന്ധ പാസ്‌വേഡ് സുരക്ഷയും പ്രവർത്തനരഹിതമാക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഉദാഹരണത്തിന്, ഒരു ഇൻകമിംഗ് കോൾ സ്വീകരിക്കുമ്പോൾ ഫോൺ കീലോക്ക് പ്രവർത്തനരഹിതമാക്കുന്നു, കോൾ അവസാനിക്കുമ്പോൾ കീലോക്ക് വീണ്ടും പ്രവർത്തനക്ഷമമാകുന്നു."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"സ്‌ക്രീൻ ലോക്ക് സങ്കീർണ്ണത അഭ്യർത്ഥിക്കുക"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"സ്ക്രീൻ ലോക്കിന്റെ സാധ്യമായ നീളവും തരവും സൂചിപ്പിക്കുന്ന, അതിന്റെ സങ്കീർണ്ണത നില (ഉയർന്നത്, ഇടത്തരം, കുറഞ്ഞത് അല്ലെങ്കിൽ ഒന്നുമില്ല) മനസിലാക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു. സ്‌ക്രീൻ ലോക്ക് ഒരു പ്രത്യേക തലത്തിലേക്ക് അപ്ഡേറ്റ് ചെയ്യുന്ന ഉപയോക്താക്കൾക്ക് നിർദ്ദേശിക്കാനും ആപ്പിനാവും, മാത്രമല്ല ഉപയോക്താക്കൾക്ക് എളുപ്പത്തിൽ അവഗണിക്കാനും മറ്റൊന്നിലേക്ക് നാവിഗേറ്റ് ചെയ്യാനുമാവും. പ്ലെയിൻടെക്‌സ്‌റ്റിൽ സ്ക്രീൻ ലോക്ക് സംഭരിക്കപ്പെട്ടിട്ടില്ലെന്ന കാര്യം ശ്രദ്ധിക്കുക, അതിനാൽ ആപ്പിന് കൃത്യമായ പാസ്‌വേഡ് അറിയില്ല."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ബയോമെട്രിക് ഹാർ‌ഡ്‌വെയർ ഉപയോഗിക്കുക"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"പരിശോധിച്ചുറപ്പിക്കുന്നതിനായി, ബയോമെട്രിക് ഹാർഡ്‌വെയർ ഉപയോഗിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ഫിംഗർപ്രിന്റ് ഹാർഡ്‌വെയർ നിയന്ത്രിക്കുക"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ഉപയോഗിക്കാനായി, മുഖത്തിന്റെ ടെംപ്ലേറ്റുകൾ ചേർക്കാനും ഇല്ലാതാക്കാനുമുള്ള രീതികൾ അഭ്യർത്ഥിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"മുഖം തിരിച്ചറിയൽ ഹാർഡ്‌വെയർ ഉപയോഗിക്കുക"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"പരിശോധിച്ചുറപ്പിക്കലിനായി മുഖം തിരിച്ചറിയൽ ഹാർഡ്‌വെയർ  ഉപയോഗിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"മുഖം പ്രോസസ്സ് ചെയ്യാനായില്ല. വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"മുഖം വളരെ തെളിച്ചമുള്ളതാണ്. കുറഞ്ഞ വെളിച്ചത്തിൽ ശ്രമിക്കുക."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"മുഖം വളരെ ഇരുണ്ടതാണ്. പ്രകാശ ലഭ്യത ഉറപ്പാക്കി ശ്രമിക്കുക."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"മുഖത്തിനടുത്തുനിന്ന് സെൻസർ അകലേയ്ക്ക് നീക്കുക."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"സെൻസർ മുഖത്തിനടുത്തേയ്ക്ക് കൊണ്ടുവരിക."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"സെൻസർ മുകളിലേക്ക് നീക്കുക."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"സെൻസർ താഴേയ്ക്ക് നീക്കുക."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"സെൻസർ വലത്തേയ്ക്ക് നീക്കുക."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"സെൻസർ ഇടത്തേയ്ക്ക് നീക്കുക."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"സെൻസറിലേക്ക് നോക്കുക."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"മുഖം കണ്ടെത്താനായില്ല."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"ഉപകരണം വളരെയധികം ഇളകുന്നു."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"നിങ്ങളുടെ മുഖം വീണ്ടും എൻറോൾ ചെയ്യുക."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"മറ്റൊരു മുഖം തിരിച്ചറിഞ്ഞു."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"വളരെയധികം സമാനത, നിങ്ങളുടെ പോസ് മാറ്റുക."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"അൽപ്പം കൂടി ക്യാമറയ്‌ക്ക് നേരെ നോക്കൂ."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"അൽപ്പം കൂടി ക്യാമറയ്‌ക്ക് നേരെ നോക്കൂ."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"നിങ്ങളുടെ തല ലംബമായി നേരെയാക്കുക"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"നിങ്ങളുടെ മുഖം വ്യക്തമാക്കുക."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"മുഖത്തിന്റെ ഹാർഡ്‌വെയർ ലഭ്യമല്ല."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"മുഖം നൽകേണ്ട സമയം കഴിഞ്ഞു. വീണ്ടും ശ്രമിക്കുക."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"മുഖം സൂക്ഷിക്കാനാവില്ല."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"മുഖത്തിന്റെ പ്രവർത്തനം റദ്ദാക്കി."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"മുഖം പരിശോധിച്ചുറപ്പിക്കൽ ഉപയോക്താവ് റദ്ദാക്കി."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"നിരവധി തവണ ശ്രമിച്ചു. പിന്നീട് വീണ്ടും ശ്രമിക്കുക."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"നിരവധി തവണ ശ്രമിച്ചു. മുഖം തിരിച്ചറിയൽ പ്രവർത്തനരഹിതമാക്കി."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"ഒരു മുഖവും എൻറോൾ ചെയ്‌തിട്ടില്ല."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"ഈ ഉപകരണത്തിൽ മുഖം പരിശോധിച്ചുറപ്പിക്കാനുള്ള സെൻസറില്ല."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"മുഖം <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> തുറക്കുക"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> സംരക്ഷിക്കാതെ അവസാനിപ്പിക്കും"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> മെമ്മറി പരിധി കവിഞ്ഞു"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"ഹീപ്പ് ഡംപ് ശേഖരിച്ചു. പങ്കിടാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ഹീപ്പ് ഡംപ് പങ്കിടണോ?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> പ്രോസസ്സ് അതിന്റെ മെമ്മറി പരിധിയായ <xliff:g id="SIZE">%2$s</xliff:g> കവിഞ്ഞു. അതിന്റെ ഡവലപ്പറുമായി പങ്കിടാൻ ഒരു ഹീപ്പ് ഡംപ് നിങ്ങൾക്ക് ലഭ്യമാണ്. ശ്രദ്ധിക്കുക: ഈ ഹീപ്പ് ഡംപിൽ അപ്ലിക്കേഷന് ആക്‌സസ്സുള്ള ഏതെങ്കിലും സ്വകാര്യ വിവരങ്ങൾ അടങ്ങിയിരിക്കാം."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"വാചകസന്ദേശത്തിനായി ഒരു പ്രവർത്തനം തിരഞ്ഞെടുക്കുക"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"റിംഗർ വോളിയം"</string>
     <string name="volume_music" msgid="5421651157138628171">"മീഡിയ വോളിയം"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"എല്ലാ നെറ്റ്‌വർക്കുകളും കാണാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"കണക്റ്റുചെയ്യുക"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"എല്ലാ നെറ്റ്‌വർക്കുകളും"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> നിർദ്ദേശിച്ച വൈഫൈ നെറ്റ്‌വർക്ക് ലഭ്യമാണ്"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> നിർദ്ദേശിച്ച നെറ്റ്‌വർക്കുകളിലേക്ക് കണക്‌റ്റ് ചെയ്യണോ?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ഉവ്വ്"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ഇല്ല"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"വൈഫൈ സ്വമേധയാ ഓണാകും"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"നെറ്റ്‌വർക്കിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"വൈഫൈയ്ക്ക് ഇന്റർനെറ്റ് ആക്‌സസ് ഇല്ല"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ഓപ്ഷനുകൾക്ക് ടാപ്പുചെയ്യുക"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"കണക്‌റ്റ് ചെയ്‌തു"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"നിങ്ങളുടെ ഹോട്ട്‌സ്‌പോട്ട് ക്രമീകരണത്തിൽ വരുത്തിയ മാറ്റങ്ങൾ"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"നിങ്ങളുടെ ഹോട്ട്‌സ്‌പോട്ട് ബാൻഡ് മാറി."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"നിങ്ങളുടെ മുൻഗണനയനുസരിച്ചുള്ള, 5GHz മാത്രം എന്നത് ഈ ഉപകരണം പിന്തുണയ്ക്കുന്നില്ല. പകരം, 5GHz ബാൻഡ് ലഭ്യമാകുമ്പോൾ അത് ഉപയോഗിക്കും."</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്റ്റ് ചെയ്തു"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB ഡീബഗ്ഗിംഗ് ഓഫാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ഡീബഗ്ഗുചെയ്യൽ പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB പോർട്ടിൽ ദ്രാവകമോ പൊടിയോ കണ്ടെത്തി"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB പോർട്ടർ സ്വയമേവ പ്രവർത്തനരഹിതമായി. കൂടുതലറിയാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB പോർട്ട് ഇപ്പോൾ സുരക്ഷിതമായി ഉപയോഗിക്കാം"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"ഔദ്യോഗിക പ്രൊഫൈൽ അൺലോക്കുചെയ്യാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> എന്നതിലേക്ക് കണക്റ്റുചെയ്തു"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ഫയലുകൾ കാണുന്നതിന് ടാപ്പുചെയ്യുക"</string>
-    <string name="pin_target" msgid="3052256031352291362">"പിൻ ചെയ്യുക"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"അൺപിൻ ചെയ്യുക"</string>
     <string name="app_info" msgid="6856026610594615344">"ആപ്പ് വിവരം"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ഡെമോ ആരംഭിക്കുന്നു…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"ദിനചര്യ മോഡ് വിവരത്തെ കുറിച്ചുള്ള അറിയിപ്പ്"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"സാധാരണയുള്ളതിലും നേരത്തെ ബാറ്ററിയുടെ ചാർജ് തീർന്നേക്കാം"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"ബാറ്ററി ലൈഫ് വര്‍ദ്ധിപ്പിക്കാൻ, ബാറ്ററി ലാഭിക്കൽ സജീവമാക്കി"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ഫോള്‍ഡര്‍"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android ആപ്പ്"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ഫയൽ"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 101ef35..6a6974d 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi дуудлага"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Идэвхгүй"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi давуу эрхтэй"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Мобайл давуу эрхтэй"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Зөвхөн Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: дамжуулагдаагүй"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Алдаа мэдээлэх"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Гаргах харилцан үйлдэл"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Дэлгэцийн зураг дарах"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Алдааны тайлан авах"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Энэ таны төхөөрөмжийн одоогийн статусын талаарх мэдээллийг цуглуулах ба имэйл мессеж болгон илгээнэ. Алдааны мэдэгдлээс эхэлж илгээхэд бэлэн болоход хэсэг хугацаа зарцуулагдана тэвчээртэй байна уу."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактив тайлан"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Үүнийг ихэнх тохиолдолд ашиглана уу. Энэ нь танд тайлангийн явцыг хянах, асуудлын талаар дэлгэрэнгүй мэдээлэл оруулах болон дэлгэцийн агшин авахыг зөвшөөрнө. Мөн тайлагнахад урт хугацаа шаарддаг таны бага ашигладаг зарим хэсгийг алгасах болно."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Байршил"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"энэ төхөөрөмжийн байршилд хандалт хийх"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-д энэ төхөөрөмжийн байршилд хандахыг зөвшөөрөх үү?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Та аппыг зөвхөн хэрэглэж байгаа үед апп нь байршилд хандах болно."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-д энэ төхөөрөмжийн байршилд хандахыг байнга зөвшөөрөх үү?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Та энэ аппыг хэрэглээгүй байсан ч апп нь байршилд үргэлж хандах болно."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Хуанли"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"Хуанли руу хандах"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-д таны календарьт хандахыг зөвшөөрөх үү?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-д таны хөгжимд хандахыг зөвшөөрөх үү?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Зураг &amp; видео"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"зураг &amp; видеондоо хандах"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-д таны зураг, видео болон шошголсон байршилд хандахыг зөвшөөрөх үү?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Цонхны агуулгыг авах"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Таны харилцан үйлчлэх цонхны контентоос шалгах."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Хүрч танихыг асаах"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Апп нь Ойролцоо Талбарын Холболт(NFC) таг, карт, болон уншигчтай холбогдох боломжтой."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"дэлгэцний түгжээг идэвхгүй болгох"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Апп нь түгжээ болон бусад холбоотой нууц үгийн аюулгүй байдлыг идэвхгүй болгох боломжтой. Жишээ нь бол утас нь дуудлага ирэх үед түгжээг идэвхгүй болгох ба дуудлага дуусахад буцаан идэвхтэй болгодог."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"дэлгэцийн түгжээний төвөгтэй байдлын хүсэлт тавих"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Аппад дэлгэцийн түгжээний боломжтой уртын хэмжээ болон төрлийг заадаг дэлгэцийн түгжээний төвөгтэй байдлын түвшнийг (өндөр, дундаж, бага эсвэл байхгүй) мэдэж авахыг зөвшөөрдөг. Түүнчлэн, апп хэрэглэгчдэд дэлгэцийн түгжээг тодорхой түвшинд шинэчлэхийг санал болгодог хэдий ч хэрэглэгч үүнийг чөлөөтэй үл хэрэгсэж, орхих боломжтой. Дэлгэцийн түгжээг ил бичвэрээр хадгалдаггүй тул апп тодорхой нууц үгийг мэддэггүй болохыг анхаарна уу."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"биометрийн техник хангамжийг ашиглах"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Aппад биометрийн техник хангамжийг баталгаажуулалтад ашиглахыг зөвшөөрдөг"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"хурууны хээний програм хангамжийг удирдах"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Аппад царайны загварыг ашиглахын тулд нэмэх эсвэл устгах аргыг идэвхжүүлэхийг зөвшөөрдөг."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"царай танилтын техник хангамжийг ашиглах"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Аппад царай танилтын техник хангамжийг баталгаажуулалтад ашиглахыг зөвшөөрдөг"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Царайг таньж чадсангүй. Дахин оролдоно уу."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Царай хэт цайвар байна. Гэрэл багатай газар оролдож үзнэ үү."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Царай хэт бараан байна. Гэрэлтэй газар туршиж үзнэ үү."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Мэдрэгчийг царайнаас холдуулна уу."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Mэдрэгчийг царайтай ойртуулна уу."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Мэдрэгчийг дээшлүүлнэ үү."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Mэдрэгчийг доошлуулна уу."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Мэдрэгчийг баруун тийш болгоно уу."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Мэдрэгчийг зүүн тийш болгоно уу."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Мэдрэгч рүү харна уу."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Царай олдсонгүй."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Хэт их хөдөлгөөнтэй байна."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Нүүрээ дахин бүртгүүлнэ үү."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Өөр нүүр илрүүллээ."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Хэт адилхан байгаа тул байрлалаа өөрчилнө үү."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Камер луу аль болох эгц харна уу."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Камер луу аль болох эгц харна уу."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Толгойгоо босоо чиглэлд тэгшилнэ үү."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Нүүрээ ил гаргана уу."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Царайны техник хангамж боломжгүй байна."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Царай таниулах хугацаа дууслаа. Дахин оролдоно уу."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Царайг хадгалах боломжгүй байна."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Царайны үйл ажиллагааг цуцаллаа."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Хэрэглэгч царайгаар баталгаажуулахыг цуцалсан байна."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Хэт олон удаа оролдлоо. Дараа дахин оролдоно уу."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Хэт олон удаа оролдлоо. Царай танилтыг идэвхгүй болголоо."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Дахин оролдоно уу."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Бүртгүүлсэн царай алга."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Энэ төхөөрөмжид нүүр баталгаажуулах мэдрэгч алга."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Царай <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g>-г нээх"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g>-г хадгалахгүйгээр хаана"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> санах ойн хязгаараас давсан"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Багтаамж хэтэрсэн байна. Хуваалцахын тулд товшино уу."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Хэт их хуримтлагдсан мэдээллийг хуваалцах уу?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Энэ үйл явц <xliff:g id="PROC">%1$s</xliff:g> нь үйл ажиллагааны санах ойн хязгаар болох <xliff:g id="SIZE">%2$s</xliff:g> хэмжээг давсан байна. Та хэт их хуримтлагдсан мэдээллийг тэдгээрийн өөрсдийнх нь хөгжүүлэгчтэй хуваалцах боломжтой. Болгоомжтой байгаарай: энэхүү хэт их хуримтлагдсан мэдээлэлд аппликейшнаас нэвтрэх боломжтой таны хувийн мэдээлэл агуулагдсан байж болно."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Текст илгээх үйлдлийг сонгох"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Хонхны аяны хэмжээ"</string>
     <string name="volume_music" msgid="5421651157138628171">"Медиа дууны түвшин"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бүх сүлжээг харахын тулд товшино уу"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Холбогдох"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Бүх сүлжээ"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g>-н санал болгож буй Wi-Fi сүлжээ боломжтой байна"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Та <xliff:g id="NAME">%s</xliff:g>-н санал болгож буй сүлжээнд холбогдох уу?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Тийм"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Үгүй"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi автоматаар асна"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Сүлжээнд нэвтэрнэ үү"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi-д интернет хандалт алга"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Сонголт хийхийн тулд товшино уу"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Холбогдсон"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Таны сүлжээний цэгийн тохиргооны өөрчлөлт"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Таны сүлжээний цэгийн зурвасыг өөрчилсөн."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Энэ төхөөрөмж таны \"зөвхөн 5Гц\" гэсэн давуу сонголтыг дэмждэггүй. Үүний оронд энэ төхөөрөмж 5Гц зурвасыг боломжтой үед нь ашиглах болно."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB дебаг хийхийг унтраахын тулд товшино уу"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB дебаг хийхийг идэвхгүй болгох бол сонгоно уу."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB порт дээрх шингэн зүйл эсвэл бохирдол"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портыг автоматаар идэвхгүй болгосон байна. Дэлгэрэнгүй мэдээлэл авахын тулд товшино уу."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB портыг ашиглахад аюулгүй байна"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Ажлын профайлын түгжээг тайлахын тулд дарна уу"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-д холбогдсон"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Файлыг үзэхийн тулд дарна уу"</string>
-    <string name="pin_target" msgid="3052256031352291362">"PIN"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"Апп-н мэдээлэл"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Жишээг эхлүүлж байна…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Хэвшлийн горимын мэдээллийн мэдэгдэл"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Батарей ихэвчлэн цэнэглэдэг хугацаанаас өмнө дуусаж болзошгүй"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Батарейны ажиллах хугацааг уртасгахын тулд Батарей хэмнэгчийг идэвхжүүллээ"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Фолдер"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Андройд апп"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Файл"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 98b64e9..61739ef7 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Panggilan Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Mati"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi diutamakan"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mudah alih diutamakan"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi sahaja"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Tidak dimajukan"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Laporan pepijat"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Tamatkan sesi"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Tangkapan skrin"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan pepijat"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpul maklumat tentang keadaan peranti semasa anda untuk dihantarkan sebagai mesej e-mel. Harap bersabar, mungkin perlu sedikit masa untuk memulakan laporan sehingga siap untuk dihantar."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Laporan interaktif"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Gunakan laporan ini dalam kebanyakan keadaan. Anda boleh menjejak kemajuan laporan, memasukkan butiran lanjut tentang masalah tersebut dan mengambil tangkapan skrin. Laporan ini mungkin meninggalkan beberapa bahagian yang kurang digunakan, yang mengambil masa lama untuk dilaporkan."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokasi"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"mengakses lokasi peranti ini"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses lokasi peranti ini?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Apl ini hanya dapat mengakses lokasi semasa anda menggunakan apl tersebut."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Sentiasa benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses lokasi peranti ini?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Apl ini akan dapat mengakses lokasi pada sepanjang masa, meskipun apabila anda tidak menggunakan apl tersebut."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"mengakses kalendar"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses kalendar anda?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses muzik anda?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Foto &amp; video"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"akses foto &amp; video anda"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mengakses foto dan video anda, termasuk lokasi yang ditandai?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Dapatkan kembali kandungan tetingkap"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Periksa kandungan tetingkap yang berinteraksi dengan anda."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Hidupkan Jelajah melalui Sentuhan"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Membenarkan apl berkomunikasi dengan teg, kad dan pembaca Komunikasi Medan Dekat (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"lumpuhkan kunci skrin anda"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Membenarkan apl melumpuhkan kunci kekunci dan sebarang keselamatan kata laluan yang berkaitan. Sebagai contoh, telefon melumpuhkan kunci kekunci apabila menerima panggilan telefon masuk kemudian mendayakan semula kunci kekunci apabila panggilan selesai."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"minta kerumitan kunci skrin"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Membenarkan apl mengetahui tahap kerumitan kunci skrin (tinggi, sederhana, rendah atau tiada) yang menunjukkan julat panjang dan jenis kunci skrin yang berkemungkinan. Apl juga boleh mencadangkan kepada pengguna supaya mengemas kini kunci skrin pada tahap tertentu namun pengguna boleh mengabaikan dan menavigasi keluar dengan bebas. Sila ambil perhatian bahawa kunci skrin tidak disimpan dalam teks biasa, maka apl tidak mengetahui kata laluan yang tepat."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"gunakan perkakasan biometrik"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Membenarkan apl menggunakan perkakasan biometrik untuk pengesahan"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"urus perkakasan cap jari"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Membenarkan apl menggunakan kaedah untuk menambahkan dan memadamkan templat wajah untuk digunakan."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"gunakan perkakasan pengesahan wajah"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Membenarkan apl menggunakan perkakasan pengesahan wajah untuk pengesahan"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Tidak dapat memproses wajah. Sila cuba lagi."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Wajah terlalu cerah. Cuba dlm cahaya lebih rendah."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Wajah terlalu gelap. Sila buka sumber cahaya."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Sila alihkan penderia lebih jauh dari wajah."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Sila dekatkan penderia ke wajah."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Sila alihkan penderia ke kedudukan lebih tinggi."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Sila alihkan penderia ke kedudukan lebih rendah."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Sila alihkan penderia ke kanan."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Sila alihkan penderia ke kiri."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Sila lihat penderia."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Tiada wajah dikesan."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Terlalu banyak gerakan."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Sila daftarkan semula wajah anda."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Wajah yang berbeza dikesan."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Terlalu serupa, sila ubah lagak gaya anda."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Sila lihat terus pada kamera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Sila lihat terus pada kamera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Sila tegakkan kepala anda."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Sila dedahkan wajah anda."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Perkakasan wajah tidak tersedia."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Tamat masa wajah dicapai. Cuba lagi."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Wajah tidak dapat disimpan."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Pengendalian wajah dibatalkan."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Pengesahan wajah dibatalkan oleh pengguna."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Terlalu banyak percubaan. Cuba sebentar lagi."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Terlalu banyak percubaan. Pengesahan wajah dilumpuhkan."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Cuba lagi."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Tiada wajah didaftarkan."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Peranti ini tiada penderia pengesahan wajah."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Wajah <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Buka <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> akan ditutup tanpa menyimpan"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> melebihi had memori"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Longgokan timbunan dikumpulkan. Ketik untuk berkongsi."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Kongsikan longgokan timbunan?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Proses <xliff:g id="PROC">%1$s</xliff:g> telah melebihi had memori proses sebanyak <xliff:g id="SIZE">%2$s</xliff:g>. Longgokan timbunan tersedia untuk anda kongsikan dengan pembangun aplikasi. Sila berhati-hati: longgokan timbunan ini boleh mengandungi sebarang maklumat peribadi anda yang boleh diakses oleh aplikasi itu."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Pilih tindakan untuk teks"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Kelantangan pendering"</string>
     <string name="volume_music" msgid="5421651157138628171">"Kelantangan media"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketik untuk melihat semua rangkaian"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Sambung"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Semua rangkaian"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Rangkaian Wi‑Fi yang dicadangkan oleh <xliff:g id="NAME">%s</xliff:g> tersedia"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Adakah anda mahu menyambung ke rangkaian yang dicadangkan oleh <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ya"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Tidak"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi akan dihidupkan secara automatik"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Log masuk ke rangkaian"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi tiada akses Internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Ketik untuk mendapatkan pilihan"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Disambungkan"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Perubahan kepada tetapan tempat liputan anda"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Jalur tempat liputan anda telah berubah."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Peranti ini tidak menyokong pilihan anda untuk 5GHz sahaja. Sebaliknya, peranti ini akan menggunakan jalur 5GHz apabila tersedia."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Ketik untuk mematikan penyahpepijatan USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk melumpuhkan penyahpepijatan USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Cecair atau serpihan dalam port USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB dilumpuhkan secara automatik. Ketik untuk mengetahui lebih lanjut."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Selamat untuk menggunakan port USB"</string>
@@ -1396,8 +1447,7 @@
     <string name="ext_media_init_action" msgid="7952885510091978278">"Sediakan"</string>
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"Tanggalkan"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"Teroka"</string>
-    <!-- no translation found for ext_media_seamless_action (6575980560886881233) -->
-    <skip />
+    <string name="ext_media_seamless_action" msgid="6575980560886881233">"Tukar output"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> tiada"</string>
     <string name="ext_media_missing_message" msgid="4012389235250987930">"Masukkan peranti sekali lagi"</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Mengalihkan <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1906,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Ketik utk membuka profil kerja"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Disambungkan ke <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Ketik untuk melihat fail"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Semat"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Nyahsemat"</string>
     <string name="app_info" msgid="6856026610594615344">"Maklumat apl"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Memulakan tunjuk cara…"</string>
@@ -1998,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Pemberitahuan maklumat Mod Rutin"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Bateri mungkin habis sebelum pengecasan biasa"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Penjimat Bateri diaktifkan untuk memanjangkan hayat bateri"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folder"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplikasi Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fail"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 09e963f..c45cf05 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WiFi ခေါ်ဆိုမှု"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ပိတ်ထားရသည်"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ဝိုင်ဖိုင်အား ပိုနှစ်သက်သော"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"မိုဘိုင်းကို အသုံးပြုလိုပါသည်"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"ကြိုးမဲ့အင်တာနက် သာလျှင်"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ထပ်ဆင့်မပို့နိုင်ပါ"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်း"</string>
     <string name="global_action_logout" msgid="935179188218826050">"သတ်မှတ်ပေးထားသည့်အချိန် ပြီးဆုံးပြီ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"ချွတ်ယွင်းမှုမှတ်တမ်း ယူခြင်း"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"သင့်ရဲ့ လက်ရှိ စက်အခြေအနေ အချက်အလက်များကို အီးမေးလ် အနေဖြင့် ပေးပို့ရန် စုဆောင်းပါမည်။ အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းမှ ပေးပို့ရန် အသင့်ဖြစ်သည်အထိ အချိန် အနည်းငယ်ကြာမြင့်မှာ ဖြစ်သဖြင့် သည်းခံပြီး စောင့်ပါရန်"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"လက်ငင်းတုံ့ပြန်နိုင်သည့် အစီရင်ခံချက်"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"အခြေအနေတော်တော်များများတွင် ၎င်းကိုအသုံးပြုပါ။ ၎င်းသည် အစီရင်ခံစာကို မှတ်သားခြင်း၊ ပြဿနာအကြောင်း နောက်ထပ်အသေးစိတ်များကို ထည့်သွင်းခြင်းနှင့် မျက်နှာပြင်ပုံဖမ်းယူခြင်းတို့ကို ပြုလုပ်ခွင့်ပေးပါသည်။ ပေးပို့ရန် အလွန်ကြာပြီး အသုံးပြုခြင်းနည်းပါးသည့်အပိုင်းကို ၎င်းက ချန်ခဲ့နိုင်ပါသည်။"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"တည်နေရာ"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"ဤစက်ပစ္စည်း၏ တည်နေရာကို ရယူရန်"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား ဤစက်ပစ္စည်း၏တည်နေရာကို သုံးခွင့်ပေးလိုပါသလား။"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"အက်ပ်ကိုအသုံးပြုသည့် အချိန်တွင်သာ ၎င်းကတည်နေရာကို အသုံးပြုခွင့်ရပါမည်။"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား ဤစက်ပစ္စည်း၏တည်နေရာကို အမြဲ အသုံးပြုခွင့်ပေးလိုပါသလား။"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"သင် အက်ပ်ကိုအသုံးပြုမနေသော်လည်း ၎င်းကတည်နေရာကို အမြဲ အသုံးပြုခွင့်ရနေပါမည်။"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ပြက္ခဒိန်"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင်၏ပြက္ခဒိန်ကို သုံးခွင့်ပေးလိုပါသလား။"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင့်တေးဂီတကို ဝင်ခွင့်ပေးလိုပါသလား။"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ဓာတ်ပုံများနှင့် ဗီဒီယိုများ"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"သင့်ဓာတ်ပုံနှင့် ဗီဒီယိုများသို့ ဝင်သည်"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"တဂ်လုပ်ထားသည့် တည်နေရာများအပါအဝင် သင့်ဓာတ်ပုံနှင့် ဗီဒီယိုများကို &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား ဝင်ကြည့်ခွင့်ပေးလိုပါသလား။"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ဝင်းဒိုးတွင် ပါရှိသည်များကို ပြန်လည်ရယူရန်"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"သင်အသုံးပြုနေသော ဝင်းဒိုးတွင် ပါရှိသည်များကို ကြည့်ရှုစစ်ဆေးသည်။"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"တို့ထိခြင်းဖြင့် ရှာဖွေမှုကို ဖွင့်ရန်"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"အက်ပ်အား တာတို စက်ကွင်း ဆက်သွယ်ရေး (NFC) တဲဂ်များ၊ ကဒ်များ နှင့် ဖတ်ကြသူတို့နှင့် ဆက်သွယ်ပြောဆိုခွင့် ပြုသည်။"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ဖန်သားပြင် သော့ချခြင်းအား မလုပ်နိုင်အောင် ပိတ်ရန်"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"အပလီကေးရှင်းအား သော့ချခြင်းနှင့် သက်ဆိုင်ရာ စကားဝှက်သတ်မှတ်ခြင်းများအား မသုံးနိုင်အောင် ပိတ်ခြင်းကို ခွင့်ပြုရန်။ ဥပမာ ဖုန်းလာလျှင် သော့ပိတ်ခြင်း ပယ်ဖျက်ခြင်း၊ ဖုန်းပြောပြီးလျှင် သော့ကို အလိုအလျောက် ပြန်ပိတ်ခြင်း"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ဖုန်းမျက်နှာပြင် လော့ခ်ချရန် ရှုပ်ထွေးမှုအဆင့် တောင်းခံခြင်း"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"ဖုန်းမျက်နှာပြင်လော့ခ်၏ ရှုပ်ထွေးမှုအဆင့် (မြင့်၊ အလယ်အလတ်၊ နိမ့် သို့မဟုတ် မရှိ) အား လေ့လာရန် အက်ပ်ကို ခွင့်ပြုသည်။ ၎င်းက သတ်မှတ်ထားနိုင်သော ဖုန်းမျက်နှာပြင်လော့ခ်၏ စာလုံးရေနှင့် အမျိုးအစားကို ညွှန်ပြပေးသည်။ အသုံးပြုသူများအနေနှင့် ဖုန်းမျက်နှာပြင်လော့ခ်ကို အတိုင်းအတာတစ်ခုအထိ အဆင့်မြှင့်ရန် အက်ပ်က အကြံပြုနိုင်သည်။ သို့သော်လည်း အသုံးပြုသူများက ၎င်းကို ဂရုပြုမနေဘဲ လွတ်လပ်စွာ ကြည့်ရှုနိုင်ပါသည်။ ဖုန်းမျက်နှာပြင်လော့ခ်ကို စာသားအတိုင်း သိမ်းမထားသဖြင့် အက်ပ်သည် စကားဝှက်အစစ်ကို မသိနိုင်ကြောင်း သတိပြုပါ။"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ဇီဝဗေဒဆိုင်ရာ အချက်အလက်သုံး ကွန်ပျူတာဆိုင်ရာ စက်ပစ္စည်းကို အသုံးပြုရန်"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"အထောက်အထားစိစစ်ခြင်းအတွက် ဇီဝဗေဒဆိုင်ရာ သတင်းအချက်အလက်များသုံးသည့် ကွန်ပျူတာဆိုင်ရာ စက်ပစ္စည်းကို အသုံးပြုရန် အက်ပ်ကို ခွင့်ပြုသည်"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"လက်ဗွေရာပစ္စည်းကို စီမံမည်"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"အသုံးပြုရန်အတွက် မျက်နှာပုံစံထည့်ရန် (သို့) ဖျက်ရန်နည်းလမ်းကို အက်ပ်အား သုံးခွင့်ပြုသည်။"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"မျက်နှာအထောက်အထားစိစစ်ခြင်း စက်ပစ္စည်းကို သုံးပါ"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"အထောက်အထားစိစစ်ရန်အတွက် ဤအက်ပ်အား မျက်နှာအထောက်အထားစိစစ်ခြင်း စက်ပစ္စည်းကိုသုံးခွင့်ပြုသည်"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"မျက်နှာကို မမှတ်မိပါ။ ထပ်လုပ်ကြည့်ပါ။"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"မျက်နှာအလွန်လင်းနေသည်။ အလင်းလျှော့ပြီး စမ်းကြည့်ပါ။"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"မျက်နှာအလွန်မှောင်နေသည်။ ပြတင်းပေါက်ဖွင့်လိုက်ပါ။"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"အာရုံခံကိရိယာကို မျက်နှာနှင့် ခွာလိုက်ပါ။"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"အာရုံခံကိရိယာကို မျက်နှာအနီး ရွှေ့လိုက်ပါ။"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"အာရုံခံကိရိယာကို ပိုမြင့်အောင်ထားပါ။"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"အာရုံခံကိရိယာကို ပိုနိမ့်အောင်ထားပါ။"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"အာရုံခံကိရိယာကို ညာဘက်သို့ ရွှေ့ပါ။"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"အာရုံခံကိရိယာကို ဘယ်ဘက်သို့ ရွှေ့ပါ။"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"အာရုံခံကိရိယာကို ကြည့်ပါ။"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"မျက်နှာတစ်ခုမျှ မတွေ့ပါ။"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"လှုပ်ရှားမှု အလွန်များနေသည်။"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"သင့်မျက်နှာကို ပြန်စာရင်းသွင်းပါ။"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"မတူသည့် မျက်နှာ တွေ့ရှိထားသည်။"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ဆင်တူနေသည်၊ အမူအရာ ပြောင်းပါ။"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"ကင်မရာကို တည့်တည့်ကြည့်ပါ။"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"ကင်မရာကို တည့်တည့်ကြည့်ပါ။"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"ခေါင်းမတ်မတ်ထားပါ။"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"မျက်နှာ ဖော်ထားပါ။"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"မျက်နှာ စက်ပစ္စည်း မရနိုင်ပါ။"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"မျက်နှာ သက်တမ်းကုန်သွားပါပြီ။ ထပ်စမ်းကြည့်ပါ။"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"မျက်နှာကို သိမ်း၍မရပါ။"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"မျက်နှာ ဆောင်ရွက်ခြင်းကို ပယ်ဖျက်လိုက်ပါပြီ။"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"အသုံးပြုသူက မျက်နှာအထောက်အထားစိစစ်မှု မလုပ်တော့ပါ။"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"အကြိမ်များစွာ စမ်းပြီးပါပြီ။ နောက်မှထပ်စမ်းပါ။"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"အကြိမ်များစွာ စမ်းပြီးပါပြီ။ ပိတ်လိုက်ပါပြီ။"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"ထပ်စမ်းကြည့်ပါ။"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"စာရင်းသွင်းထားသည့် မျက်နှာတစ်ခုမျှ မရှိပါ။"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"ဤစက်တွင် မျက်နှာအထောက်အထားစိစစ်ခြင်း အာရုံခံကိရိယာမရှိပါ။"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"မျက်နှာ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> ကို ဖွင့်ရန်"</string>
     <string name="new_app_description" msgid="5894852887817332322">"မသိမ်းဘဲ <xliff:g id="OLD_APP">%1$s</xliff:g> ကို ပိတ်လိုက်ပါမည်"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> သိမ်းထားနိုင်မှု အကန့်အသတ် ကျော်လွန်နေ"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"သိမ်းဆည်းနိုင်မှု ပမာဏကျော်လွန်သွားပါပြီ။ မျှဝေရန် တို့ပါ။"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"အရေးပေါ် သိမ်းထားပေးမှု ကို မျှဝေမလား။"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> လုပ်ဆောင်နိုင်မှုသည် <xliff:g id="SIZE">%2$s</xliff:g>ရှိသည့် သိမ်းထားနိုင်မှု ပမာဏထက်ကျော်လွန်သွားသည်။ စက်လုပ်ဆောင်ရည်မြင့်တင်ပေးသူနှင့် မျှဝေမှုလုပ်ရန်  အရေးပေါ်သိမ်းထားပေးမှု ရမည်။"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"စာတိုအတွက် လုပ်ဆောင်ချက် ရေးပါ"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"ဖုန်းမြည်သံအတိုးအကျယ်"</string>
     <string name="volume_music" msgid="5421651157138628171">"မီဒီယာအသံအတိုးအကျယ်"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ကွန်ရက်အားလုံးကို ကြည့်ရန် တို့ပါ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"ချိတ်ဆက်ရန်"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ကွန်ရက်အားလုံး"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> အကြံပြုထားသော Wi‑Fi ကွန်ရက်ကို ရရှိနိုင်ပါသည်"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> အဆိုပြုထားသော ကွန်ရက်များသို့ ချိတ်ဆက်လိုပါသလား။"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ကို အလိုအလျောက်​ ပြန်ဖွင့်ပေးလိမ့်ပါမည်"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi တွင် အင်တာနက်ချိတ်ဆက်မှု မရှိပါ"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"အခြားရွေးချယ်စရာများကိုကြည့်ရန် တို့ပါ"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"ချိတ်ဆက်ထားသည်"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"သင်၏ဟော့စပေါ့ ဆက်တင်များ ပြောင်းလဲမှု"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"သင်၏ ဟော့စပေါ့လိုင်း ပြောင်းသွားပါပြီ။"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"ဤစက်ပစ္စည်းသည် သင်၏ 5GHz သီးသန့်ရွေးချယ်မှုအတွက် ပံ့ပိုးမထားပါ။ ၎င်းအစား ဤစက်ပစ္စည်းသည် ရနိုင်သည့်အခါ 5GHz လိုင်းကို သုံးသွားပါမည်။"</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားရှာပြင်စနစ် ချိတ်ဆက်ထားသည်"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB အမှားရှာပြင်ခြင်းကို ပိတ်ရန် တို့ပါ"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ဖြင့် အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ပို့တ်တွင် အရည် သို့မဟုတ် အမှိုက်စ ရှိနေသည်"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ပို့တ်ကို အလိုအလျောက် ပိတ်ထားသည်။ ပိုမိုလေ့လာရန် တို့ပါ။"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB ပို့တ်ကို စိတ်ချစွာ သုံးနိုင်ပါပြီ"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"သင့်အလုပ်ပရိုဖိုင်ကို သော့ဖွင့်ရန် တို့ပါ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ချိတ်ဆက်ထားသည်"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ဖိုင်များကိုကြည့်ရန် တို့ပါ"</string>
-    <string name="pin_target" msgid="3052256031352291362">"တွဲပါ"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"ဖြုတ်ပါ"</string>
     <string name="app_info" msgid="6856026610594615344">"အက်ပ်အချက်အလက်"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"သရုပ်ပြချက်ကို စတင်နေသည်…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"ပုံမှန်မုဒ်အတွက် အချက်အလက်ပြသည့် အကြောင်းကြားချက်"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ပုံမှန်အားသွင်းမှုမပြုလုပ်မီ ဘက်ထရီကုန်သွားနိုင်သည်"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"ဘက်ထရီသက်တမ်းကို တိုးမြှင့်ရန် \'ဘက်ထရီအားထိန်း\' စတင်ပြီးပါပြီ"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ဖိုင်တွဲ"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android အပလီကေးရှင်း"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ဖိုင်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 1aced28..02efec6 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi-anrop"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Av"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi er foretrukket"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Først-på-mobil"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Bare Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Ikke viderekoblet"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Feilrapport"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Avslutt økten"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skjermdump"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Utfør feilrapport"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Informasjon om tilstanden til enheten din samles inn og sendes som en e-post. Det tar litt tid fra du starter feilrapporten til e-posten er klar, så vær tålmodig."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv rapport"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Bruk dette alternativet i de fleste tilfeller. Da kan du spore fremgangen for rapporten, skrive inn flere detaljer om problemet samt ta skjermdumper. Noen deler som tar lang tid å behandle, blir kanskje utelatt."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Posisjon"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"få tilgang til enhetens plassering"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til denne enhetens posisjon?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Appen får bare tilgang til posisjonen når du bruker appen."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Vil du alltid gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til denne enhetens posisjon?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Appen får alltid tilgang til posisjonen, selv når du ikke bruker appen."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"åpne kalenderen din"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til kalenderen din?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til musikken din?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Bilder og videoer"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"få tilgang til bildene og videoene dine"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilgang til bildene og videoene dine, inkludert merkede steder?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"hente innhold i vinduer"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Appen analyserer innholdet i vinduer du samhandler med."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"slå på berøringsutforsking"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Lar appen kommunisere med etiketter, kort og lesere som benytter NFC-teknologi."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivere skjermlåsen"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Lar appen deaktivere tastelåsen og eventuell tilknyttet passordsikkerhet. Et eksempel er at telefonen deaktiverer tastelåsen når du mottar et innkommende anrop, og deretter aktiverer tastelåsen igjen når samtalen er ferdig."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"be om skjermlåsens kompleksitet"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Lar appen lære skjermlåsens kompleksitetsnivå (høy, middels, lav eller ingen), som indikerer det mulige området for lengde og type skjermlås. Appen kan foreslå at brukeren oppdaterer skjermlåsen til et bestemt nivå, men brukere kan velge å ignorere dette og navigere bort. Vær oppmerksom på at skjermlåsen ikke er lagret i klartekst, så appen kan ikke se det nøyaktige passordet."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"bruke biometrisk maskinvare"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Lar appen bruke biometrisk maskinvare til godkjenning"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"administrere fingeravtrykkmaskinvare"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Lar appen bruke metoder for å legge til og slette ansiktmaler for bruk."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"bruke maskinvare for ansiktsautentisering"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Lar appen bruke maskinvare for ansiktsautentisering til autentisering"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Kunne ikke behandle ansiktet. Prøv igjen."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Ansiktet er for lyst. Prøv med svakere lys."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Ansiktet er for mørkt. Bruk en lyskilde."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Flytt sensoren lengre vekk fra ansiktet."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Hold sensoren nærmere ansiktet."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Flytt sensoren opp."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Flytt sensoren ned."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Flytt sensoren til høyre."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Flytt sensoren til venstre."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Se på sensoren."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Ingen ansikter er oppdaget."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"For mye bevegelse."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registrer ansiktet ditt på nytt."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Et annet ansikt er gjenkjent."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"For likt – endre posituren din."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Se mer direkte mot kameraet."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Se mer direkte mot kameraet."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Rett hodet ditt vertikalt."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Ikke skjul ansiktet ditt."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Maskinvare for ansikt er ikke tilgjengelig."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Tidsavbrudd for ansikt er nådd. Prøv igjen."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Ansiktet kan ikke lagres."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Ansikt-operasjonen ble avbrutt."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Ansiktsautentiseringen ble avbrutt av brukeren."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"For mange forsøk. Prøv igjen senere."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"For mange forsøk. Ansiktsautentisering er slått av."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Prøv igjen."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Ingen ansikt er registrert."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Denne enheten har ikke sensor for ansiktsautentisering."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Ansikt <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Åpne <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> lukkes uten å lagre"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> er over minnegrensen"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Minnedumpen er samlet inn. Trykk for å dele."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vil du dele minnedumpen («heap dump»)?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g>-prosessen er <xliff:g id="SIZE">%2$s</xliff:g> over grensen for prosessminne. En minnedump («heap dump») er tilgjengelig for deling med utvikleren. Vær forsiktig – denne minnedumpen kan inneholde noen av de personlige opplysningene dine som appen har tilgang til."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Velg handling for tekst"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Ringetonevolum"</string>
     <string name="volume_music" msgid="5421651157138628171">"Medievolum"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trykk for å se alle nettverkene"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koble til"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle nettverk"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Et Wi‑Fi-nettverkt som ble foreslått av <xliff:g id="NAME">%s</xliff:g>, er tilgjengelig"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Vil du koble til nettverkene som foreslås av <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nei"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi slås på automatisk"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Logg på nettverk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi har ikke Internett-tilgang"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Trykk for å få alternativer"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Tilkoblet"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Endres til innstillingene dine for Wi-Fi-soner"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Båndet ditt for Wi-Fi-sone er endret."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Denne enheten støtter ikke innstillingen din for bare 5 GHz. I stedet bruker enheten 5 GHz-båndet når det er tilgjengelig."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Trykk for å slå av USB-feilsøking"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Væske eller rusk i USB-porten"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten deaktiveres automatisk. Trykk for å finne ut mer."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Trygt å bruke USB-porten"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Trykk for å låse opp jobbprofilen"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Koblet til <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Trykk for å se filer"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Fest"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Løsne"</string>
     <string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Starter demo …"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Varsel med informasjon om rutinemodus"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Batteriet kan gå tomt før den vanlige ladingen"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Batterisparing er aktivert for å forlenge batterilevetiden"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Mappe"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android-app"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fil"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 806e520..b51f4b541 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WiFi कलिङ"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"निष्क्रिय"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi मनपराइयो"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"रूचाइएको मोबाइल"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi मात्र"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अगाडि पठाइएको छैन"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"बग रिपोर्ट"</string>
     <string name="global_action_logout" msgid="935179188218826050">"सत्रको अन्त्य गर्नुहोस्"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"स्क्रिनसट"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"बग रिपोर्ट लिनुहोस्"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"एउटा इमेल सन्देशको रूपमा पठाउनलाई यसले तपाईँको हालैको उपकरणको अवस्थाको बारेमा सूचना जम्मा गर्ने छ। बग रिपोर्ट सुरु गरेदेखि पठाउन तयार नभएसम्म यसले केही समय लिन्छ; कृपया धैर्य गर्नुहोस्।"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"अन्तरक्रियामूलक रिपोर्ट"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"बढी भन्दा बढी परिस्थितिहरूमा यसको प्रयोग गर्नुहोस्। यसले तपाईँलाई रिपोर्टको प्रगति ट्र्याक गर्न, समस्याका बारे थप विवरणहरू प्रविष्ट गर्न र स्क्रिनसटहरू लिन अनुमति दिन्छ। यसले रिपोर्ट गर्न लामो समय लिने केही कम प्रयोग हुने खण्डहरूलाई समावेश नगर्न सक्छ।"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"यस यन्त्रको स्थानमाथि पहुँच"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई यो यन्त्रको स्थानमाथि पहुँच राख्न दिने हो?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"तपाईं उक्त अनुप्रयोग प्रयोग गरिरहेका बेलामा त्यससँग स्थानमाथिको पहुँच रहने छ।"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई यो यन्त्रको स्थानमाथि पहुँच राख्न दिने हो?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"तपाईं उक्त अनुप्रयोग प्रयोग नगरिरहेका बेलामा पनि त्यससँग स्थानमाथिको पहुँच रहने छ।"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"पात्रो"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"तपाईंको पात्रोमाथि पहुँच गर्नुहोस्"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई आफ्नो पात्रोमाथि पहुँच राख्न दिने हो?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई तपाईंको सङ्गीतमाथि पहुँच राख्न दिने हो?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"तस्बिर तथा भिडियोहरू"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"आफ्नो तस्बिर &amp; भिडियोहरूमाथि पहुँच राख्नुहोस्‌"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई ट्याग गरिएका स्थानहरूलगायत तपाईंका तस्बिर तथा भिडियोहरूमाथि पहुँच गर्न दिने हो?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विन्डो सामग्रीको पुनःबहाली गर्नुहोस्।"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"तपाईँको अन्तरक्रिया भइरहेको विन्डोको सामग्रीको निरीक्षण गर्नुहोस्।"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"छोएर गरिने खोजलाई सुचारु गर्नुहोस्"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"अनुप्रयोगलाई नयाँ क्षेत्र संचार (NFC) ट्यागहरू, कार्डहरू र पाठकहरूसँग अन्तर्क्रिया गर्न अनुमति दिन्छ।"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"स्क्रिन लक असक्षम पार्नुहोस्"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"कुनै सम्बन्धित पासवर्ड सुरक्षा र किलकलाई असक्षम पार्न अनुप्रयोगलाई अनुमति दिन्छ। उदाहरणको लागि, अन्तर्गमन फोन कल प्राप्त गर्दा फोनले किलकलाई असक्षम पार्छ, त्यसपछि कल सकिएको बेला किलक पुनःसक्षम पार्छ।"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"स्क्रिन लकको जटिलतासम्बन्धी जानकारी प्राप्त गर्ने अनुरोध गर्नुहोस्"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"यसले अनुप्रयोगलाई स्क्रिन लकको जटिलताको स्तर (उच्च, मध्यम, न्यून वा कुनै पनि होइन) थाहा पाउने अनुमति दिन्छ जसले स्क्रिन लकको लम्बाइको सम्भावित दायरा र त्यसको प्रकारलाई जनाउँछ। यसै गरी, यो अनुप्रयोगले प्रयोगकर्ताहरूलाई स्क्रिन लक अद्यावधिक गर्ने सुझाव पनि दिन सक्छ तर प्रयोगकर्ताहरू उक्त सुझावको बेवास्ता गरी बाहिर निस्कन सक्छन्। स्क्रिन लकलाई सादा पाठको ढाँचामा भण्डारण नगरिने हुँदा यो अनुप्रयोगले वास्तविक पासवर्ड थाहा पाउँदैन भन्ने कुरा याद राख्नुहोस्।"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"बायोमेट्रिक हार्डवेयर प्रयोग गर्नुहोस्‌"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"अनुप्रयोगलाई प्रमाणीकरणका लागि बायोमेट्रिक हार्डवेयर प्रयोग गर्न अनुमति दिन्छ"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"औठाछाप हार्डवेयर व्यवस्थापन गर्नुहोस्"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"अनुप्रयोगलाई प्रयोगका लागि अनुहार टेम्प्लेट थप्न र मेटाउने तरिका आह्वान गर्न अनुमति दिन्छ।"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"अनुहार प्रमाणिकरण हार्डवेयर प्रयोग गर्नुहोस्"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"अनुप्रयोगलाई प्रमाणीकरणका लागि अनुहार प्रमाणीकरण हार्डवेयर प्रयोग गर्न अनुमति दिन्छ"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"अनुहार प्रशोधन गर्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्।"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"अनुहारमा धेरै उज्यालो छ। कृपया कम प्रकाशमा प्रयास गर्नुहोस्।"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"अनुहार धेरै गाढा छ। कृपया प्रकाशको स्रोतको थप्नुहोस्‌।"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"कृपया अनुहारबाट सेन्सरलाई अलिक टाढा सार्नुहोस्।"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"कृपया अनुहारलाई सेन्सरको नजिक ल्याउनुहोस्।"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"कृपया सेन्सरलाई माथि सार्नुहोस्।"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"कृपया सेन्सरलाई तल सार्नुहोस्।"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"कृपया सेन्सरलाई दायाँतिर सार्नुहोस्।"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"कृपया सेन्सरलाई बायाँतिर सार्नुहोस्।"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"कृपया सेन्सरमा हेर्नुहोस्।"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"अनुहार पत्ता लागेन।"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"अत्यधिक हल्लियो।"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"कृपया आफ्नो अनुहार पुनः दर्ता गर्नुहोस्।"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"अर्कै अनुहार पत्ता लाग्यो।"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"अनुहार उस्तै भयो, कृपया आफ्नो पोज बदल्नुहोस्।"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"कृपया आफ्नो अनुहार अझ सीधा पारेर क्यामेरामा हेर्नु"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"कृपया आफ्नो अनुहार अझ सीधा पारेर क्यामेरामा हेर्नु"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"कृपया आफ्नो अनुहार ठाडो रूपमा सीधा पार्नुहोस्।"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"कृपया आफ्नो अनुहार नढाक्नुहोस्।"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"अनुहार पहिचान गर्ने हार्डवेयर उपलब्ध छैन।"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"अनुहारको समय सकिएको छ। फेरि प्रयास गर्नुहोस्‌।"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"अनुहार भण्डारण गर्न सकिँदैन।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"अनुहार पहिचान रद्द गरियो।"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"प्रयोगकर्ताले अनुहार प्रमाणीकरण रद्द गर्नु भयो।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"धेरैपटक प्रयासहरू भए। पछि फेरि प्रयास गर्नुहोस्‌।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"अत्यधिक धेरैपटक गलत प्रयासहरू भए। अनुहार प्रमाणिकरणलाई असक्षम पारियो।"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"फेरि प्रयास गर्नुहोस्।"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"कुनै पनि अनुहार दर्ता गरिएन।"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"यो यन्त्रमा अनुहार प्रमाणीकरण गर्ने कुनै पनि सेन्सर छैन।"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"अनुहार <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1219,9 +1252,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> खोल्नुहोस्"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> सुरक्षित नगरिकनै बन्द हुने छ"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ले मेमोरी सीमा नाघ्यो"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"हिप डम्प सङ्‍कलन गरियो, ट्याप गरेर आदान प्रदान गर्नुहोस्।"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"हिप डम्प साझेदारी गर्नुहुन्छ?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"प्रक्रिया <xliff:g id="PROC">%1$s</xliff:g>ले यसको प्रक्रिया मेमोरी सीमा <xliff:g id="SIZE">%2$s</xliff:g> नाघेको छ। तपाईँको लागि विकासकर्तासँग साझेदारी गर्न एउटा हिप डम्प उपलब्ध छ। होसियार हुनुहोस्: यो हिप डम्पमा अनुप्रयोगको पहुँच भएको तपाईँको कुनै पनि व्यक्तिगत जानकारी हुन सक्छ।"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"पाठको लागि एउटा प्रकार्य छान्नुहोस्"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"बजाउने मात्रा"</string>
     <string name="volume_music" msgid="5421651157138628171">"मिडियाको आवाजको मात्रा"</string>
@@ -1260,8 +1300,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सबै नेटवर्कहरू हेर्न ट्याप गर्नुहोस्"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"जडान गर्नुहोस्"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"सबै नेटवर्कहरू"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> ले प्रस्ताव गरेको Wi‑Fi नेटवर्क उपलब्ध छ"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"तपाईं <xliff:g id="NAME">%s</xliff:g> ले प्रस्ताव गरेका नेटवर्कहरूमा जोडिन चाहनुहुन्छ?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"हो"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"होइन"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi स्वतः सक्रिय हुनेछ"</string>
@@ -1273,9 +1315,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"सञ्जालमा साइन इन गर्नुहोस्"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi मार्फत इन्टरनेटमाथि पहुँच राख्न सकिँदैन"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"विकल्पहरूका लागि ट्याप गर्नुहोस्"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"जोडियो"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"तपाईंको हटस्पट सेटिङहरूमा परिवर्तन हुन्छ"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"तपाईंको हटस्पट ब्यान्ड परिवर्तन भएको छ।"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"यो यन्त्रले तपाईंको 5GHz मात्रको प्राथमिकतालाई समर्थन गर्दैन। बरु, उपलब्ध भएको खण्डमा यो यन्त्रले 5GHz ब्यान्ड प्रयोग गर्छ।"</string>
@@ -1360,6 +1407,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने सुविधा सुचारू छ"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB डिबग प्रक्रिया निष्क्रिय पार्न ट्याप गर्नुहोस्‌"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङलाई असक्षम पार्न ट्याप गर्नुहोस्।"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्टमा तरल पदार्थ वा धुलो भएको कुरा पत्ता लाग्यो"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट स्वतः असक्षम पारियो। थप जान्न ट्याप गर्नुहोस्।"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB पोर्ट प्रयोग गर्न सुरक्षित छ"</string>
@@ -1911,8 +1962,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"कार्य प्रोफाइल अनलक गर्न ट्याप गर्नुहोस्"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> मा जडान गरिएको छ"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"फाइलहरू हेर्न ट्याप गर्नुहोस्"</string>
-    <string name="pin_target" msgid="3052256031352291362">"पिन गर्नुहोस्"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"अनपिन गर्नुहोस्"</string>
     <string name="app_info" msgid="6856026610594615344">"अनुप्रयोगका बारे जानकारी"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"डेमो सुरु गर्दै…"</string>
@@ -2003,6 +2052,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"दिनचर्या मोडको जानकारीमूलक सूचना"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"प्रायः चार्ज गर्ने समय हुनुभन्दा पहिले नै ब्याट्री सकिन सक्छ"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"ब्याट्रीको आयु बढाउन ब्याट्री सेभर सक्रिय गरियो"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"फोल्डर"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android अनुप्रयोग"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"फाइल"</string>
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml b/core/res/res/values-night/colors_device_defaults.xml
similarity index 75%
rename from packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
rename to core/res/res/values-night/colors_device_defaults.xml
index 66cfaff..08ad492 100644
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
+++ b/core/res/res/values-night/colors_device_defaults.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2019 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,5 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
+
+<resources>
+    <color name="accent_device_default">@color/accent_device_default_dark</color>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index 0721f6f..8640510 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -63,9 +63,11 @@
 
     <!-- Theme for the dialog shown when an app crashes or ANRs. -->
     <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert" />
+    <style name="Theme.DeviceDefault.Dialog.Alert.DayNight" parent="Theme.DeviceDefault.Dialog.Alert" />
 
     <style name="Theme.DeviceDefault.DayNight" parent="Theme.DeviceDefault" />
 
     <style name="ThemeOverlay.DeviceDefault.Accent.DayNight"
            parent="@style/ThemeOverlay.DeviceDefault.Accent" />
+
 </resources>
\ No newline at end of file
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f7482bc..bc55c45 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Bellen via wifi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Uit"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Voorkeur voor wifi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Voorkeur voor mobiel"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Alleen wifi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: niet doorgeschakeld"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bugrapport"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Sessie beëindigen"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Bugrapport genereren"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Hiermee worden gegevens over de huidige status van je apparaat verzameld en als e-mail verzonden. Wanneer u een bugrapport start, duurt het even voordat het kan worden verzonden. Even geduld alstublieft."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactief rapport"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Gebruik deze optie in de meeste situaties. Hiermee kun je de voortgang van het rapport bijhouden, meer gegevens over het probleem opgeven en screenshots maken. Mogelijk worden bepaalde minder vaak gebruikte gedeelten weggelaten (waarvoor het lang zou duren om een rapport te genereren)."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Locatie"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"de locatie van dit apparaat openen"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang geven tot de locatie van dit apparaat?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"De app heeft alleen toegang tot de locatie wanneer je de app gebruikt."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; altijd toegang geven tot de locatie van dit apparaat?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"De app heeft altijd toegang tot de locatie, ook wanneer je de app niet gebruikt."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"toegang krijgen tot je agenda"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang geven tot je agenda?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang geven tot je muziek?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Foto\'s en video\'s"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"toegang tot je foto\'s en video\'s"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang geven tot je foto\'s en video\'s, waaronder getagde locaties?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Content van vensters ophalen"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"De content inspecteren van een venster waarmee je interactie hebt."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\'Verkennen via aanraking\' inschakelen"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Hiermee kan de app communiceren met NFC-tags (Near Field Communication), kaarten en lezers."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"je schermvergrendeling uitschakelen"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Hiermee kan de app de toetsenblokkering en bijbehorende wachtwoordbeveiliging uitschakelen. Zo kan de telefoon de toetsenblokkering uitschakelen wanneer je wordt gebeld en de toetsenblokkering weer inschakelen als het gesprek is beëindigd."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"complexiteit van schermvergrendeling opvragen"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Hiermee krijgt de app toestemming om het complexiteitsniveau van de schermvergrendeling te achterhalen (hoog, midden, laag of geen). Dat geeft een indicatie van het mogelijke lengtebereik en type van de schermvergrendeling. De app kan gebruikers ook voorstellen de schermvergrendeling naar een bepaald niveau te updaten, maar gebruikers kunnen dit altijd negeren en de app verlaten. De schermvergrendeling wordt niet opgeslagen in platte tekst, zodat de app het precieze wachtwoord niet weet."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"biometrische hardware gebruiken"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Hiermee kan de app biometrische hardware gebruiken voor verificatie"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"Vingerafdrukhardware beheren"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Hiermee kan de app methoden aanroepen om gezichtstemplates toe te voegen en te verwijderen voor gebruik."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"hardware voor gezichtsherkenning gebruiken"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Hiermee kan de app hardware voor gezichtsherkenning gebruiken voor verificatie"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Kan gezicht niet verwerken. Probeer het opnieuw."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Gezicht is te helder. Probeer bij minder licht."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Gezicht is te donker. Laat meer licht toe."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Houd de sensor verder weg van je gezicht."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Houd de sensor dichter bij je gezicht."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Beweeg de sensor omhoog."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Beweeg de sensor omlaag."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Beweeg de sensor naar rechts."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Beweeg de sensor naar links."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Kijk naar de sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Geen gezicht gedetecteerd."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Te veel beweging."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registreer je gezicht opnieuw."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Ander gezicht gedetecteerd."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Lijkt te veel op elkaar. Verander je pose."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Kijk rechter in de camera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Kijk rechter in de camera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Houd je hoofd verticaal recht."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Laat je gezicht zien."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardware voor gezichtsherkenning niet beschikbaar."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Time-out voor gezicht bereikt. Probeer opnieuw."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Gezicht kan niet worden opgeslagen."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Bewerking voor gezichtsherkenning geannuleerd."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Gezichtsverificatie geannuleerd door gebruiker."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Te veel pogingen. Probeer het later opnieuw."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Te veel pogingen. Gezichtsherkenning inactief."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Probeer het opnieuw."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Geen gezicht geregistreerd."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Dit apparaat heeft geen sensor voor gezichtsherkenning."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Gezicht <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> openen"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> wordt gesloten zonder op te slaan"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> heeft geheugenlimiet overschreden"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Heap dump verzameld. Tik om te delen."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Heap dump delen?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Het proces <xliff:g id="PROC">%1$s</xliff:g> heeft de procesgeheugenlimiet overschreden met <xliff:g id="SIZE">%2$s</xliff:g>. Een heap dump is voor u beschikbaar om te delen met de betreffende ontwikkelaar. Let op: Deze heap dump kan persoonsgegevens bevatten waartoe de app toegang heeft."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Een actie voor tekst selecteren"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Belvolume"</string>
     <string name="volume_music" msgid="5421651157138628171">"Mediavolume"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerken te bekijken"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinding maken"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netwerken"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Er is een wifi-netwerk beschikbaar dat is voorgesteld door <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Wil je verbinding maken met netwerken die worden voorgesteld door <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nee"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wifi wordt automatisch ingeschakeld"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Inloggen bij netwerk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wifi-netwerk heeft geen internettoegang"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tik voor opties"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Verbonden"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Wijzigingen in je hotspot-instellingen"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Je hotspot-band is gewijzigd."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Dit apparaat biedt geen ondersteuning voor je voorkeur voor alleen 5 GHz. In plaats daarvan gebruikt dit apparaat de 5-GHz-band wanneer deze beschikbaar is."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tik om USB-foutopsporing uit te schakelen"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vloeistof of vuil in USB-poort"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-poort is automatisch uitgeschakeld. Tik voor meer informatie."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Veilig om USB-poort te gebruiken"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Ontgrendel werkprofiel met tik"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Verbonden met <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tik om bestanden te bekijken"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Vastzetten"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Losmaken"</string>
     <string name="app_info" msgid="6856026610594615344">"App-info"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo starten…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Informatiemelding voor routinemodus"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"De batterij raakt mogelijk leeg voordat deze normaal gesproken wordt opgeladen"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Batterijbesparing is geactiveerd om de batterijduur te verlengen"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Map"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android-app"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Bestand"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 1607b40..eb7e6ae 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"ୱାଇଫାଇ କଲିଂ"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ଅଫ୍"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ପସନ୍ଦ କରାଯାଇଥିବା ୱାଇ-ଫାଇ"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ପସନ୍ଦର ମୋବାଇଲ୍‌"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"କେବଳ ୱାଇ-ଫାଇ"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ଫରୱାର୍ଡ କରାଯାଇନାହିଁ"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ବଗ୍‌ ରିପୋର୍ଟ"</string>
     <string name="global_action_logout" msgid="935179188218826050">"ସେସନ୍‍ ଶେଷ କରନ୍ତୁ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ସ୍କ୍ରୀନଶଟ୍‌"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"ବଗ୍ ରିପୋର୍ଟ ନିଅନ୍ତୁ"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"ଇ-ମେଲ୍ ମେସେଜ୍‍ ଭାବରେ ପଠାଇବାକୁ, ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ଡିଭାଇସ୍‌ ବିଷୟରେ ଏହା ସୂଚନା ସଂଗ୍ରହ କରିବ। ବଗ୍ ରିପୋର୍ଟ ଆରମ୍ଭ ହେବାପରଠାରୁ ଏହାକୁ ପଠାଇବା ପାଇଁ କିଛି ସମୟ ଲାଗିବ, ଦୟାକରି ଧୈର୍ଯ୍ୟ ରଖନ୍ତୁ।"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ଇଣ୍ଟରାକ୍ଟିଭ୍‍ ରିପୋର୍ଟ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ଅଧିକାଂଶ କ୍ଷେତ୍ରରେ ଏହା ବ୍ୟବହାର କରନ୍ତୁ। ଏହାଦ୍ୱାରା ଆପଣ ରିପୋର୍ଟର ପ୍ରଗତିକୁ ଟ୍ରାକ୍‍ କରିପାରିବେ, ସମସ୍ୟା ଉପରେ ଅଧିକ ବିବରଣୀ ଲେଖିପାରିବେ ଏବଂ ସ୍କ୍ରୀନଶଟ୍‍ ନେଇପାରିବେ। ଏହା କିଛି କମ୍‌-ବ୍ୟବହାର କରାଯାଇଥିବା ବିଭାଗକୁ ଛାଡ଼ିଦେଇପାରେ, ଯାହା ରିପୋର୍ଟ କରିବାକୁ ଅଧିକ ସମୟ ନିଏ।"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"ଲୋକେଶନ୍‌"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"ଏହି ଡିଭାଇସ୍‌ର ଲୋକେଶନ୍‍ ଆକ୍ସେସ୍‍ କରେ"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ଏହି ଡିଭାଇସ୍‌ର ଲୋକେଶନ୍‍ ଆକ୍ସେସ୍‍ କରିବା ପାଇଁ ଅନୁମତି ଦେବେ କି?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"ଆପଣ ଆପ୍‍ ବ୍ୟବହାର କରୁଥିବା ବେଳେ କେବଳ ଲୋକେସନ୍‍କୁ ଆପ୍‍‍ର ଆକ୍ସେସ୍‍ ରହିବ।"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"ସଦାବେଳେ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ଏହି ଡିଭାଇସ୍‌ର ଲୋକେସନ୍‍ ଆକ୍ସେସ୍‍ କରିବା ପାଇଁ ଅନୁମତି ଦେବେ କି?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"ଆପଣ ଆପ୍‍ ବ୍ୟବହାର କରୁନଥିଲେ ମଧ୍ୟ, ଲୋକେସନ୍‍କୁ ସଦାବେଳେ ଆପ୍‍‍ର ଆକ୍ସେସ୍‍ ରହିବ।"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"କ୍ୟାଲେଣ୍ଡର୍"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍‍ ଆକ୍ସେସ୍‍ କରେ"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍‌କୁ ଆକ୍ସେସ୍‍ କରିବା ପାଇଁ ଅନୁମତି ଦେବେ କି?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"ଆପଣଙ୍କ ସଙ୍ଗୀତକୁ ଆକ୍ସେସ୍‍ କରିବାକୁ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ଅନୁମତି ଦେବେ କି?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ଫଟୋ ଓ ଭିଡିଓ"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"ଆପଣଙ୍କ ଫଟୋ ଏବଂ ଭିଡିଓ ଆକ୍ସେସ୍‍ କରନ୍ତୁ"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"ଟ୍ୟାଗ୍ କରାଯାଇଥିବା ଲୋକେସନ୍ ସହିତ ଆପଣଙ୍କ ଫଟୋ ଏବଂ ଭିଡିଓ ଆକ୍ସେସ୍ କରିବାକୁ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; କୁ ଅନୁମତି ଦେବେ କି?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ୱିଣ୍ଡୋ କଣ୍ଟେଣ୍ଟ ହାସଲ କରନ୍ତୁ"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ଆପଣ କାମ କରୁଥିବା ୱିଣ୍ଡୋର କଣ୍ଟେଣ୍ଟକୁ ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ସ୍ପର୍ଶ ଦ୍ୱାରା ଏକ୍ସପ୍ଲୋର୍‍ ଅନ୍‍ କରନ୍ତୁ"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"ନିଅର୍‍ ଫିଲ୍ଡ କମ୍ୟୁନିକେସନ୍‍ନ (NFC) ଟାଗ୍‍, କାର୍ଡ ଓ ରିଡରଗୁଡ଼ିକ ସହ ଯୋଗାଯୋଗ କରିବା ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ଆପଣଙ୍କ ସ୍କ୍ରୀନ୍‍ ଲକ୍‍ ଅକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ଆପ୍‌କୁ କୀ\'ଲକ୍ କିମ୍ବା ସେଥିରେ ଥିବା କୌଣସି ପାସ୍‌ୱର୍ଡ ସୁରକ୍ଷାକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଅନୁମତି ଦିଏ, ଉଦାହରଣସ୍ୱରୂପ, ଇନ୍‌କମିଙ୍ଗ ଫୋନ୍‌ କଲ୍ ପ୍ରାପ୍ତ କରିବା ସମୟରେ ଫୋନ୍‌ଟି କୀ\'ଲକ୍‌କୁ ଅକ୍ଷମ କରିଦିଏ, ତା’ପରେ କଲ୍ ସମାପ୍ତ ହେବାପରେ ପୁଣି କୀ\'ଲକ୍‌କୁ ସକ୍ଷମ କରିଥାଏ।"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ସ୍କ୍ରିନ୍ ଲକ୍ ଜଟିଳତା ପ୍ରାପ୍ତ କରନ୍ତୁ"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"ସ୍କ୍ରିନ୍ ଲକ୍‌ର ଜଟିଳତା ସ୍ତର (ଉଚ୍ଚ, ମଧ୍ୟମ, ନିମ୍ନ କିମ୍ବା କିଛିନୁହେଁ), ଜାଣିବାକୁ ଆପ୍‌କୁ ଅନୁମତି ଦିଅନ୍ତୁ, ଯାହା ସ୍କ୍ରିନ୍ ଲକ୍‌ର ସମ୍ଭାବ୍ୟ ପରିସୀମାର ଲମ୍ବ ଏବଂ ପ୍ରକାର ସୂଚୀତ କରେ। ଆପ୍ ଏହା ମଧ୍ୟ ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କୁ ପରାମର୍ଶ ଦେଇପାରେ ଯେ ସେମାନେ ସ୍କ୍ରିନ୍ ଲକ୍‌କୁ ଏକ ନିର୍ଦ୍ଧିଷ୍ଟ ସ୍ତର ପର୍ଯ୍ୟନ୍ତ ଅପ୍‌ଡେଟ୍ କରିପାରନ୍ତି, କିନ୍ତୁ ଉପଯୋଗକର୍ତ୍ତାମାନେ ନିଜ ଇଚ୍ଛାରେ ଏହାକୁ ଉପେକ୍ଷା ଏବଂ ନାଭିଗେଟ୍ କରିପାରିବେ। ଏହା ଧ୍ୟାନ ଦିଅନ୍ତୁ ଯେ ସ୍କ୍ରିନ୍ ଲକ୍ ସରଳ ଟେକ୍ସଟ୍‌ରେ ଷ୍ଟୋର୍ କରାଯାଇନଥାଏ ଯେପରି ଆପ୍ ସଠିକ୍ ପାସ୍‌‍ୱର୍ଡ ଜାଣିପାରିନଥାଏ।"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ବାୟୋମେଟ୍ରିକ୍‌ ହାର୍ଡୱେର୍‌ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"ସ୍ୱୀକୃତି ପାଇଁ ବାୟୋମେଟ୍ରିକ୍‌ ହାର୍ଡୱେର୍‌ ବ୍ୟବହାର କରିବାକୁ ଅନୁମତି ଦିଏ"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ହାର୍ଡୱେର୍‍ ପରିଚାଳନା କରନ୍ତୁ"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ବ୍ୟବହାର ପାଇଁ ଆପ୍‍କୁ ଫେସିଆଲ୍‍ ଟେମ୍ପଲେଟ୍‍ ଯୋଡିବା ଓ ଡିଲିଟ୍‍ ର ପଦ୍ଧତି ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ।"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"ଫେସ୍‍ ପ୍ରମାଣୀକରଣ ହାର୍ଡୱେର୍‌ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"ଫେସ୍‍ ପ୍ରମାଣୀକରଣ ହାର୍ଡୱେର୍‌ର ପ୍ରମାଣ ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦିଅନ୍ତୁ।"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"ଫେସ୍‍ ଚିହ୍ନଟ ହେଲାନାହିଁ ।ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"ଫେସ୍‍ଟି ବହୁତ ଉଜ୍ଵଳ ଦେଖାଯାଉଛି। ଦୟାକରି, କମ ଆଲୋକରେ ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"ଫେସ୍‍ଟି ବହୁତ କଳା ଦେଖାଯାଉଛି। ଦୟାକରି ଆଲୋକକୁ ଅନାବୃତ କରନ୍ତୁ।"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"ଦୟାକରି ସେନ୍‍ସର୍‍କୁ ଫେସ୍‍ ପାଖରୁ ଦୂରେଇ ରଖନ୍ତୁ"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"ଦୟାକରି ସେନ୍‍ସର୍‍କୁ ଫେସ୍‍ର ଅତି ନିକଟକୁ ଆଣନ୍ତୁ।"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"ଦୟାକରି ସେନ୍‍ସର୍‍କୁ ଆହୁରି ଉପରକୁ ଘୁଞ୍ଚାନ୍ତୁ।"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"ଦୟାକରି ସେନ୍‍ସର୍‍କୁ ତଳକୁ ଘୁଞ୍ଚାନ୍ତୁ।"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"ଦୟାକରି ସେନ୍‍ସର୍‍କୁ ଦକ୍ଷିଣକୁ ଘୁଞ୍ଚାନ୍ତୁ।"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"ଦୟାକରି ସେନ୍‍ସର୍‍କୁ ବାମକୁ ଘୁଞ୍ଚାନ୍ତୁ।"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"ଦୟାକରି ସେନ୍‍ସର୍‍କୁ ଦେଖନ୍ତୁ"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"କୌଣସି ଫେସ୍‍ ଚିହ୍ନଟ ହେଲା ନାହିଁ"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"ଅତ୍ୟଧିକ ଅସ୍ଥିର।"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ଦୟାକରି ଆପଣଙ୍କର ମୁହଁ ପୁଣି-ଏନ୍‍ରୋଲ୍ କରନ୍ତୁ।"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"ଭିନ୍ନ ମୁହଁ ଚିହ୍ନଟ କରାଗଲା।"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ଅତ୍ୟନ୍ତ ସମପରି, ଦୟାକରି ଆପଣଙ୍କର ପୋଜ୍ ବଦଳାନ୍ତୁ।"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"ଦୟାକରି କ୍ୟାମେରାକୁ ସିଧା ଦେଖନ୍ତୁ।"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"ଦୟାକରି କ୍ୟାମେରାକୁ ସିଧା ଦେଖନ୍ତୁ।"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"ଦୟାକରି ଆପଣଙ୍କର ମୁଣ୍ଡକୁ ସିଧା ରଖନ୍ତୁ।"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"ଦୟାକରି ଆପଣଙ୍କର ମୁହଁକୁ ଘୋଡାନ୍ତୁ ନାହିଁ।"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"ଫେସ୍‍ର ହାର୍ଡୱେୟାର୍‍ ଉପଲବ୍ଧ ନାହିଁ।"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"ଫେସ୍‍ର ସମୟସୀମା ସରିଗଲା। ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"ଫେସ୍‍ ମେମୋରୀରେ ଷ୍ଟୋର୍‍ କରାଯାଇପାରିବ ନାହିଁ।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ଫେସ୍‍ର ଅପରେଶନ୍‍ କ୍ୟାନ୍ସଲ୍‍ ହୋ‍ଇଗଲା"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"ଉପଯୋଗକର୍ତ୍ତା ମୁହଁ ଚିହ୍ନଟକରଣ ବାତିଲ୍‌ କରିଛନ୍ତି।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ବାରମ୍ବାର ଚେଷ୍ଟା। ପରେ ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ବାରମ୍ବାର ଚେଷ୍ଟା। ଫେସ୍‍ ପ୍ରମାଣୀକରଣ ଅକ୍ଷମ କରାଗଲା।"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"କୌଣସି ଫେସ୍‍ ପଞ୍ଜୀକୃତ ହୋ‍ଇନଥିଲା।"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"ଡିଭାଇସ୍‍‍ରେ ମୁହଁ ପ୍ରାମାଣିକିକରଣ ସେନ୍‍ସର୍ ନାହିଁ"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g>ଙ୍କ ଫେସ୍‍"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g>କୁ ଖୋଲନ୍ତୁ"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> ସେଭ୍ ନହୋଇ ବନ୍ଦ ହୋଇଯିବ"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ଧାର୍ଯ୍ୟ ମେମୋରୀରୁ ବାହାରକୁ ଗଲା"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"’ହୀପ୍ ଡମ୍ପ’ ସଂଗ୍ରହ କରାଯାଇସାରିଛି। ଶେୟାର୍ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ହିପ୍‌ ଡମ୍ପ ଶେୟାର୍‍ କରିବେ?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> ପ୍ରୋସେସ୍‍ ଏହାର ଧାର୍ଯ୍ୟ <xliff:g id="SIZE">%2$s</xliff:g> ମେମୋରୀ ସୀମାରୁ ବାହରକୁ ଗଲା। ଏହାର ଡେଭଲପରଙ୍କ ସହ ଶେୟାର୍‍ କରିବାକୁ ଏକ ହିପ୍‍ ଡମ୍ପ ଉପଲବ୍ଧ ଅଛି। ସାବଧାନ ରୁହନ୍ତୁ: ଆପ୍ଲିକେଶନର ଆକ୍ସେସ୍‍ ରହିଥିବା ଆପଣଙ୍କର ଯେକୌଣସି ବ୍ୟକ୍ତିଗତ ସୂଚନା ଏହି ହିପ୍‍ ଡମ୍ପରେ ରହିପାରେ।"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"ଟେକ୍ସଟ୍‍ ପାଇଁ ଏକ କାର୍ଯ୍ୟ ବାଛନ୍ତୁ"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"ରିଙ୍ଗର୍‌ ଭଲ୍ୟୁମ୍"</string>
     <string name="volume_music" msgid="5421651157138628171">"ମିଡିଆ ଭଲ୍ୟୁମ୍‌"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ସମସ୍ତ ନେଟ୍‌ୱର୍କ ଦେଖିବାକୁ ଟାପ୍‍ କରନ୍ତୁ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"କନେକ୍ଟ କରନ୍ତୁ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ସମସ୍ତ ନେଟ୍‌ୱର୍କ"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g>ଙ୍କ ଦ୍ୱାରା ପ୍ରସ୍ତାବିତ ଏକ ୱାଇ-ଫାଇ ନେଟ୍‌ୱର୍କ ଉପଲବ୍ଧ ଅଛି"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g>ଙ୍କ ଦ୍ବାରା ପ୍ରସ୍ତାବିତ ନେଟ୍‌ୱର୍କ ସହ ସଂଯୋଗ କରିବାକୁ ଚାହାନ୍ତି କି?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ହଁ"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ନାହିଁ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ୱାଇ-ଫାଇ ସ୍ୱଚାଳିତ ଭାବେ ଅନ୍ ହେବ"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ନେଟ୍‌ୱର୍କରେ ସାଇନ୍‍ ଇନ୍‍ କରନ୍ତୁ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"ୱାଇ-ଫାଇର କୌଣସି ଇଣ୍ଟରନେଟ୍‍ ଆକ୍ସେସ୍‍ ନାହିଁ"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ବିକଳ୍ପ ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"ସଂଯୁକ୍ତ ହୋଇଛି"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"ଆପଣଙ୍କର ହଟ୍‌ସ୍ପଟ୍‍ ସେଟିଙ୍ଗକୁ ବଦଳିଯାଇଛି"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"ଆପଣଙ୍କର ହଟ୍‍ସ୍ପଟ୍‌ ପରିବର୍ତ୍ତନ କରାଯାଇଛି"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"କେବଳ 5GHz ପାଇଁ, ଏହି ଡିଭାଇସ୍‍ ଆପଣଙ୍କର ପସନ୍ଦକୁ ସପୋର୍ଟ କରେନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ, ଏହି ଡିଭାଇସ୍‍ 5GHz ବ୍ୟାଣ୍ଡ ବ୍ୟବହାର କରିବ।"</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ଡିବଗିଙ୍ଗ ସଂଯୁକ୍ତ ହୋଇଛି"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USBର ଡିବଗିଙ୍ଗ ସୁବିଧାକୁ ବନ୍ଦ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ଡିବଗିଙ୍ଗକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ପୋର୍ଟରେ ତରଳ ପଦାର୍ଥ ବା ଧୂଳି"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ପୋର୍ଟ ସ୍ୱଚାଳିତ ଭାବେ ଅକ୍ଷମ ହୋଇଛି। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB ପୋର୍ଟ ବ୍ୟବହାର କରିବା ପାଇଁ ସୁରକ୍ଷିତ ଅଟେ"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‍ ଅନଲକ୍‍ କରିବାକୁ ଟାପ୍‍ କରନ୍ତୁ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ସହ କନେକ୍ଟ କରାଗଲା"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ଫାଇଲ୍‍ ଦେଖିବା ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ"</string>
-    <string name="pin_target" msgid="3052256031352291362">"ପିନ୍‍"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"ଅନପିନ୍ କରନ୍ତୁ"</string>
     <string name="app_info" msgid="6856026610594615344">"ଆପ୍‍ ସୂଚନା"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ଡେମୋ ଆରମ୍ଭ କରାଯାଉଛି…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"ନିୟମିତ ମୋଡ୍‍ ସୂଚନା ବିଜ୍ଞପ୍ତି"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ସାଧାରଣ ଭାବରେ ଚାର୍ଜ୍ କରିବା ପୂର୍ବରୁ ବ୍ୟାଟେରୀ ସରିଯାଇପାରେ"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"ବ୍ୟାଟେରୀର ସମୟକୁ ବଢ଼ାଇବା ପାଇଁ ବ୍ୟଟେରୀ ସେଭର୍‍କୁ କାର୍ଯ୍ୟକାରୀ କରାଯାଇଛି"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ଫୋଲ୍ଡର୍"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android ଆପ୍ଲିକେସନ୍"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ଫାଇଲ୍"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 421d52f..b46f321 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ਬੰਦ"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ਤਰਜੀਹੀ ਵਾਈ-ਫਾਈ"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ਮੋਬਾਈਲ ਨੂੰ ਤਰਜੀਹ ਹੈ"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"ਸਿਰਫ਼ ਵਾਈ-ਫਾਈ"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ਅੱਗੇ ਨਹੀਂ ਭੇਜਿਆ ਗਿਆ"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ਬਗ ਰਿਪੋਰਟ"</string>
     <string name="global_action_logout" msgid="935179188218826050">"ਸੈਸ਼ਨ ਸਮਾਪਤ ਕਰੋ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"ਬੱਗ ਰਿਪੋਰਟ ਲਓ"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"ਇਹ ਇੱਕ ਈਮੇਲ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ, ਤੁਹਾਡੇ ਵਰਤਮਾਨ ਡੀਵਾਈਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਠੀ ਕਰੇਗਾ। ਬੱਗ ਰਿਪੋਰਟ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਥੋੜ੍ਹਾ ਸਮਾਂ ਲੱਗੇਗਾ ਜਦੋਂ ਤੱਕ ਇਹ ਭੇਜੇ ਜਾਣ ਲਈ ਤਿਆਰ ਨਾ ਹੋਵੇ, ਕਿਰਪਾ ਕਰਕੇ ਧੀਰਜ ਰੱਖੋ।"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ਅੰਤਰਕਿਰਿਆਤਮਕ ਰਿਪੋਰਟ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ਜ਼ਿਆਦਾਤਰ ਹਾਲਾਤਾਂ ਵਿੱਚ ਇਸ ਦੀ ਵਰਤੋਂ ਕਰੋ। ਇਹ ਤੁਹਾਨੂੰ ਰਿਪੋਰਟ ਦੀ ਪ੍ਰਗਤੀ ਨੂੰ ਟਰੈਕ ਕਰਨ, ਸਮੱਸਿਆ ਬਾਰੇ ਹੋਰ ਵੇਰਵੇ ਦਾਖਲ ਕਰਨ, ਅਤੇ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦਿੰਦਾ ਹੈ। ਇਹ ਉਹਨਾਂ ਘੱਟ-ਵਰਤੇ ਗਏ ਕੁਝ ਭਾਗਾਂ ਨੂੰ ਨਜ਼ਰ-ਅੰਦਾਜ਼ ਕਰ ਸਕਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਦੀ ਰਿਪੋਰਟ ਕਰਨ ਵਿੱਚ ਵੱਧ ਸਮਾਂ ਲੱਗ ਸਕਦਾ ਹੈ।"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"ਟਿਕਾਣਾ"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"ਇਸ ਡੀਵਾਈਸ ਦੇ ਨਿਰਧਾਰਤ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚੋ"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"ਕੀ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਇਸ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਐਪ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਹੀ ਐਪ ਕੋਲ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ।"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"ਕੀ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਹਮੇਸ਼ਾਂ ਇਸ ਡੀਵਾਈਸ ਦੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"ਐਪ ਕੋਲ ਹਮੇਸ਼ਾਂ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਹੋਵੇਗੀ, ਭਾਵੇਂ ਤੁਸੀਂ ਐਪ ਦੀ ਵਰਤੋਂ ਨਾ ਕਰ ਰਹੇ ਹੋਵੋ।"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ਕੈਲੰਡਰ"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"ਕੀ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨੀ ਦੇਣੀ ਹੈ?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"ਕੀ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਤੁਹਾਡੇ ਸੰਗੀਤ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"ਤੁਹਾਡੀਆਂ ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਤੱਕ ਪਹੁੰਚ"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"ਕੀ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਟੈਗ ਕੀਤੇ ਟਿਕਾਣਿਆਂ ਸਮੇਤ ਤੁਹਾਡੀਆਂ ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰਨਾ"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਉਸ ਵਿੰਡੋ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਅੰਤਰਕਿਰਿਆ ਕਰ ਰਹੇ ਹੋ"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\'ਸਪੱਰਸ਼ ਰਾਹੀਂ ਪੜਚੋਲ ਕਰੋ\' ਚਾਲੂ ਕਰਨਾ"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"ਐਪ ਨੂੰ ਨਜ਼ਦੀਕੀ ਖੇਤਰ ਸੰਚਾਰ (NFC) ਟੈਗਾਂ, ਕਾਰਡਾਂ ਅਤੇ ਰੀਡਰਾਂ ਨਾਲ ਸੰਚਾਰ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ਆਪਣਾ ਸਕ੍ਰੀਨ  ਲਾਕ  ਅਸਮਰੱਥ ਬਣਾਓ"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ਐਪ ਨੂੰ ਕੀਲਾਕ ਅਤੇ ਕਿਸੇ ਵੀ ਸੰਬੰਧਿਤ ਪਾਸਵਰਡ ਸੁਰੱਖਿਆ ਨੂੰ ਬੰਦ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਫ਼ੋਨ ਇੱਕ ਇਨਕਮਿੰਗ ਫ਼ੋਨ ਕਾਲ ਪ੍ਰਾਪਤ ਕਰਨ ਵੇਲੇ ਬੰਦ ਕਰਦਾ ਹੈ, ਫਿਰ ਜਦੋਂ ਕਾਲ ਖਤਮ ਹੁੰਦੀ ਹੈ ਤਾਂ ਕੀਲਾਕ ਨੂੰ ਮੁੜ-ਚਾਲੂ ਕਰਦਾ ਹੈ।"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਜਟਿਲਤਾ ਲਈ ਬੇਨਤੀ ਕਰੋ"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"ਐਪ ਨੂੰ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਜਟਿਲਤਾ ਦੇ ਪੱਧਰ ਬਾਰੇ ਜਾਣਨ ਦਿਓ (ਉੱਚ, ਮੱਧਮ, ਘੱਟ ਜਾਂ ਕੋਈ ਨਹੀਂ), ਜੋ ਲੰਬਾਈ ਦੀ ਸੰਭਵ ਰੇਂਜ ਅਤੇ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਕਿਸਮ ਦਾ ਸੰਕੇਤ ਦਿੰਦਾ ਹੈ। ਐਪ ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਇੱਕ ਖਾਸ ਪੱਧਰ ਤੱਕ ਸਕ੍ਰੀਨ ਲਾਕ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੁਝਾਅ ਵੀ ਦੇ ਸਕਦੀ ਹੈ ਪਰ ਵਰਤੋਂਕਾਰ ਇਸਨੂੰ ਅਣਡਿੱਠ ਕਰ ਸਕਦੇ ਹਨ। ਨੋਟ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਲਾਕ ਸਧਾਰਨ ਲਿਖਤ ਵਿੱਚ ਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਇਸ ਲਈ ਐਪ ਸਹੀ ਪਾਸਵਰਡ ਬਾਰੇ ਨਹੀਂ ਜਾਣਦੀ ਹੈ।"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ਬਾਇਓਮੈਟ੍ਰਿਕ ਹਾਰਡਵੇਅਰ ਵਰਤੋ"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"ਐਪ ਨੂੰ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਬਾਇਓਮੈਟ੍ਰਿਕ ਹਾਰਡਵੇਅਰ ਵਰਤਣ ਦਿੰਦਾ ਹੈ"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਹਾਰਡਵੇਅਰ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ਐਪ ਨੂੰ ਵਰਤਣ ਲਈ ਚਿਹਰਾ ਟੈਮਪਲੇਟ ਸ਼ਾਮਲ ਕਰਨ ਜਾਂ ਮਿਟਾਉਣ ਦੀਆਂ ਵਿਧੀਆਂ ਦੀ ਬੇਨਤੀ ਕਰਨ ਦਿੰਦੀ ਹੈ।"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਰਨ ਹਾਰਡਵੇਅਰ ਵਰਤੋ"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"ਐਪ ਨੂੰ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਰਨ ਹਾਰਡਵੇਅਰ ਵਰਤਣ ਦਿੰਦੀ ਹੈ"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਨਹੀਂ ਹੋਈ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"ਚਿਹਰਾ ਬਹੁਤ ਚਮਕਦਾਰ ਹੈ। ਘੱਟ ਰੋਸ਼ਨੀ ਵਿੱਚ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"ਚਿਹਰਾ ਹਨੇਰੇ ਵਿੱਚ ਹੈ। ਚਾਨਣ ਕਰੋ।"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"ਚਿਹਰੇ ਨੂੰ ਸੈਂਸਰ ਤੋਂ ਦੂਰ ਲਿਜਾਓ।"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"ਚਿਹਰੇ ਨੂੰ ਸੈਂਸਰ ਦੇ ਨੇੜੇ ਲਿਆਓ।"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"ਸੈਂਸਰ ਨੂੰ ਉੱਪਰ ਕਰੋ।"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"ਸੈਂਸਰ ਨੂੰ ਥੱਲੇ ਕਰੋ।"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"ਸੈਂਸਰ ਨੂੰ ਸੱਜੇ ਪਾਸੇ ਲਿਜਾਓ।"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"ਸੈਂਸਰ ਨੂੰ ਖੱਬੇ ਪਾਸੇ ਲਿਜਾਓ।"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"ਕਿਰਪਾ ਕਰਕੇ ਸੈਂਸਰ ਵੱਲ ਦੇਖੋ।"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"ਕੋਈ ਚਿਹਰਾ ਨਹੀਂ ਦਿਸਿਆ।"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਹਿਲਜੁਲ।"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ਕਿਰਪਾ ਕਰਕੇ ਆਪਣਾ ਚਿਹਰਾ ਦੁਬਾਰਾ ਦਰਜ ਕਰੋ।"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"ਵੱਖਰੇ ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਕੀਤੀ ਗਈ।"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ਬਹੁਤ ਮਿਲਦਾ-ਜੁਲਦਾ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਆਪਣਾ ਅੰਦਾਜ਼ ਬਦਲੋ।"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"ਕਿਰਪਾ ਕਰਕੇ ਸਿੱਧਾ ਕੈਮਰੇ ਵੱਲ ਦੇਖੋ।"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"ਕਿਰਪਾ ਕਰਕੇ ਸਿੱਧਾ ਕੈਮਰੇ ਵੱਲ ਦੇਖੋ।"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਸਿਰ ਨੂੰ ਸਿੱਧਾ ਖੜ੍ਹਵਾਂ ਰੱਖੋ।"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"ਕਿਰਪਾ ਕਰਕੇ ਆਪਣਾ ਚਿਹਰਾ ਦਿਖਾਓ।"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"ਚਿਹਰਾ ਹਾਰਡਵੇਅਰ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"ਚਿਹਰਾ ਪਛਾਣਨ ਦਾ ਸਮਾਂ ਸਮਾਪਤ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"ਚਿਹਰੇ ਦੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ਚਿਹਰਾ ਪਛਾਣਨ ਦੀ ਪ੍ਰਕਿਰਿਆ ਰੱਦ ਕੀਤੀ ਗਈ।"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"ਵਰਤੋਂਕਾਰ ਵੱਲੋਂ ਚਿਹਰਾ ਪੁਸ਼ਟੀਕਰਨ ਨੂੰ ਰੱਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ਹੱਦੋਂ ਵੱਧ ਕੋਸ਼ਿਸ਼ਾਂ। ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ਹੱਦੋਂ ਵੱਧ ਕੋਸ਼ਿਸ਼ਾਂ। ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਰਨ ਬੰਦ ਹੈ।"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"ਕੋਈ ਚਿਹਰਾ ਜਾਣਕਾਰੀ ਦਰਜ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਕੋਈ ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਰਨ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"ਚਿਹਰਾ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> ਰੱਖਿਅਤ ਕੀਤੇ ਬਿਨਾਂ ਬੰਦ ਹੋ ਜਾਵੇਗੀ"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> ਦੀ ਮੈਮਰੀ ਸੀਮਾ ਵਧ ਗਈ ਹੈ"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"ਹੀਪ ਡੰਪ ਨੂੰ ਇਕੱਤਰ ਕੀਤਾ ਗਿਆ। ਸਾਂਝਾ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ਕੀ ਹੀਪ ਡੰਪ ਸ਼ੇਅਰ ਕਰਨਾ ਹੈ?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"ਪ੍ਰਕਿਰਿਆ <xliff:g id="PROC">%1$s</xliff:g> ਦੀ ਆਪਣੀ ਪ੍ਰਕਿਰਿਆ ਮੈਮਰੀ ਸੀਮਾ <xliff:g id="SIZE">%2$s</xliff:g> ਵਧ ਗਈ ਹੈ। ਇਸਦੇ ਵਿਕਾਸਕਾਰ ਨਾਲ ਸਾਂਝਾ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਲਈ ਇੱਕ ਹੀਪ ਡੰਪ ਉਪਲਬਧ ਹੈ। ਸਾਵਧਾਨ ਰਹੋ: ਇਸ ਹੀਪ ਡੰਪ ਵਿੱਚ ਤੁਹਾਡੀ ਕੋਈ ਵੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਹੋ ਸਕਦੀ ਹੈ, ਜਿਸ \'ਤੇ ਐਪਲੀਕੇਸ਼ਨ ਦੀ ਪਹੁੰਚ ਹੈ।"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"ਲਿਖਤ ਲਈ ਕੋਈ ਕਾਰਵਾਈ ਚੁਣੋ"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"ਰਿੰਗਰ ਵੌਲਿਊਮ"</string>
     <string name="volume_music" msgid="5421651157138628171">"ਮੀਡੀਆ ਵੌਲਿਊਮ"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ਸਾਰੇ ਨੈੱਟਵਰਕਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"ਕਨੈਕਟ ਕਰੋ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ਸਾਰੇ ਨੈੱਟਵਰਕ"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> ਵੱਲੋਂ ਸੁਝਾਇਆ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਹੈ"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"ਕੀ ਤੁਸੀਂ <xliff:g id="NAME">%s</xliff:g> ਵੱਲੋਂ ਸੁਝਾਏ ਨੈੱਟਵਰਕਾਂ ਨਾਲ ਕਨੈਕਟ ਹੋਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ਹਾਂ"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ਨਹੀਂ"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ਵਾਈ‑ਫਾਈ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਚੱਲ ਪਵੇਗਾ"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"ਵਾਈ-ਫਾਈ ਦੀ ਕੋਈ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ਵਿਕਲਪਾਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"ਕਨੈਕਟ ਹੋਏ"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"ਤੁਹਾਡੀਆਂ ਹੌਟਸਪੌਟ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਬਦਲਾਅ"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"ਤੁਹਾਡਾ ਹੌਟਸਪੌਟ ਬੈਂਡ ਬਦਲ ਗਿਆ ਹੈ।"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"ਇਹ ਡੀਵਾਈਸ ਸਿਰਫ਼ 5GHz ਦੀ ਤੁਹਾਡੀ ਤਰਜੀਹ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦਾ ਹੈ। ਇਸਦੀ ਬਜਾਏ, ਇਹ ਡੀਵਾਈਸ ਉਪਲਬਧ ਹੋਣ \'ਤੇ 5GHz ਬੈਂਡ ਵਰਤੇਗਾ।"</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ਡੀਬਗਿੰਗ ਕਨੈਕਟ ਕੀਤੀ"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB ਡੀਬੱਗਿੰਗ ਬੰਦ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ਡੀਬੱਗਿੰਗ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਚੁਣੋ।"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ਪੋਰਟ ਵਿੱਚ ਪਾਣੀ ਜਾਂ ਧੂੜ-ਮਿੱਟੀ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ਪੋਰਟ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ। ਹੋਰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB ਪੋਰਟ ਵਰਤਣਾ ਸੁਰੱਖਿਅਤ ਹੈ"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋਈ"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ਫ਼ਾਈਲਾਂ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <string name="pin_target" msgid="3052256031352291362">"ਪਿੰਨ ਕਰੋ"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"ਅਨਪਿੰਨ ਕਰੋ"</string>
     <string name="app_info" msgid="6856026610594615344">"ਐਪ ਜਾਣਕਾਰੀ"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ਡੈਮੋ ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"ਨਿਯਮਬੱਧ ਮੋਡ ਦੀ ਜਾਣਕਾਰੀ ਵਾਲੀ ਸੂਚਨਾ"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"ਬੈਟਰੀ ਚਾਰਜ ਕਰਨ ਦੇ ਮਿੱਥੇ ਸਮੇਂ ਤੋਂ ਪਹਿਲਾਂ ਸ਼ਾਇਦ ਬੈਟਰੀ ਖਤਮ ਹੋ ਜਾਵੇ"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"ਬੈਟਰੀ ਲਾਈਫ਼ ਵਧਾਉਣ ਲਈ ਬੈਟਰੀ ਸੇਵਰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ਫੋਲਡਰ"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android ਐਪਲੀਕੇਸ਼ਨ"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ਫ਼ਾਈਲ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 674ccb0..07e8932 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -143,8 +143,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Połączenia przez Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Wył."</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferuj Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferowane komórkowe"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Tylko Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: nieprzekierowane"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -232,7 +234,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Zgłoszenie błędu"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Zakończ sesję"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Zrzut ekranu"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Zgłoś błąd"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Informacje o bieżącym stanie urządzenia zostaną zebrane i wysłane e-mailem. Przygotowanie zgłoszenia błędu do wysłania chwilę potrwa, więc zachowaj cierpliwość."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Raport interaktywny"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Używaj tej opcji w większości przypadków. Umożliwia śledzenie postępów raportu, podanie dodatkowych szczegółów problemu i wykonanie zrzutów ekranu. Raport może pomijać niektóre rzadko używane sekcje, których utworzenie zajmuje dużo czasu."</string>
@@ -287,9 +290,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokalizacja"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"dostęp do informacji o lokalizacji tego urządzenia"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Zezwolić aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na dostęp do lokalizacji urządzenia?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplikacja będzie mieć dostęp do lokalizacji tylko wtedy, gdy jest używana."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Zawsze zezwalać aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> na dostęp do lokalizacji urządzenia?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplikacja będzie zawsze mieć dostęp do lokalizacji, nawet wtedy, gdy nie jest używana."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendarz"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostęp do kalendarza"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Zezwolić aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na dostęp do kalendarza?"</string>
@@ -322,7 +328,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Zezwolić aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na dostęp do muzyki?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Zdjęcia i filmy"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"dostęp do zdjęć i filmów"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Zezwolić aplikacji „<xliff:g id="APP_NAME">%1$s</xliff:g>” na dostęp do Twoich zdjęć i filmów, w tym do otagowanych lokalizacji?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pobieranie zawartości okna"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Sprawdzanie zawartości okna, z którego korzystasz."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Włączenie czytania dotykiem"</string>
@@ -515,8 +524,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Pozwala aplikacji na komunikowanie się z tagami, kartami i czytnikami NFC (Near Field Communication)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"wyłączanie blokady ekranu"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Pozwala aplikacji na wyłączenie blokady klawiatury i wszystkich związanych z tym haseł zabezpieczających. Na przykład telefon wyłącza blokadę klawiatury, gdy odbiera połączenie przychodzące, a następnie włącza ją ponownie po zakończeniu połączenia."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"zażądaj informacji o stopniu złożoności blokady ekranu"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Zezwala aplikacji na poznanie stopnia złożoności blokady ekranu (wysoki, średni, niski lub brak), który wskazuje na możliwy zakres długości oraz typ blokady ekranu. Aplikacja może też zasugerować zaktualizowanie blokady ekranu pod kątem określonego stopnia złożoności, ale użytkownik może to zignorować i zamknąć komunikat. Pamiętaj, że blokada ekranu nie jest zapisywana jako tekst jawny, więc aplikacja nie pozna dokładnego hasła."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"używanie sprzętu biometrycznego"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Zezwala aplikacji na używanie sprzętu biometrycznego na potrzeby autoryzacji"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"zarządzanie czytnikiem linii papilarnych"</string>
@@ -571,37 +582,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Zezwala na aktywowanie przez aplikację metody dodawania i usuwania szablonów twarzy."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"używanie sprzętu do uwierzytelniania za pomocą twarzy"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Zezwala na używanie przez aplikację sprzętu do analizy twarzy na potrzeby uwierzytelniania"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Nie można przeanalizować twarzy. Spróbuj ponownie."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Zbyt jasna twarz. Spróbuj w ciemniejszym miejscu."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Zbyt ciemna twarz. Spróbuj w jaśniejszym miejscu."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Oddal czujnik od twarzy."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Przybliż czujnik do twarzy."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Przesuń czujnik wyżej."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Przesuń czujnik niżej."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Przesuń czujnik w prawo."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Przesuń czujnik w lewo."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Spójrz na czujnik."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nie wykryto twarzy."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Urządzenie za bardzo się porusza."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Zarejestruj swoją twarz ponownie."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Wykryto inną twarz."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Za mała różnica. Zmień pozycję."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Patrz prosto w obiektyw."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Patrz prosto w obiektyw."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Wyprostuj głowę w pionie."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Odsłoń twarz."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Czujnik twarzy nie jest dostępny."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Upłynął limit czasu analizy twarzy. Spróbuj ponownie."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Nie można zapisać informacji o twarzy."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Analiza twarzy została anulowana."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Użytkownik anulował uwierzytelnianie twarzą."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Zbyt wiele prób. Spróbuj ponownie później."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Zbyt wiele prób. Wyłączono uwierzytelnianie za pomocą twarzy."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Spróbuj ponownie."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nie zarejestrowano twarzy."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"To urządzenie nie jest wyposażone w czujnik twarzy."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Twarz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1253,9 +1286,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Otwórz aplikację <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"Aplikacja <xliff:g id="OLD_APP">%1$s</xliff:g> zostanie zamknięta bez zapisywania"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> przekroczył limit pamięci"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Pobrano zrzut sterty – kliknij, by go udostępnić"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Udostępnić zrzut stosu?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> przekroczył swój limit pamięci, który wynosi <xliff:g id="SIZE">%2$s</xliff:g>. Możesz udostępnić zrzut stosu programiście procesu. Uwaga: ten zrzut może zawierać wszelkie dane osobowe, do których aplikacja ma dostęp."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Wybierz czynność, jaka ma zostać wykonana na tekście"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Głośność dzwonka"</string>
     <string name="volume_music" msgid="5421651157138628171">"Głośność multimediów"</string>
@@ -1298,8 +1338,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Kliknij, by zobaczyć wszystkie sieci"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Połącz"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Wszystkie sieci"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Sieć Wi‑Fi sugerowana przez użytkownika <xliff:g id="NAME">%s</xliff:g> jest dostępna"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Czy chcesz połączyć się z sieciami sugerowanymi przez użytkownika <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Tak"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nie"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi włączy się automatycznie"</string>
@@ -1311,9 +1353,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Zaloguj się do sieci"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Sieć Wi-Fi nie ma dostępu do internetu"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Kliknij, by wyświetlić opcje"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Połączono"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Zmieniono ustawienia hotspotu"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Zmieniono pasmo hotspotu."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"To urządzenie nie może korzystać tylko z częstotliwości 5 GHz. Będzie korzystać z tego pasma, jeśli będzie ono dostępne."</string>
@@ -1398,6 +1445,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Kliknij, by wyłączyć debugowanie USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Wilgoć lub brud w porcie USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB został automatycznie wyłączony. Kliknij, by dowiedzieć się więcej."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Możesz bezpiecznie korzystać z portu USB"</string>
@@ -1973,8 +2024,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Kliknij, by odblokować profil"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Połączono z: <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dotknij, by wyświetlić pliki"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Przypnij"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Odepnij"</string>
     <string name="app_info" msgid="6856026610594615344">"O aplikacji"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Uruchamiam tryb demo…"</string>
@@ -2067,6 +2116,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Powiadomienie z informacją o trybie rutynowym"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Bateria może się wyczerpać przed zwykłą porą ładowania"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Włączono Oszczędzanie baterii, by wydłużyć czas pracy na baterii"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folder"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplikacja na Androida"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Plik"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 9a078f8..ae01cfb 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Chamada no Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferido"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferência pela rede móvel"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Somente Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não encaminhado"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de bugs"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Finalizar sessão"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de tela"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Obter relatório de bugs"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Isto coletará informações sobre o estado atual do dispositivo para enviá-las em uma mensagem de e-mail. Após iniciar o relatório de bugs, será necessário aguardar algum tempo até que esteja pronto para ser enviado."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Relatório interativo"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Use este recurso na maioria das circunstâncias. Ele permite que você acompanhe o progresso do relatório, informe mais detalhes sobre o problema e faça capturas de tela. É possível que ele omita algumas seções menos utilizadas que levam muito tempo na emissão dos relatórios."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Local"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"acesse o local do dispositivo"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse a localização deste dispositivo?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"O app só terá acesso ao local enquanto estiver sendo usado."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Sempre permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse o local deste disp.?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"O app sempre terá acesso ao local, mesmo quando não estiver sendo usado."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acesse sua agenda"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse sua agenda?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Permitir que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse suas músicas?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotos e vídeos"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"acessar suas fotos e seus vídeos"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Permitir que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse seus vídeos e fotos, incluindo os locais marcados?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Acessar conteúdo de uma janela"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspeciona o conteúdo de uma janela com a qual você está interagindo."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar por toque"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Permite que o app se comunique com leitores, cartões e etiqueta NFC (comunicação a curta distância)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desativar o bloqueio de tela"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite que o app desative o bloqueio de teclas e qualquer segurança por senha associada. Por exemplo, o telefone desativa o bloqueio de telas ao receber uma chamada e o reativa quando a chamada é finalizada."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"solicitar complexidade do bloqueio de tela"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Permite que o app saiba o nível de complexidade do bloqueio de tela (alto, médio, baixo ou nenhum), que indica o intervalo possível de comprimento e o tipo de bloqueio de tela. O app também pode sugerir a atualização do bloqueio de tela até um certo nível, mas os usuários podem ignorar a sugestão. O bloqueio de tela não é armazenado em texto simples, então o app não tem acesso à senha exata."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"Usar hardware de biometria"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que o app use hardware de biometria para autenticação"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gerenciar hardware de impressão digital"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que o app execute métodos para adicionar e excluir modelos de rosto para uso."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"usar hardware de autenticação facial"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Permite que o app use o hardware de autenticação facial para autenticação"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Falha ao processar o rosto. Tente novamente."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Rosto muito iluminado. Tente com menos iluminação."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Rosto muito escuro. Acrescente uma fonte de luz."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Afaste o sensor do rosto."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Aproxime o sensor do rosto."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Mova o sensor para cima."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Mova o sensor para baixo."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Mova o sensor para a direita."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Mova o sensor para a esquerda."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Olhe para o sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nenhum rosto detectado."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Muito movimento."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registre seu rosto novamente."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Rosto diferente detectado."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Muito parecido, mude de posição."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Olhe mais diretamente para a câmera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Olhe mais diretamente para a câmera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Alinhe sua cabeça na vertical."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Descubra seu rosto."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardware de rosto não disponível."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Tempo máx. p/ captura facial atingido. Tente novamente."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Não é possível armazenar um rosto."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operação facial cancelada."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticação facial cancelada pelo usuário."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Excesso de tentativas. Tente novamente mais tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Excesso de tentativas. Autenticação facial desat."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Tente novamente."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nenhum rosto registrado."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Este dispositivo não tem um sensor de autenticação facial."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Abrir <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"O app <xliff:g id="OLD_APP">%1$s</xliff:g> será fechado sem salvar"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> excedeu o limite de memória"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"O despejo de heap foi coletado. Toque para compartilhar."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Compartilhar despejo de heap?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"O processo <xliff:g id="PROC">%1$s</xliff:g> excedeu seu limite de memória de <xliff:g id="SIZE">%2$s</xliff:g>. Um despejo de heap está disponível para compartilhamento com o desenvolvedor. Tenha cuidado: esse despejo de heap pode conter informações pessoais às quais o aplicativo tem acesso."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Escolha uma ação para o texto"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volume da campainha"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volume da mídia"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Uma rede Wi‑Fi sugerida por <xliff:g id="NAME">%s</xliff:g> está disponível"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Você quer se conectar às redes sugeridas por <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sim"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Não"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"O Wi‑Fi será ativado automaticamente"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"O Wi‑Fi não tem acesso à Internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Toque para ver opções"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Conectado"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Mudanças nas suas configurações de ponto de acesso"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Sua banda de ponto de acesso foi alterada."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Este dispositivo não é compatível com sua preferência apenas por 5 GHz. Em vez disso, o dispositivo usará a banda de 5 GHz quando ela estiver disponível."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Toque para desativar a depuração USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou detrito na porta USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é desativada automaticamente. Toque para saber mais."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"É seguro usar a porta USB"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Toque p/ desbl. perfil de trab."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toque para ver os arquivos"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Fixar guia"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Liberar guia"</string>
     <string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demonstração…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notificação de informação do modo rotina"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"A bateria pode acabar antes da recarga normal"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"A \"Economia de bateria\" foi ativada para aumentar a duração da carga"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Pasta"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplicativo Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Arquivo"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 9a078f8..ae01cfb 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Chamada no Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferido"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferência pela rede móvel"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Somente Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não encaminhado"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de bugs"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Finalizar sessão"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de tela"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Obter relatório de bugs"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Isto coletará informações sobre o estado atual do dispositivo para enviá-las em uma mensagem de e-mail. Após iniciar o relatório de bugs, será necessário aguardar algum tempo até que esteja pronto para ser enviado."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Relatório interativo"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Use este recurso na maioria das circunstâncias. Ele permite que você acompanhe o progresso do relatório, informe mais detalhes sobre o problema e faça capturas de tela. É possível que ele omita algumas seções menos utilizadas que levam muito tempo na emissão dos relatórios."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Local"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"acesse o local do dispositivo"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse a localização deste dispositivo?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"O app só terá acesso ao local enquanto estiver sendo usado."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Sempre permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse o local deste disp.?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"O app sempre terá acesso ao local, mesmo quando não estiver sendo usado."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acesse sua agenda"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse sua agenda?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Permitir que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse suas músicas?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotos e vídeos"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"acessar suas fotos e seus vídeos"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Permitir que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acesse seus vídeos e fotos, incluindo os locais marcados?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Acessar conteúdo de uma janela"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspeciona o conteúdo de uma janela com a qual você está interagindo."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar por toque"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Permite que o app se comunique com leitores, cartões e etiqueta NFC (comunicação a curta distância)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desativar o bloqueio de tela"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite que o app desative o bloqueio de teclas e qualquer segurança por senha associada. Por exemplo, o telefone desativa o bloqueio de telas ao receber uma chamada e o reativa quando a chamada é finalizada."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"solicitar complexidade do bloqueio de tela"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Permite que o app saiba o nível de complexidade do bloqueio de tela (alto, médio, baixo ou nenhum), que indica o intervalo possível de comprimento e o tipo de bloqueio de tela. O app também pode sugerir a atualização do bloqueio de tela até um certo nível, mas os usuários podem ignorar a sugestão. O bloqueio de tela não é armazenado em texto simples, então o app não tem acesso à senha exata."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"Usar hardware de biometria"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite que o app use hardware de biometria para autenticação"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gerenciar hardware de impressão digital"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que o app execute métodos para adicionar e excluir modelos de rosto para uso."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"usar hardware de autenticação facial"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Permite que o app use o hardware de autenticação facial para autenticação"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Falha ao processar o rosto. Tente novamente."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Rosto muito iluminado. Tente com menos iluminação."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Rosto muito escuro. Acrescente uma fonte de luz."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Afaste o sensor do rosto."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Aproxime o sensor do rosto."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Mova o sensor para cima."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Mova o sensor para baixo."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Mova o sensor para a direita."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Mova o sensor para a esquerda."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Olhe para o sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nenhum rosto detectado."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Muito movimento."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registre seu rosto novamente."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Rosto diferente detectado."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Muito parecido, mude de posição."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Olhe mais diretamente para a câmera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Olhe mais diretamente para a câmera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Alinhe sua cabeça na vertical."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Descubra seu rosto."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardware de rosto não disponível."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Tempo máx. p/ captura facial atingido. Tente novamente."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Não é possível armazenar um rosto."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operação facial cancelada."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Autenticação facial cancelada pelo usuário."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Excesso de tentativas. Tente novamente mais tarde."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Excesso de tentativas. Autenticação facial desat."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Tente novamente."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nenhum rosto registrado."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Este dispositivo não tem um sensor de autenticação facial."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Abrir <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"O app <xliff:g id="OLD_APP">%1$s</xliff:g> será fechado sem salvar"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> excedeu o limite de memória"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"O despejo de heap foi coletado. Toque para compartilhar."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Compartilhar despejo de heap?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"O processo <xliff:g id="PROC">%1$s</xliff:g> excedeu seu limite de memória de <xliff:g id="SIZE">%2$s</xliff:g>. Um despejo de heap está disponível para compartilhamento com o desenvolvedor. Tenha cuidado: esse despejo de heap pode conter informações pessoais às quais o aplicativo tem acesso."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Escolha uma ação para o texto"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volume da campainha"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volume da mídia"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Uma rede Wi‑Fi sugerida por <xliff:g id="NAME">%s</xliff:g> está disponível"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Você quer se conectar às redes sugeridas por <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sim"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Não"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"O Wi‑Fi será ativado automaticamente"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"O Wi‑Fi não tem acesso à Internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Toque para ver opções"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Conectado"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Mudanças nas suas configurações de ponto de acesso"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Sua banda de ponto de acesso foi alterada."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Este dispositivo não é compatível com sua preferência apenas por 5 GHz. Em vez disso, o dispositivo usará a banda de 5 GHz quando ela estiver disponível."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Toque para desativar a depuração USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou detrito na porta USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é desativada automaticamente. Toque para saber mais."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"É seguro usar a porta USB"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Toque p/ desbl. perfil de trab."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toque para ver os arquivos"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Fixar guia"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Liberar guia"</string>
     <string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iniciando demonstração…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notificação de informação do modo rotina"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"A bateria pode acabar antes da recarga normal"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"A \"Economia de bateria\" foi ativada para aumentar a duração da carga"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Pasta"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplicativo Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Arquivo"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 63b3411..ad08ca4 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -142,8 +142,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Apelare prin Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Dezactivată"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Se preferă conexiunea Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Se preferă datele mobile"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Numai Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: neredirecționată"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -230,7 +232,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Raport despre erori"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Încheiați sesiunea"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captură de ecran"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Executați un raport despre erori"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Acest raport va colecta informații despre starea actuală a dispozitivului, pentru a le trimite într-un e-mail. Aveți răbdare după pornirea raportului despre erori până când va fi gata de trimis."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Raport interactiv"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Folosiți această opțiune în majoritatea situațiilor. Astfel, puteți să urmăriți progresul raportului, să introduceți mai multe detalii în privința problemei și să creați capturi de ecran. Pot fi omise unele secțiuni mai puțin folosite pentru care raportarea durează prea mult."</string>
@@ -284,9 +287,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Locație"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"acceseze locația acestui dispozitiv"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să acceseze locația acestui dispozitiv?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplicația va avea acces la locație doar atunci când o folosiți."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să acceseze locația dispozitivului?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplicația va avea în permanență acces la locație, chiar și atunci când nu o folosiți."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceseze calendarul"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să vă acceseze calendarul?"</string>
@@ -319,7 +325,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să vă acceseze muzica?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotografii și videoclipuri"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"accesați fotografiile și videoclipurile"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Permiteți aplicației &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să acceseze fotografiile și videoclipurile, inclusiv locațiile etichetate?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Analizează conținutul ferestrei"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspectează conținutul unei ferestre cu care interacționați."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activează funcția Explorați prin atingere"</string>
@@ -512,8 +521,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Permite aplicației să comunice cu etichetele, cardurile și cititoarele NFC (Near Field Communication)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"dezactivează blocarea ecranului"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite aplicației să dezactiveze blocarea tastelor și orice modalitate asociată de securizare prin parolă. De exemplu, telefonul dezactivează blocarea tastelor când se primește un apel telefonic și reactivează blocarea tastelor la terminarea apelului."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"solicitați complexitatea blocării ecranului"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Permite aplicației să învețe nivelul de complexitate al blocării ecranului (ridicat, mediu, scăzut sau fără) ce indică intervalul posibil de lungime a parolei și tipul de blocare a ecranului. Aplicația le poate sugera utilizatorilor să își actualizeze blocarea ecranului la un anumit nivel, dar utilizatorii pot ignora sugestia și pot naviga în continuare. Rețineți că blocarea ecranului nu este stocată ca text simplu, astfel încât aplicația să nu cunoască parola exactă."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"utilizați hardware biometric"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Permite aplicației să folosească hardware biometric pentru autentificare"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gestionează hardware-ul pentru amprentă"</string>
@@ -568,37 +579,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite aplicației să invoce metode pentru a adăuga și a șterge șabloane faciale pentru utilizare."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"să folosească hardware de autentificare facială"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Permite aplicației să folosească hardware de autentificare facială pentru autentificare"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Chipul nu a putut fi procesat. Încercați din nou."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Chip prea luminat. Încercați cu mai puțină lumină."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Chip prea întunecat. Măriți sursa de lumină."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Deplasați senzorul mai departe de chip."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Aduceți senzorul mai aproape de chip."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Deplasați senzorul mai sus."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Deplasați senzorul mai jos."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Deplasați senzorul spre dreapta."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Deplasați senzorul spre stânga."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Priviți spre senzor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nu s-a detectat niciun chip."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Prea multă mișcare."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Reînregistrați-vă chipul."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"A fost detectat un chip diferit."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Prea asemănător, schimbați poziția."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Priviți mai direct spre cameră."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Priviți mai direct spre cameră."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Îndreptați capul pe verticală."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Descoperiți-vă chipul."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hardware-ul pentru chip nu este disponibil."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Timpul pentru reunoaștere facială a expirat. Încercați din nou."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Chipul nu poate fi stocat."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operațiunea privind chipul a fost anulată."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Autentificarea chipului anulată de utilizator."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Prea multe încercări. Reîncercați mai târziu."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Prea multe încercări. Autentificarea facială este dezactivată."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Încercați din nou."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nu au fost înregistrate chipuri."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Dispozitivul nu are un senzor de autentificare a chipului."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Chip <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1233,9 +1266,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Deschideți <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> se va închide fără să salveze"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> a depășit limita de memorie"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Datele privind memoria au fost culese. Atingeți pentru a trimite."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Trimiteți datele privind memoria?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Procesul <xliff:g id="PROC">%1$s</xliff:g> și-a depășit limita de memorie de <xliff:g id="SIZE">%2$s</xliff:g>. Sunt disponibile datele privind memoria, pe care le puteți trimite dezvoltatorului. Atenție: aceste date privind memoria pot conține informațiile personale la care aplicația are acces."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Alegeți o acțiune pentru text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volum sonerie"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volum media"</string>
@@ -1276,8 +1316,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Atingeți pentru a vedea toate rețelele"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectați-vă"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Toate rețelele"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Este disponibilă o rețea propusă de <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Doriți să vă conectați la rețelele propuse de <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nu"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi se va activa automat"</string>
@@ -1289,9 +1331,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Conectați-vă la rețea"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Rețeaua Wi-Fi nu are acces la internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Atingeți pentru opțiuni"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Conectat"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Modificări aduse setărilor pentru hotspot"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"S-a schimbat banda de frecvență a hotspotului."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Dispozitivul nu acceptă doar preferința pentru 5 GHz. Dispozitivul va folosi banda de 5 GHz când este disponibilă."</string>
@@ -1376,6 +1423,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Remedierea erorilor prin USB este conectată"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Atingeți pentru a dezactiva remedierea erorilor prin USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selectați pentru a dezactiva remedierea erorilor prin USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Lichide sau reziduuri în portul USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Portul USB este dezactivat automat. Atingeți ca să aflați mai multe."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Portul USB poate fi folosit în siguranță"</string>
@@ -1939,8 +1990,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Atingeți ca să deblocați"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectat la <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Atingeți pentru a vedea fișierele"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Fixați"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Anulați fixarea"</string>
     <string name="app_info" msgid="6856026610594615344">"Informații despre aplicație"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Se pornește demonstrația…"</string>
@@ -2032,6 +2081,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notificare pentru informații despre modul Rutină"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Bateria se poate descărca înainte de încărcarea obișnuită"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Economisirea bateriei este activată pentru a prelungi durata de funcționare a bateriei"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Dosar"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplicație Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fișier"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 0aed6bc..ae9d483 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -143,8 +143,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Звонки по Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Отключено"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Приоритет Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Приоритет мобильного Интернета"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Только Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не переадресовано"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -232,7 +234,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Отчет об ошибке"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Закончить сеанс"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Скриншот"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Отчет об ошибке"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Информация о текущем состоянии вашего устройства будет собрана и отправлена по электронной почте. Подготовка отчета займет некоторое время."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактивный отчет"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Рекомендуем этот вариант в большинстве случаев, чтобы отслеживать статус отчета, указывать дополнительные данные о проблеме и делать скриншоты. Некоторые разделы могут быть исключены, чтобы сократить время подготовки отчета."</string>
@@ -287,9 +290,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Местоположение"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"доступ к данным о местоположении устройства"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к данным о местоположении устройства?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Доступ будет открыт, только когда вы пользуетесь приложением."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Всегда разрешать приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к геоданным устройства?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Доступ будет открыт, даже когда вы не пользуетесь приложением."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календарь"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"доступ к календарю"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к календарю?"</string>
@@ -322,7 +328,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к музыке?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Фото и видео"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"доступ к фото и видео"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Открыть приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к вашим фото и видео, а также к данным о местах съемки?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Получать содержимое окна"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Анализировать содержимое активного окна."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Включать Изучение касанием"</string>
@@ -515,8 +524,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Приложение сможет обмениваться данными с NFC-метками, картами и устройствами считывания, используя NFC."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Отключение функции блокировки экрана"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Приложение сможет отключать блокировку экрана и другие функции защиты. Например, блокировка экрана будет отключаться при получении входящего вызова и включаться после завершения разговора."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"Запрос данных об уровне сложности блокировки экрана"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Приложение получит доступ к сведениям об уровне сложности блокировки экрана (высокий, средний, низкий или не задан), в том числе о типе блокировки и длине пароля. Кроме того, оно сможет предлагать пользователям повысить уровень сложности блокировки. Эти рекомендации необязательны. Обратите внимание, что пароль не хранится в виде открытого текста и недоступен приложению."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"Использование биометрического оборудования"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Приложение сможет использовать биометрическое оборудование для аутентификации"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управление сканером отпечатков"</string>
@@ -571,37 +582,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Приложение сможет добавлять и удалять шаблоны лиц."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"Использовать оборудование для распознавания лиц"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Приложение сможет использовать распознающее оборудование для аутентификации."</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Не удалось распознать лицо. Повторите попытку."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Лицо слишком яркое. Притушите свет."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Лицо слишком темное. Сделайте свет ярче."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Уберите устройство дальше от лица"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Поднесите устройство ближе к лицу"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Поднимите устройство выше"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Опустите устройство ниже"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Сдвиньте устройство правее"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Сдвиньте устройство левее"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Посмотрите в камеру устройства"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Лица не обнаружены"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Не перемещайте устройство."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Повторите попытку."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Обнаружено другое лицо."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Слишком похожее выражение лица. Измените позу."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Смотрите прямо в камеру."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Смотрите прямо в камеру."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Выровняйте голову по вертикали."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Откройте лицо."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Оборудование для распознавания лица недоступно"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Превышено время ожидания. Повторите попытку."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Невозможно сохранить распознанное лицо"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Распознавание отменено"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Распознавание лица отменено пользователем."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Слишком много попыток. Повторите позже."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Слишком много попыток. Сканер отключен."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Попробуйте ещё раз"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Нет зарегистрированных лиц"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"На этом устройстве нет сканера для распознавания лица."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Лицо <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1253,9 +1286,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Открыть приложение \"<xliff:g id="NEW_APP">%1$s</xliff:g>\""</string>
     <string name="new_app_description" msgid="5894852887817332322">"Приложение \"<xliff:g id="OLD_APP">%1$s</xliff:g>\" будет закрыто без сохранения."</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Объем памяти процесса \"<xliff:g id="PROC">%1$s</xliff:g>\" превышен"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Создан дамп кучи. Нажмите, чтобы отправить его."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Отправить дамп кучи?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Процесс \"<xliff:g id="PROC">%1$s</xliff:g>\" превысил объем памяти (<xliff:g id="SIZE">%2$s</xliff:g>). При необходимости отправьте созданный дамп кучи разработчику. Обратите внимание, что файл может содержать личные данные, доступные приложению."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Выберите действие для текста"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Громкость звонка"</string>
     <string name="volume_music" msgid="5421651157138628171">"Громкость мультимедиа"</string>
@@ -1298,8 +1338,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Нажмите, чтобы увидеть список сетей"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Подключиться"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Все сети"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Доступна сеть Wi-Fi, найденная приложением \"<xliff:g id="NAME">%s</xliff:g>\""</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Подключиться к сетям, найденным приложением \"<xliff:g id="NAME">%s</xliff:g>\"?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Нет"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi включится автоматически"</string>
@@ -1311,9 +1353,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Регистрация в сети"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Сеть Wi-Fi не подключена к Интернету"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Нажмите, чтобы показать варианты."</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Подключено"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Изменения в настройках точки доступа"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Частота точки доступа изменена."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Устройство не может работать только на частоте 5 ГГц. Эта частота будет использоваться, когда это возможно."</string>
@@ -1398,6 +1445,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Нажмите, чтобы отключить отладку по USB."</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку по USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"В USB-порт попала вода или грязь"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт был автоматически отключен. Нажмите, чтобы узнать подробности."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Можно использовать USB-порт"</string>
@@ -1440,8 +1491,7 @@
     <string name="ext_media_init_action" msgid="7952885510091978278">"Настроить"</string>
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"Извлечь"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"Обзор"</string>
-    <!-- no translation found for ext_media_seamless_action (6575980560886881233) -->
-    <skip />
+    <string name="ext_media_seamless_action" msgid="6575980560886881233">"Сменить устройство вывода"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> не найден"</string>
     <string name="ext_media_missing_message" msgid="4012389235250987930">"Подключите накопитель снова."</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Перенос приложения <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1974,8 +2024,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Нажмите, чтобы разблокировать раб. профиль"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Подключено к <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Нажмите, чтобы просмотреть файлы"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Закрепить"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Открепить"</string>
     <string name="app_info" msgid="6856026610594615344">"О приложении"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Запуск деморежима…"</string>
@@ -2068,6 +2116,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Уведомление о батарее"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Батарея может разрядиться"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Чтобы увеличить время работы от батареи, был включен режим энергосбережения."</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Папка"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Приложение Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Файл"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index cc6087a..2eeaad6 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi ඇමතීම"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ක්‍රියාවිරහිතයි"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi වඩා කැමතියි"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ජංගම කැමතියි"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi පමණයි"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ඉදිරියට නොයවන ලදි"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"දෝෂ වර්තාව"</string>
     <string name="global_action_logout" msgid="935179188218826050">"සැසිය අවසන් කරන්න"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"තිර රුව"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"දෝෂ වාර්තාවක් ගන්න"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"ඊ-තැපැල් පණිවිඩයක් ලෙස යැවීමට මෙය ඔබගේ වත්මන් උපාංග තත්වය ගැන තොරතුරු එකතු කරනු ඇත. දෝෂ වාර්තාව ආරම්භ කර එය යැවීමට සූදානම් කරන තෙක් එයට කිසියම් කාලයක් ගතවනු ඇත; කරුණාකර ඉවසන්න."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"අන්තර්ක්‍රියා වාර්."</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"බොහොමයක් වාතාවරණ යටතේ මෙය භාවිත කරන්න. එය ඔබට වාර්තාවේ ප්‍රගතිය හඹා යාමට, ගැටලුව පිළිබඳ වැඩි විස්තර ඇතුළත් කිරීමට, සහ තිර රූ ගැනීමට ඉඩ දෙයි. එය වාර්තා කිරීමට දිගු වේලාවක් ගන්නා සමහර අඩුවෙන්-භාවිත වන කොටස් මග හැරීමට හැකිය."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"ස්ථානය"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"මෙම උපාංගයේ ස්ථානයට ප්‍රවේශ කරන්න"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; වෙත මෙම උපාංගයේ ස්ථානය ලබා ගැනීමට ඉඩ දෙන්නද?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"ඔබ යෙදුම භාවිතා විට පමණක් යෙදුමට ස්ථානයට ප්‍රවේශය ඇත."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; වෙත මෙම උපාංගයේ ස්ථානය ලබා ගැනීමට සැම විට ඉඩ දෙන්නද?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"ඔබ යෙදුම භාවිතා නොකරන විට පවා යෙදුමට සැම විටම ස්ථානයට ප්‍රවේශය ඇත."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"දින දර්ශනය"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ඔබේ දින දර්ශනයට පිවිසෙන්න"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; වෙත ඔබගේ දින දර්ශනය ප්‍රවේශ කිරීමට ඉඩ දෙන්නද?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; හට ඔබගේ දින දර්ශනය වෙත පිවිසීමට ඉඩ දෙන්නද?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ඡායාරූප සහ වීඩියෝ"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"ඔබගේ ඡායාරූප සහ වීඩියෝ වෙත පිවිසෙන්න"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; හට ටැග් කළ ස්ථාන ඇතුළුව, ඔබේ ඡායාරූප සහ වීඩියෝවලට ප්‍රවේශයට ඉඩ දෙන්න ද?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"කවුළු අන්න්තර්ගතය ලබාගන්න"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ඔබ අන්තර්ක්‍රියාකාරී වන කවුළුවේ අන්තර්ගතය පරීක්ෂා කරන්න."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ස්පර්ශයෙන් ගවේෂණය සක්‍රිය කරන්න"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"ආසන්න ක්ෂේත්‍ර සන්නිවේදන (NFC) ටැග්, පත්, සහ කියවන්නන් සමඟ සන්නිවේදනය කිරීමට යෙදුමට අවසර දෙන්න."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ඔබගේ තිරයේ අගුල අබල කරන්න"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"යතුරු අගුල සහ ඕනෑම සම්බන්ධිත මුරපද ආරක්ෂාවක් අබල කිරීමට යෙදුමට අවසර දෙන්න. මෙහි උදාහරණයක් වන්නේ පැමිණෙන ඇමතුමක් ලැබෙද්දී, දුරකථනය අක්‍රිය වන අතර ඇමතුම අවසාන වන විට යතුරු අගුල නැවත සක්‍රිය වෙයි."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"තිර අගුළු සංකීර්ණතාව ඉල්ලන්න"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"යෙදුමට තිර අගුලෙහි තිබිය හැකි දිගෙහි පරාසය සහ වර්ගය පිළිබිඹු කරන, තිර අඟුළු සංකීර්ණතා මට්ටම (ඉහළ, මධ්‍යම, අඩු හෝ රහිත) දැන ගැනීමට ඉඩ දෙයි. යෙදුම පරිශීලකයින්ට තිර අගුල නිශ්චිත මට්ටමකට යාවත්කාලීන කිරීමට යෝජනා කළ හැකි නමුත් ඔවුන්ට නිදහසේ නොසලකා හැර ඉවතට සංචාලනය කළ හැකිය. තිර අගුල සරල පෙළින් ගබඩා කර නැති බැවින් යෙදුම නිවැරදි මුරපදය නොදන්නා බව සලකන්න."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ජීවමිතික දෘඪාංග භාවිත කරන්න"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"සත්‍යාපනය සඳහා ජීවමිතික දෘඪාංග භාවිත කිරීමට යෙදුමට ඉඩ දෙයි"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"ඇඟිලි සලකුණු දෘඩාංග කළමනාකරණය කිරීම."</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"මුහුණු අච්චු එකතු කිරීමට සහ ඉවත් කිරීමට අදාළ ක්‍රම භාවිතය සඳහා මෙම යෙදුමට ඉඩ දෙයි."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"මුහුණු සත්‍යාපක දෘඪාංග භාවිතා කරන්න"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"සත්‍යාපනය සඳහා සත්‍යාපක දෘඪාංග භාවිත කිරීමට යෙදුමට ඉඩ දෙයි"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"මුහුණ සැකසීමට නොහැකි විය. කරුණාකර නැවත උත්සාහ කර."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"මුහුණ දීප්තිමත් වැඩිය. කරුණාකර අඩු ආලෝකය උත්සාහ කරන්න."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"මුහුණ අඳුරු වැඩිය. කරුණාර ආලෝක ප්‍රභවය නිරාවරණය කරන්න."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"කරුණාකර සංවේදකය මුහුණෙන් වඩා ඈත් කරන්න."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"කරුණාකර සංවේදකය මුහුණ සමීපයට ගෙන එන්න."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"කරුණාකර සංවේදකය ඉහළට ගෙන යන්න."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"කරුණාකර සංවේදකය පහළට ගෙන යන්න."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"කරුණාකර සංවේදකය දකුණට ගෙන යන්න."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"කරුණාකර සංවේදකය වමට ගෙන යන්න."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"කරුණාකර සංවේදකය දෙස බලන්න."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"මුහුණ අනාවරණය කර නොගන්නා ලදී."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"චලනය ඉතා වැඩියි."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ඔබේ මුහුණ යළි ලියාපදිංචි කරන්න."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"වෙනත් මුහුණක් අනාවරණ විය."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ඉතා සමානයි, ඔබේ හැඩ ගැසීම වෙනස් කරන්න."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"කැමරාව වෙත තවත් ඍජුව බලන්න."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"කැමරාව වෙත තවත් ඍජුව බලන්න."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"ඔබේ හිස සිරස් ආකාරයේ කෙළින් කරන්න."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"ඔබේ මුහුණ අරින්න."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"මුහුණු දෘඪාංගය ලද නොහැකිය."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"මුහුණු කාල නිමාව ළඟා විය. නැවත උත්සාහ කරන්න."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"මුහුණ ගබඩා කළ නොහැක."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"මුහුණු මෙහෙයුම අවලංගු කරන ලදී."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"පරිශීලකයා විසින් මුහුණ සත්‍යාපනය අවලංගු කරන ලදී."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"උත්සාහයන් ඉතා වැඩි ගණනකි. පසුව නැවත උත්සාහ කරන්න."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"උත්සාහයන් ඉතා වැඩි ගණනකි. මුහුණු සත්‍යාපනය අබල කරන ලදී."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"නැවත උත්සාහ කරන්න."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"මුහුණක් ඇතුළත් කර නොමැත."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"මෙම උපාංගයේ මුහුණු සත්‍යාපන සංවේදකයක් නැත."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"මුහුණු <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1215,9 +1248,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> විවෘත කරන්න"</string>
     <string name="new_app_description" msgid="5894852887817332322">"සුරැකීමෙන් තොරව <xliff:g id="OLD_APP">%1$s</xliff:g> වැසෙනු ඇත"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> මතකයේ සීමාව ඉක්මවා ඇත"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"ඉවත දැමීම් ගොඩ රැස් කරන ලදී. බෙදා ගැනීමට තට්ටු කරන්න"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"සංච නික්ෂේපය බෙදාගන්න ද?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> ක්‍රියාවලිය එහි ක්‍රියාවලියේ <xliff:g id="SIZE">%2$s</xliff:g> මතකය ඉක්මවා ඇත. ඔබට එහි වර්ධකයන් සමග බෙදාගැනීමට සංච නික්ෂේපයක් ඇත. ප්‍රවේසම් වන්න: මෙම යෙදුම පිවිසිය හැකි ඔබගේ පෞද්ගලික තොරතුරු මෙම සංච නික්ෂේපයෙහි අඩංගු වී තිබිය හැකිය."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"පෙළ සඳහා ක්‍රියාව තෝරන්න"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"හඬ නඟනයේ ශබ්දය"</string>
     <string name="volume_music" msgid="5421651157138628171">"මාධ්‍ය ශබ්දය"</string>
@@ -1256,8 +1296,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"සියලු ජාල බැලීමට තට්ටු කරන්න"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"සම්බන්ධ කරන්න"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"සියලු ජාල"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> විසින් යෝජිත Wi-Fi ජාලයක් ලැබේ"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"ඔබට <xliff:g id="NAME">%s</xliff:g> විසින් යෝජනා කරනු ලබන ජාල වෙත සම්බන්ධ කිරීමට අවශ්‍යද?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ඔව්"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"නැත"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ස්වයංක්‍රියව ක්‍රියාත්මක වනු ඇත"</string>
@@ -1269,9 +1311,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ජාලයට පුරනය වන්න"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi සඳහා අන්තර්ජාල ප්‍රවේශය නැත"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"විකල්ප සඳහා තට්ටු කරන්න"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"සම්බන්ධයි"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"ඔබගේ හොට්ස්පොට් සැකසීම්වලට වෙනස් කිරීම්"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"ඔබගේ හොට්ස්පොට් කලාපය වෙනස් වී ඇත."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"මෙම උපාංගය 5GHz සඳහා ඔබේ මනාපවලට සහාය නොදක්වයි. ඒ වෙනුවට, මෙම උපාංගය ලබා ගත හැකි විට 5GHz කලාපය භාවිතා කරනු ඇත."</string>
@@ -1356,6 +1403,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB නිදොස් කිරීම ක්‍රියාවිරහිත කිරීමට තට්ටු කරන්න"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB තොට තුළ ද්‍රව හෝ කුණු"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB තොට ස්වයංක්‍රීයව අබල කෙරේ. තවත් දැන ගැනීමට තට්ටු කරන්න."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB තොට භාවිත කිරීම ආරක්‍ෂිතයි"</string>
@@ -1907,8 +1958,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"කාර්යාල පැතිකඩ අගුලු හැරීමට තට්ටු කරන්න"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> වෙත සම්බන්ධ විය"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ගොනු බැලීමට තට්ටු කරන්න"</string>
-    <string name="pin_target" msgid="3052256031352291362">"අමුණන්න"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"ගලවන්න"</string>
     <string name="app_info" msgid="6856026610594615344">"යෙදුම් තොරතුරු"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ආදර්ශනය ආරම්භ කරමින්..."</string>
@@ -1999,6 +2048,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"දිනචරියා ප්‍රකාර තතු දැනුම්දීම"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"බැටරිය සුපුරුදු ආරෝපණයට පෙර ඉවර විය හැක"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"බැටරි සුරැකුම බැටරි ආයු කාලය දීර්ඝ කිරීමට සක්‍රිය කෙරිණි"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ෆෝල්ඩරය"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android යෙදුම"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ගොනුව"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 067165b..d776d0a 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -143,8 +143,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Klicanje prek Wi-Fi-ja"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"Govor prek Wi-Fi-ja"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Izklopljeno"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednostno Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Prednostno mobilno"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ni posredovano"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -232,7 +234,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Poročilo o napakah"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Končaj sejo"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Posnetek zaslona"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Ustvari poročilo o napakah"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"S tem bodo zbrani podatki o trenutnem stanju naprave, ki bodo poslani v e-poštnem sporočilu. Izvedba poročila o napakah in priprava trajata nekaj časa, zato bodite potrpežljivi."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktivno poročilo"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"To možnost uporabite v večini primerov. Omogoča spremljanje poteka poročila, vnos več podrobnosti o težavi in snemanje posnetkov zaslona. Morda bodo izpuščeni nekateri redkeje uporabljani razdelki, za katere je poročanje dolgotrajno."</string>
@@ -287,9 +290,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"dostop do lokacije te naprave"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Želite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; omogočiti dostop do lokacije te naprave?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplikacija bo imela dostop do lokacije samo, ko aplikacijo uporabljate."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Želite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; vedno dovoliti dostop do lokacije te naprave?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplikacija bo vedno imela dostop do lokacije, tudi ko aplikacije ne uporabljate."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Koledar"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostop do koledarja"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Želite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; omogočiti dostop do koledarja?"</string>
@@ -322,7 +328,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Želite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; omogočiti dostop do glasbe?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotografije in videoposnetki"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"dostop do fotografij in videoposnetkov"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Želite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; omogočiti dostop do fotografij, videoposnetkov in v njih označenih lokacij?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pridobiti vsebino okna"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Preverjanje vsebine okna, ki ga uporabljate."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vklopiti raziskovanje z dotikom"</string>
@@ -515,8 +524,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Podpira komunikacijo med računalnikom in oznakami, karticami in bralniki komunikacije s tehnologijo bližnjega polja."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogočanje zaklepanja zaslona"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Aplikaciji dovoljuje, da onemogoči zaklep tipkovnice in morebitno povezano varnostno geslo. Telefon na primer onemogoči zaklep tipkovnice pri dohodnem klicu ter vnovič omogoči zaklep, ko je klic končan."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"zahteva zapletenost zaklepanja zaslona"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Aplikaciji dovoljuje, da pridobi raven zapletenosti zaklepanja zaslona (visoka, srednja, nizka ali brez), ki označuje možen obseg dolžine in vrsto zaklepanja zaslona. Aplikacija lahko tudi predlaga uporabnikom, da posodobijo zaklepanje zaslona na določeno raven, vendar lahko uporabniki to opozorilo prezrejo in ga zaprejo tako, da se pomaknejo stran. Upoštevajte, da zaklepanje zaslona ni shranjeno v navadnem besedilu, tako da aplikacija ne pozna točnega gesla."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"uporaba strojne opreme za biometrične podatke"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Aplikaciji omogoča uporabo strojne opreme za biometrične podatke za preverjanje pristnosti"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljanje strojne opreme za prstne odtise"</string>
@@ -571,37 +582,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Aplikaciji omogoča sprožanje načinov za dodajanje in brisanje predlog z obrazi za uporabo."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"uporaba strojne opreme za preverjanje pristnosti obraza"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Aplikaciji omogoča uporabo strojne opreme za preverjanje pristnosti obraza"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Obraza ni bilo mogoče obdelati. Poskusite znova."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Obraz je presvetel. Poskusite pri manj svetlobe."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Obraz je pretemen. Odkrijte vir svetlobe."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Tipalo premaknite dlje od obraza."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Tipalo premaknite bliže obrazu."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Tipalo premaknite višje."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Tipalo premaknite nižje."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Tipalo premaknite v desno."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Tipalo premaknite v levo."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Poglejte v tipalo."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Ni zaznanih obrazov."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Preveč se premikate."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Znova prijavite svoj obraz."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Zaznan je drug obraz."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Preveč podobno, spremenite položaj."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Glejte bolj naravnost v fotoaparat."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Glejte bolj naravnost v fotoaparat."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Zravnajte glavo."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Odkrijte si obraz."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Strojna oprema za prepoznavo obraza ni na voljo."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Dosežena časovna omejitev za obraz. Poskusite znova."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Obraza ni mogoče shraniti."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Dejanje z obrazom je bilo preklicano."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Preverjanje pristnosti obraza preklical uporabnik"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Preveč poskusov. Poskusite znova pozneje."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Preveč poskusov. Preverjanje pristnosti obraza je onemogočeno."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Poskusite znova."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Ni prijavljenih obrazov."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Ta naprava nima tipala za preverjanje pristnosti obraza."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Obraz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1253,9 +1286,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Odpri <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"Aplikacija <xliff:g id="OLD_APP">%1$s</xliff:g> se bo zaprla brez shranjevanja"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Proces <xliff:g id="PROC">%1$s</xliff:g> je presegel omejitev pomnilnika"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Izvoz kopice je zbran. Dotaknite se za deljenje z drugimi."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Deljenje izvoza kopice z drugimi?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> je presegel <xliff:g id="SIZE">%2$s</xliff:g> omejitve pomnilnika za proces. Izvoz kopice je na voljo, da ga delite z razvijalcem. Previdno: izvoz kopice lahko vsebuje vaše osebne podatke, do katerih ima aplikacija dostop."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Izberite dejanje za besedilo"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Glasnost zvonjenja"</string>
     <string name="volume_music" msgid="5421651157138628171">"Glasnost predstavnosti"</string>
@@ -1298,8 +1338,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dotaknite se, če si želite ogledati vsa omrežja"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Vzpostavi povezavo"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Vsa omrežja"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Na voljo je omrežje Wi-Fi po predlogu aplikacije <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Želite vzpostaviti povezavo z omrežji, ki jih predlaga aplikacija <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Povezava Wi‑Fi se bo samodejno vklopila"</string>
@@ -1311,9 +1353,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Prijava v omrežje"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Omrežje Wi-Fi nima dostopa do interneta"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Dotaknite se za možnosti"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Povezava je vzpostavljena"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Spremembe nastavitev dostopne točke"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Pas dostopne točke je spremenjen."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Ta naprava ne podpira prednostne nastavitve samo za 5-GHz pas. Namesto tega bo ta naprava uporabljala 5-GHz pas, ko bo na voljo."</string>
@@ -1398,6 +1445,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje napak prek USB je povezano"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Dotaknite se, če želite izklopiti odpravljanje napak prek USB-ja"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"V vratih USB je tekočina ali umazanija"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Vrata USB so samodejno onemogočena. Dotaknite se, če želite izvedeti več."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Vrata USB so varna za uporabo"</string>
@@ -1973,8 +2024,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Dotaknite se za odkl. del. pr."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Vzpostavljena povezava z napravo <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dotaknite se, če si želite ogledati datoteke"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Pripenjanje"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Odpenjanje"</string>
     <string name="app_info" msgid="6856026610594615344">"Podatki o aplikaciji"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Začenjanje predstavitve …"</string>
@@ -2067,6 +2116,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Rutinsko informativno obvestilo o načinu delovanja"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Akumulator se bo morda izpraznil, preden ga običajno priključite na polnjenje"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Vklopilo se je varčevanje z energijo akumulatorja za podaljšanje časa delovanja akumulatorja"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Mapa"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplikacija za Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Datoteka"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 61703f3..ce9c564 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Telefonatë me WiFi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Çaktivizuar"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferohet Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferohet rrjeti celular"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Vetëm Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nuk u transferua"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Raporti i defekteve në kod"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Jepi fund sesionit"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Pamja e ekranit"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Merr raportin e defekteve në kod"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Ky funksion mundëson mbledhjen e informacioneve mbi gjendjen aktuale të pajisjes për ta dërguar si mesazh mail-i. Do të duhet pak kohë nga nisja e raportit të defekteve në kod. Faleminderit për durimin."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Raport interaktiv"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Përdore këtë në shumicën e rrethanave. Të lejon të gjurmosh progresin e raportit dhe të fusësh më shumë detaje rreth problemit dhe të regjistrosh pamje të ekranit. Mund të fshijë disa seksione që përdoren më pak të cilat kërkojnë shumë kohë për t\'u raportuar."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Vendndodhja"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"qaset te vendndodhja e kësaj pajisjeje"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Të lejohet që &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; të ketë qasje te vendndodhja e kësaj pajisjeje?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Aplikacioni do të ketë qasje te vendndodhja vetëm kur po e përdor aplikacionin."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Të lejohet gjithmonë që &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; të ketë qasje te vendndodhja?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Aplikacioni do të ketë gjithmonë qasje te vendndodhja, edhe kur nuk po e përdor aplikacionin."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendari"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"qasje te kalendari yt"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Të lejohet që &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; të ketë qasje te kalendari yt?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Të lejohet që &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; të ketë qasje te muzika jote?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotografitë dhe videot"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"qasu te fotografitë dhe videot e tua"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Të lejohet që &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; të qaset te fotografitë dhe videot e tua, duke përfshirë vendndodhjet e etiketuara?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Nxjerrë përmbajtjen e dritares"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspekton përmbajtjen e dritares me të cilën po ndërvepron."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivizojë funksionin \"Eksploro me prekje\""</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Lejon aplikacionin të komunikojë me etiketimet e \"Komunikimit të fushës së afërt (NFC)\", kartat dhe lexuesit."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"çaktivizo kyçjen e ekranit"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Lejon aplikacionin të çaktivizojë kyçjen e tasteve dhe çdo mbrojtje të lidhur me fjalëkalimin. Për shembull, telefoni çaktivizon kyçjen e tasteve kur merr një telefonatë hyrëse, pastaj riaktivizon kyçjen e tasteve kur mbaron telefonata."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"kërko kompleksitetin e kyçjes së ekranit"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Lejo që aplikacioni të mësojë nivelin e kompleksitetit të kyçjes së ekranit (i lartë, i mesëm, i ulët ose asnjë), që tregon gamën e mundshme të gjatësisë dhe llojin e kyçjes së ekranit. Aplikacioni mund t\'u sugjerojë gjithashtu përdoruesve që të përditësojnë kyçjen e ekranit në një nivel të caktuar, por përdoruesit mund ta shpërfillin lirshëm dhe të navigojnë më tej. Ki parasysh se kyçja e ekranit nuk ruhet në tekst të thjeshtë, prandaj aplikacioni nuk e di fjalëkalimin e saktë."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"përdor harduerin biometrik"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"E lejon aplikacionin që të përdorë harduerin biometrik për vërtetimin"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"të menaxhojë harduerin e gjurmës së gishtit"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Lejon aplikacionin të aktivizojë mënyra për shtim e fshirje të shablloneve të përdorura."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"përdor harduerin për vërtetimin e fytyrës"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Lejon aplikacionin të përdorë harduer vërtetimi të fytyrës për procesin e vërtetimit"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Fytyra nuk mund të përpunohej. Provo sërish."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Fytyra ka shumë ndriçim. Provo me më pak ndriçim."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Fytyra shumë e errët. Zbulo burimin e dritës."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Lëvize sensorin pak më larg fytyrës."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Sille sensorin më pranë fytyrës."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Lëvize sensorin më lart."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Lëvize sensorin më poshtë."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Lëvize sensorin djathtas."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Lëvize sensorin majtas."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Shiko nga sensori"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Nuk u diktua fytyrë"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Ka shumë lëvizje."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Regjistroje përsëri fytyrën tënde."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"U diktua fytyrë tjetër."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Tepër e ngjashme, ndrysho pozën"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Shikoje kamerën më drejt."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Shikoje kamerën më drejt."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Drejtoje kokën vertikalisht"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Zbuloje fytyrën"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Nuk ka harduer për fytyrën."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Mbaroi afati për fytyrën. Provo sërish."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Fytyra nuk mund të ruhet."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Veprimi me fytyrën u anulua."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Vërtetimi me fytyrë u anulua nga përdoruesi."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Shumë përpjekje. Provo sërish më vonë."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Shumë përpjekje. Vërtetimi për fytyrën joaktiv."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Provo sërish."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Nuk ka fytyrë të regjistruar."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Kjo pajisje nuk ka sensor vërtetimi për fytyrën."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Fytyra <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Hap <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> do të mbyllet pa u ruajtur"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> e ka kaluar kufirin e memories"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Stiva e skedarëve fiktivë është mbledhur. Trokit për t\'i ndarë."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Të ndahet stiva e skedarëve fiktivë?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Procesi <xliff:g id="PROC">%1$s</xliff:g> ka kaluar kufirin e tij të memories së procesit me <xliff:g id="SIZE">%2$s</xliff:g>. Mundësohet stivimi e skedarëve fiktivë në mënyrë që t\'i ndani me zhvilluesit e tyre. Bëni kujdes pasi stiva e skedarëve fiktivë mund të përmbajë ndonjë informacion tëndin personal ku aplikacioni ka qasje."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Zgjidh një veprim për tekstin"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Volumi i ziles"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volumi i medias"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trokit për të parë të gjitha rrjetet"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Lidhu"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Të gjitha rrjetet"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Ofrohet një rrjet Wi‑Fi i propozuar nga <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Dëshiron të lidhesh me rrjetet e propozuara nga <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Po"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Jo"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi do të aktivizohet automatikisht"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Identifikohu në rrjet"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi nuk ka qasje në internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Trokit për opsionet"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Lidhur"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Ndryshimet në cilësimet e zonës së qasjes për internet"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Brezi yt i zonës së qasjes për internet ka ndryshuar."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Kjo pajisje nuk e mbështet preferencën për vetëm 5 GHz. Përkundrazi, pajisja do të përdorë brezin 5 GHz nëse ka."</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Trokit për të çaktivizuar korrigjimin e USB-së"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Përzgjidhe për të çaktivizuar korrigjimin e gabimeve të USB-së"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Lëngje ose papastërti në portën e USB-së"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Porta e USB-së është çaktivizuar automatikisht. Trokit për të mësuar më shumë."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Nuk ka rrezik të përdoret porta e USB-së"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Trokit për ta shkyçur profilin e punës"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"U lidh me <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Trokit për të parë skedarët"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Gozhdo"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Zhgozhdo"</string>
     <string name="app_info" msgid="6856026610594615344">"Informacioni mbi aplikacionin"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Po nis demonstrimin..."</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Njoftimi i informacionit të \"Modalitetit rutinë\""</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Bateria mund të mbarojë përpara ngarkimit të zakonshëm"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"\"Kursyesi i baterisë\" u aktivizua për të zgjatur jetëgjatësinë e baterisë"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Dosje"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Aplikacion i Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Skedar"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 68c272c..1d7ae45 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -142,8 +142,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Позивање преко Wi-Fi-ја"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Искључено"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Предност има Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Желим мобилне податке"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Само Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Није прослеђено"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -230,7 +232,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Извештај о грешци"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Заврши сесију"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Снимак екрана"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Направи извештај о грешци"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Овим ће се прикупити информације о тренутном стању уређаја како би биле послате у поруци е-поште. Од започињања извештаја о грешци до тренутка за његово слање проћи ће неко време; будите стрпљиви."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Интерактив. извештај"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Користите ово у већини случајева. То вам омогућава да пратите напредак извештаја, да уносите додатне детаље о проблему и да снимате снимке екрана. Вероватно ће изоставити неке мање коришћене одељке за које прављење извештаја дуго траје."</string>
@@ -284,9 +287,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"приступи локацији овог уређаја"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Желите ли да омогућите да &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; приступа локацији овог уређаја?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Апликација ће имати приступ локацији само док користите апликацију."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Желите ли да омогућите да &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; приступа локацији овог уређаја?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Апликација ће увек имати приступ локацији, чак и када не користите апликацију."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"приступи календару"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Желите ли да омогућите да &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; приступа календару?"</string>
@@ -319,7 +325,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Желите ли да омогућите да &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; приступа музици?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Слике и видео снимци"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"приступ сликама и видео снимцима"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Желите ли да дозволите да „<xliff:g id="APP_NAME">%1$s</xliff:g>“ приступа сликама и видео снимцима, укључујући означене локације?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"да преузима садржај прозора"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Проверава садржај прозора са којим остварујете интеракцију."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"да укључи Истраживања додиром"</string>
@@ -512,8 +521,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Дозвољава апликацији да комуницира са ознакама, картицама и читачима комуникације кратког домета (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"онемогућавање закључавања екрана"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Дозвољава апликацији да онемогући закључавање тастатуре и све повезане безбедносне мере са лозинкама. На пример, телефон онемогућава закључавање тастатуре при пријему долазног телефонског позива, а затим га поново омогућава по завршетку позива."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"тражење сложености закључавања екрана"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Дозвољава апликацији да сазна ниво сложености закључавања екрана (висока, средња, ниска или ниједна), што указује на могући опсег трајања и тип закључавања екрана. Апликација може и да предлаже корисницима да ажурирају закључавање екрана на одређени ниво, али корисници слободно могу да занемаре то и да иду на друге странице. Имајте на уму да се подаци за закључавање екрана не чувају као обичан текст, па апликација не зна тачну лозинку."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"користи биометријски хардвер"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Дозвољава апликацији да користи биометријски хардвер за потврду идентитета"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управљај хардвером за отиске прстију"</string>
@@ -568,37 +579,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Дозвољава да апликација активира методе за додавање и брисање шаблона лица ради коришћења."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"коришћење хардв. за потврду идентитета помоћу лица"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Дозвољава да апликација користи хардвер за потврду идентитета помоћу лица"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Обрада лица није успела. Пробајте поново."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Лице је пресветло. Пробајте са слабијим осветљењем."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Лице је исувише тамно. Откријте извор светла."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Удаљите сензор од лица."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Приближите сензор лицу."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Померите сензор навише."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Померите сензор наниже."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Померите сензор удесно."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Померите сензор улево."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Гледајте у сензор."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Није откривено ниједно лице."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Много се померате."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Поново региструјте лице."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Откривено је друго лице."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Превише је слично, промените позу."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Гледајте право у камеру."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Гледајте право у камеру."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Исправите главу."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Откријте лице."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Харвдер за лице није доступан."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Истекло је време за проверу лица. Пробајте поново."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Није могуће сачувати лице."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Обрада лица је отказана."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Корисник је отказао потврду лица."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Превише покушаја. Пробајте поново касније."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Више покушаја. Потврда идентитета је онемогућена."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Пробајте поново."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Није регистровано ниједно лице."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Овај уређај нема сензор за потврду идентитета помоћу лица."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1233,9 +1266,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Отвори <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> ће се затворити без чувања"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> премашује ограничење меморије"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Снимак динамичког дела меморије је направљен. Додирните за дељење."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Желите ли да делите снимак динамичког дела меморије?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Процес <xliff:g id="PROC">%1$s</xliff:g> је премашио ограничење меморије за процес од <xliff:g id="SIZE">%2$s</xliff:g>. Снимак динамичког дела меморије је доступан и можете да га делите са програмером. Будите опрезни: овај снимак динамичког дела меморије може да садржи неке личне податке којима апликација може да приступа."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Изаберите радњу за текст"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Јачина звука звона"</string>
     <string name="volume_music" msgid="5421651157138628171">"Јачина звука медија"</string>
@@ -1276,8 +1316,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Додирните да бисте видели све мреже"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Повежи"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Све мреже"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Wi‑Fi мрежа коју предлаже <xliff:g id="NAME">%s</xliff:g> је доступна"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Желите ли да се повежете на мреже које предлаже <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ће се аутоматски укључити"</string>
@@ -1289,9 +1331,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Пријавите се на мрежу"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi нема приступ интернету"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Додирните за опције"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Повезано је"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Промене подешавања за хотспот"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Опсег хотспота је промењен."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Овај уређај не подржава подешавање само за 5 GHz. Уређај ће користити опсег од 5 GHz када буде доступан."</string>
@@ -1376,6 +1423,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је омогућено"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Додирните да бисте искључили отклањање грешака са USB-а"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистоћа у USB порту"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт је аутоматски искључен. Додирните да бисте сазнали више."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Коришћење USB порта је безбедно"</string>
@@ -1939,8 +1990,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Додиром откљ. профил за Work"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Повезано је са производом <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Додирните за преглед датотека"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Закачи"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Откачи"</string>
     <string name="app_info" msgid="6856026610594615344">"Информације о апликацији"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Покрећемо демонстрацију..."</string>
@@ -2032,6 +2081,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Обавештење о информацијама Рутинског режима"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Батерија ће се можда испразнити пре уобичајеног пуњења"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Уштеда батерије је активирана да би се продужило трајање батерије"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Директоријум"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android апликација"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Датотека"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index aaf33bb..02f47d9 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi-samtal"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Av"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi i första hand"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Använd mobildata"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Endast Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Vidarebefordras inte"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Felrapport"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Avsluta session"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skärmdump"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Skapa felrapport"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Nu hämtas information om aktuell status för enheten, som sedan skickas i ett e-postmeddelade. Det tar en liten stund innan felrapporten är färdig och kan skickas, så vi ber dig ha tålamod."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv rapport"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Bör användas i de flesta fall. Då kan du spåra rapportförloppet, ange mer information om problemet och ta skärmdumpar. En del mindre använda avsnitt, som det tar lång tid att rapportera om, kan uteslutas."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Plats"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"komma åt enhetens platsuppgifter"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; åtkomst till enhetens plats?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Appen har endast åtkomst till platsen när du använder den."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; åtkomst till enhetens plats?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Appen har alltid åtkomst till platsen, även om du inte använder den."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"få tillgång till din kalender"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; åtkomst till din kalender?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; åtkomstbehörighet till din musik?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Foton och videor"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"åtkomstbehörighet till dina foton &amp; videor"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Vill du tillåta att &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; får åtkomst till dina foton och videor, inklusive taggade platser?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Hämta fönsterinnehåll"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Granska innehållet i ett fönster som du interagerar med."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivera Explore by touch"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Tillåter att appen kommunicerar med etiketter, kort och läsare för närfältskommunikation (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"inaktivera skärmlåset"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Tillåter att appen inaktiverar tangentlåset och tillhörande lösenordsskydd. Ett exempel kan vara att tangentlåset inaktiveras vid inkommande samtal och aktiveras igen när samtalet är avslutat."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"begär komplexitetsnivå för skärmlåset"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Tillåter att appen får reda på komplexitetsnivån för skärmlåset (hög, mellan, låg eller ingen). Detta ger en indikation på skärmlåsets möjliga längd och typ. Appen kan även föreslå att skärmlåset uppdateras till en viss nivå, men användare kan ignorera förslaget och fortsätta navigera. Observera att skärmlåset inte lagras i vanlig text så appen får inte reda på det exakta lösenordet."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"använd biometrisk maskinvara"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Tillåter att appen använder biometrisk maskinvara vid autentisering"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"hantera maskinvara för fingeravtryck"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Tillåter att appen anropar metoder för att lägga till och radera ansiktsmallar."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"använda maskinvara för ansiktsautentisering"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Tillåter att appen använder maskinvara för ansiktsigenkänning vid autentisering"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Det gick inte att läsa av ansiktet. Försök igen."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Ansiktet är för ljust. Testa i svagare belysning."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Ansiktet är för mörkt. Testa i starkare belysning."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Flytta sensorn längre ifrån ansiktet."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Ha sensorn närmare ansiktet."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Flytta sensorn uppåt."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Flytta sensorn nedåt."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Flytta sensorn åt höger."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Flytta sensorn åt vänster."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Titta på sensorn."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Inget ansikte hittades."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"För mycket rörelse."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registrera ansiktet på nytt."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Ett annat ansiktet har upptäckts."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"För likt. Ändra ansiktsposition."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Titta rakt in i kameran."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Titta rakt in i kameran."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Räta på huvudet vertikalt."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Skym inte ansiktet."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Maskinvara för ansiktsigenkänning saknas."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Tidsgränsen för ansikte har nåtts. Försök igen."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Det gick inte att lagra ansiktet."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Ansiktsåtgärden har avbrutits."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Autentiseringen av ansiktet avbröts av användaren."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Du har gjort för många försök. Försök igen senare."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"För många försök. Ansiktsautentisering inaktiverad"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Försök igen."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Inget ansikte har registrerats."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Enheten har ingen sensor för ansiktsautentisering."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Ansikte <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Öppna <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> stängs utan att spara"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Minnesgränsen har överskridits för <xliff:g id="PROC">%1$s</xliff:g>"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"En minnesdump har skapats. Tryck här om du vill dela den."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Vill du dela minnesdumpen?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Minnesgränsen på <xliff:g id="SIZE">%2$s</xliff:g> har överskridits för processen <xliff:g id="PROC">%1$s</xliff:g>. En dump av minnesheapen har skapats så att du kan dela den med utvecklaren. Var försiktig: minnesdumpen kan innehålla personliga uppgifter som appen har åtkomst till."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Välj en åtgärd för text"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Ringvolym"</string>
     <string name="volume_music" msgid="5421651157138628171">"Mediavolym"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryck för att visa alla nätverk"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Anslut"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alla nätverk"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Det finns ett tillgängligt Wi‑Fi-nätverk som föreslås av <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Vill du ansluta till nätverk som föreslås av <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nej"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi aktiveras automatiskt"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Logga in på nätverket"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi-nätverket är inte anslutet till internet"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tryck för alternativ"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Ansluten"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Ändringar i inställningarna för surfzon"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Frekvensbandet för surfzonen har ändrats."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Den här enheten har inte stöd för inställningen för att endast använda 5 GHz. I stället används 5 GHz när det är möjligt."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Tryck för att inaktivera USB-felsökning"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Välj för att inaktivera USB-felsökning."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vätska eller smuts i USB-porten"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten har inaktiverats automatiskt. Tryck för att läsa mer."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Nu kan du använda USB-porten igen"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Tryck och lås upp jobbprofilen"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Ansluten till <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Filerna visas om du trycker här"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Fäst"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Lossa"</string>
     <string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
     <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo startas …"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Avisering om rutinläge"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Batteriet kan ta slut innan du brukar ladda det"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Batterisparläget har aktiverats för att utöka batteritiden"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Mapp"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android-app"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fil"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index ae7531b0..358c1fb 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Kupiga simu kupitia WiFi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Imezimwa"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi inapedelewa"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mtandao wa simu unapendelewa"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi pekee"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Haijatumiwa mwingine"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ripoti ya hitilafu"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Maliza kipindi"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Picha ya skrini"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Chukua ripoti ya hitilafu"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Hii itakusanya maelezo kuhusu hali ya kifaa chako kwa sasa, na itume kama barua pepe. Itachukua muda mfupi tangu ripoti ya hitilafu ianze kuzalishwa hadi iwe tayari kutumwa; vumilia."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Ripoti ya kushirikiana"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Tumia chaguo hili katika hali nyingi. Hukuruhusu kufuatilia jinsi ripoti yako inavyoendelea, kuandika maelezo zaidi kuhusu tatizo na kupiga picha za skrini. Huenda ikaacha baadhi ya sehemu ambazo hazitumiki sana na zinachukua muda mrefu kuripoti."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Mahali"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"itambue mahali kifaa hiki kilipo"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; itambue mahali kifaa kilipo?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Programu itafikia tu data ya mahali ulipo unaipotumia."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Ungependa kuruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie data ya mahali kifaa hiki kilipo kila wakati?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Programu itaweza kufikia data ya mahali kifaa kilipo hata wakati huitumii."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ifikie kalenda yako"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie kalenda yako?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie muziki wako?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Picha na video"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"kufikia picha na video zako"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Ungependa kuruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ufikie picha na video zako, yakiwemo maeneo uliyotambulisha?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Kufikia maudhui ya dirisha"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kuchunguza maudhui ya dirisha unalotumia."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Kuwasha \'Chunguza kwa Kugusa\'"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Inaruhusu programu kuwasiliana na lebo, kadi na wasomaji wa Near Field Communication (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"zima kufuli la skrini yako"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Inaruhusu programu kulemaza ufunguo wa vitufe na usalama mwingine ambata wa nenosiri. Kwa mfano, simu inalemaza ufunguo wa viitufe inapopokea simu inayoingia, kisha inawezesha upya ufunguo wa vitufe wakati simu inapokamilika."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"iombe kiwango cha uchangamano wa kufunga skrini"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Huruhusu programu kupata maelezo kuhusu kiwango cha uchangamano wa kufunga skrini (juu, wastani, chini au hakuna), ambacho huashiria urefu unaowezekana na aina ya kufunga skrini. Programu pia inaweza kumpendekezea mtumiaji asasishe mbinu ya kufunga skrini iwe ya kiwango fulani lakini mtumiaji anaweza kuamua kupuuza na kuendelea. Kumbuka kuwa maelezo ya kufunga skrini hayahifadhiwi kama maandishi, hivyo programu haitambui nenosiri mahususi."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"tumia maunzi ya kibiolojia"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Huruhusu programu itumie maunzi ya kibiolojia katika uthibitishaji"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"dhibiti maunzi ya kitambulisho"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Huruhusu programu iombe njia za kuongeza na kufuta violezo vya uso vitakavyotumiwa."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"tumia maunzi ya kuthibistiha uso"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Huruhusu programu ithibitishe uso kwa kutumia maunzi ya kuthibitisha"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Imeshindwa kuchakata uso. Tafadhali jaribu tena."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Uso unang\'aa sana. Tafadhalia punguza mwangaza."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Uso hauna mwangaza wa kutosha. Tafadhali ongeza mwangaza."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Tafadhali sogeza kitambuzi mbali na uso."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Tafadhali sogeza kitambuzi karibu na uso."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Tafadhali sogeza kitambuzi juu."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Tafadhali sogeza kitambuzi chini."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Tafadhali sogeza kitambuzi kulia."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Tafadhali sogeza kitambuzi kushoto."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Tafadhali angalia kitambuzi."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Haikutambua uso wowote"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Inatikisika sana."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Tafadhali sajili uso wako tena."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Imetambua uso tofauti."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Inafanana sana, tafadhali badilisha mkao wako."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Tafadhali angalia kamera moja kwa moja."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Tafadhali angalia kamera moja kwa moja."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Tafadhali simamisha kichwa chako wima."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Tafadhali usifunike uso wako."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Maunzi ya uso hayapatikani."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Muda wa kutambua uso umeisha. Jaribu tena."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Huwezi kuhifadhi uso."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Utendaji wa kitambulisho umeghairiwa."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Uthibitishaji wa uso umeghairiwa na mtumiaji."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Umejaribu mara nyingi mno. Jaribu tena baadaye."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Umejaribu mara nyingi mno. Kitambuzi cha uso kimezimwa."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Jaribu tena."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Hujasajili uso wowote."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Kifaa hiki hakina kitambuzi kinachothibitisha uso."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Uso wa <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Fungua <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> itajifunga bila kuhifadhi mabadiliko"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> imezidi kiwango cha hifadhi kinachotakikana"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Imezidi kikomo cha hifadhi. Gusa ili ushiriki."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Ungependa kushiriki picha ya binafsi?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Mchakato wa <xliff:g id="PROC">%1$s</xliff:g> umezidi kiwango kinachotakikana cha hifadhi cha <xliff:g id="SIZE">%2$s</xliff:g>. Unaweza kupata picha ya hifadhi ili uishiriki na msadini programu wa picha. Tahadhari: picha hii ya hifadhi inaweza kuwa na maelezo yako ya binafsi ambayo yanaweza kufikiwa na programu."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Chagua kitendo kwa ajili ya maandishi"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Sauti ya mlio"</string>
     <string name="volume_music" msgid="5421651157138628171">"Sauti ya muziki"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Gusa ili uone mitandao yote"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Unganisha"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Mitandao yote"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Mtandao wa Wi‑Fi uliopendekezwa na <xliff:g id="NAME">%s</xliff:g> unapatikana"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Je, ungependa kuunganisha kwenye mitandao inayopendekezwa na <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ndiyo"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hapana"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi itawashwa kiotomatiki"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ingia katika mtandao"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi haina muunganisho wa intaneti"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Gusa ili upate chaguo"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Imeunganisha"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Mabadiliko kwenye mipangilio ya mtandao pepe"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Bendi ya mtandao pepe wako imebadilika."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Kifaa hiki hakitumii mapendeleo yako ya GHz 5 pekee. Badala yake, kifaa hiki kitatumia bendi ya GHz 5 itakapopatikana."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Utatuaji wa USB umeunganishwa"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Gusa ili uzime utatuzi wa USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chagua ili kulemaza utatuaji USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Unyevu au uchafu katika mlango wa USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Mlango wa USB umezimwa kiotomatiki. Gusa ili upate maelezo zaidi."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Ni salama kutumia mlango wa USB"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Gusa ili ufungue wasifu wa kazini"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Imeunganishwa na <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Gusa ili uangalie faili"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Bandika"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Bandua"</string>
     <string name="app_info" msgid="6856026610594615344">"Maelezo ya programu"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Inaanzisha onyesho..."</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Arifa ya maelezo ya Hali ya Kawaida"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Huenda betri itakwisha chaji mapema"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Imewasha Kiokoa Betri ili kurefusha muda wa matumizi ya betri"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folda"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Programu ya Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Faili"</string>
diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml
index 6edb88e..e2c8d8a 100644
--- a/core/res/res/values-sw600dp/config.xml
+++ b/core/res/res/values-sw600dp/config.xml
@@ -51,5 +51,9 @@
              4 - Snap to the long edges in each orientation and magnet to corners
     -->
     <integer name="config_pictureInPictureSnapMode">3</integer>
+
+    <!-- Controls whether the nav bar can move from the bottom to the side in landscape.
+         Only applies if the device display is not square. -->
+    <bool name="config_navBarCanMove">false</bool>
 </resources>
 
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index ded03cc..a1cf66a 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi కాలింగ్"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ఆఫ్‌లో ఉంది"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fiకి ప్రాధాన్యత"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"మొబైల్‌కి ప్రాధాన్యత ఇవ్వబడింది"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi మాత్రమే"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ఫార్వార్డ్ చేయబడలేదు"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"బగ్ నివేదిక"</string>
     <string name="global_action_logout" msgid="935179188218826050">"సెషన్‌ను ముగించు"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"స్క్రీన్‌షాట్"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"బగ్ నివేదికను సిద్ధం చేయి"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"ఇది ఇ-మెయిల్ సందేశం రూపంలో పంపడానికి మీ ప్రస్తుత పరికర స్థితి గురించి సమాచారాన్ని సేకరిస్తుంది. బగ్ నివేదికను ప్రారంభించడం మొదలుకొని పంపడానికి సిద్ధం చేసే వరకు ఇందుకు కొంత సమయం పడుతుంది; దయచేసి ఓపిక పట్టండి."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"ప్రభావశీల నివేదిక"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"చాలా సందర్భాల్లో దీన్ని ఉపయోగించండి. ఇది నివేదిక ప్రోగ్రెస్‌ను ట్రాక్ చేయడానికి, సమస్య గురించి మరిన్ని వివరాలను నమోదు చేయడానికి మరియు స్క్రీన్‌షాట్‌లు తీయడానికి మిమ్మల్ని అనుమతిస్తుంది. ఇది నివేదించడానికి ఎక్కువ సమయం పట్టే తక్కువ వినియోగ విభాగాలను విడిచిపెట్టవచ్చు."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"స్థానం"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"ఈ పరికర స్థానాన్ని యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"ఈ పరికర స్థానాన్ని యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని అనుమతించాలా?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"మీరు యాప్‌ని ఉపయోగిస్తున్నప్పుడు మాత్రమే యాప్ స్థానానికి యాక్సెస్ కలిగి ఉంటుంది."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"ఈ పరికర స్థానాన్ని యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని ఎల్లప్పుడూ అనుమతించాలా?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"ఈ యాప్ ఎల్లప్పుడూ స్థానానికి యాక్సెస్ కలిగి ఉంటుంది, మీరు యాప్‌ని ఉపయోగించనప్పుడు కూడా."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"క్యాలెండర్"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"మీ క్యాలెండర్‌ను యాక్సెస్ చేయడానికి"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"మీ క్యాలెండర్‌ని యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని అనుమతించాలా?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"మీ సంగీతాన్ని యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని అనుమతించాలా?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"ఫోటోలు &amp; వీడియోలు"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"మీ ఫోటోలను &amp; వీడియోలను యాక్సెస్ చేయండి"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"ట్యాగ్ చేసిన స్థానాలతో సహా, మీ ఫోటోలు, వీడియోలను యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను అనుమతించాలా?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"విండో కంటెంట్‍ను తిరిగి పొందుతుంది"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"మీరు పరస్పర చర్య చేస్తున్న విండో కంటెంట్‌‍ను పరిశీలిస్తుంది."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"తాకడం ద్వారా విశ్లేషణను ప్రారంభిస్తుంది"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"సమీప ఫీల్డ్ కమ్యూనికేషన్ (NFC) ట్యాగ్‌లు, కార్డులు మరియు రీడర్‌లతో కమ్యూనికేట్ చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"మీ స్క్రీన్ లాక్‌ను నిలిపివేయడం"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"కీలాక్ మరియు ఏదైనా అనుబంధించబడిన పాస్‌వర్డ్ భద్రతను నిలిపివేయడానికి యాప్‌ను అనుమతిస్తుంది. ఉదాహరణకు, ఇన్‌కమింగ్ ఫోన్ కాల్ వస్తున్నప్పుడు ఫోన్ కీలాక్‌ను నిలిపివేస్తుంది, ఆపై కాల్ ముగిసిన తర్వాత కీలాక్‌ను మళ్లీ ప్రారంభిస్తుంది."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"స్క్రీన్ లాక్ సంక్లిష్టత అభ్యర్థన"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"ఇది మీ స్క్రీన్ లాక్ పాస్‌వర్డ్‌ బల స్థాయి (తీవ్రంగా ఉండాలా లేదా ఓ మోస్తరుగా ఉండాలా లేదా తక్కువ తీవ్రంగా గానీ అసలు ఏదీ కాకుండా ఉండాలా) అనే విషయాన్ని గుర్తుంచుకోవడానికి యాప్‌కి అనుమతిస్తుంది, అలాగే పాస్‌‌వర్డ్ పొడుగు ఎంత ఉండాలీ, ఏ రకమైన స్క్రీన్ లాక్ పధ్ధతి అనుసరించాలో సూచిస్తుంది. యాప్ ఇంకా స్క్రీన్ లాక్‌ పాస్‌వర్డ్‌ బల స్థాయిని ఏ స్థాయిలో సెట్ చేసుకుంటే బాగుంటుందో వినియోగదారులకు తెలపగలదు కానీ వినియోగదారులు దాని సూచనలను పట్టించుకోకుండా వారి ఇష్టం మేరకు చక్కగా సెట్ చేసుకోవచ్చు. మీకో ముఖ్యమైన మాట స్క్రీన్ లాక్‌ పాస్‌వర్డ్‌ అనేది సాదా వచన రూపంలో నిల్వ చేయబడదు, కనుక అసలు మీరు పాస్‌వర్డ్‌ ఏం పెట్టారనే విషయం యాప్‌కి తెలియదు."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"బయోమెట్రిక్ హార్డ్‌వేర్‌ని ఉపయోగించు"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"ప్రమాణీకరణ కోసం బయోమెట్రిక్ హార్డ్‌వేర్‌ను ఉపయోగించడానికి యాప్‌ని అనుమతిస్తుంది"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"వేలిముద్ర హార్డ్‌వేర్‌ని నిర్వహించడానికి అనుమతి"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"వినియోగం కోసం ముఖ టెంప్లేట్‌లను జోడించే మరియు తొలగించే పద్ధతులను అమలు చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"ముఖ ప్రమాణీకరణ హార్డ్‌వేర్‌ను వాడండి"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"ప్రమాణీకరణ కోసం ముఖ ప్రామాణీకరణ హార్డ్‌వేర్‌ను ఉపయోగించడానికి యాప్‌ని అనుమతిస్తుంది"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"ముఖాన్ని ప్రాసెస్ చేయడం సాధ్యపడలేదు. దయచేసి మళ్లీ ప్రయత్నించండి."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"ముఖం చాలా ప్రకాశవంతంగా ఉంటుంది. దయచేసి తక్కువ కాంతిలో ప్రయత్నించండి."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"ముఖం చాలా చీకటిగా ఉంది. దయచేసి కాంతి మూలాన్ని వెతకండి."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"దయచేసి ముఖం నుండి దూరంగా సెన్సార్‌ను జరపండి."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"దయచేసి సెన్సార్‌ను ముఖానికి మరింత దగ్గరగా తీసుకురండి."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"దయచేసి సెన్సార్‌ను ఎక్కువకు జరపండి."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"దయచేసి సెన్సార్‌ను తక్కువకు జరపండి."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"దయచేసి సెన్సార్‌ను కుడికి జరపండి."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"దయచేసి సెన్సార్‌ను ఎడమవైపుకు జరపండి."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"దయచేసి సెన్సార్‌ను చూడండి."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"ఎలాంటి ముఖం గుర్తించబడలేదు."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"చలనం ఎక్కువగా ఉంది."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"దయచేసి మీ ముఖాన్ని మళ్లీ నమోదు చేయండి."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"వేరొక ముఖం గుర్తించబడింది."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ఒకే మాదిరిగా ఉంది, దయచేసి భంగిమను మార్చండి."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"దయచేసి కెమెరా వైపు మరింత సూటిగా చూడండి."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"దయచేసి కెమెరా వైపు మరింత సూటిగా చూడండి."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"దయచేసి మీ తలను నిలువుగా, నిటారుగా ఉంచండి."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"దయచేసి మీ ముఖంపై చీకటి లేకుండా చూడండి."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"ముఖ హార్డ్‌వేర్ అందుబాటులో లేదు."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"ముఖ గడువు సమయం చేరుకుంది. మళ్లీ ప్రయత్నించండి."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"ముఖం నిల్వ చేయబడదు."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ముఖ కార్యకలాపం రద్దయింది."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"వినియోగదారు ద్వారా ముఖ ప్రమాణీకరణ రద్దు చేయబడింది."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"చాలా ఎక్కువ ప్రయత్నాలు చేసారు. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"చాలా ఎక్కువ ప్రయత్నాలు చేసారు. ముఖ ప్రమాణీకరణ నిలిపివేయబడింది."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"మళ్లీ ప్రయత్నించండి."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"ముఖం నమోదు చేయబడలేదు."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"ముఖాన్ని ప్రమాణీకరణ చేసే సెన్సార్ ఈ పరికరం కలిగిలేదు."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"ముఖ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g>ని తెరువు"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> సేవ్ చేయకుండానే మూసివేయబడుతుంది"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> మెమరీ పరిమితిని మించిపోయింది"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"కుప్పలు తెప్పలుగా సేకరించబడింది. షేర్ చేయడానికి నొక్కండి"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"హీప్ డంప్‌ను భాగస్వామ్యం చేయాలా?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> ప్రాసెస్ దాని <xliff:g id="SIZE">%2$s</xliff:g> ప్రాసెస్ మెమరీ పరిమితిని మించిపోయింది. మీకు దాని డెవలపర్‌తో షేర్ చేయడానికి హీప్ డంప్ అందుబాటులో ఉంది. జాగ్రత్తగా ఉండండి: ఈ హీప్ డంప్‌లో యాప్‌ యాక్సెస్ కలిగి ఉన్న మీ వ్యక్తిగత సమాచారం ఏదైనా ఉండవచ్చు."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"వచనం కోసం చర్యను ఎంచుకోండి"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"రింగర్ వాల్యూమ్"</string>
     <string name="volume_music" msgid="5421651157138628171">"మీడియా వాల్యూమ్"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"అన్ని నెట్‌వర్క్‌లు చూడటానికి నొక్కండి"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"కనెక్ట్ చేయి"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"అన్ని నెట్‌వర్క్‌లు"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> సూచించిన ఒక Wi-Fi నెట్‌వర్క్ ఇప్పుడు అందుబాటులో ఉంది"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"మీరు <xliff:g id="NAME">%s</xliff:g> సూచించిన నెట్‌వర్క్‌లతో కనెక్ట్ చేయాలనుకుంటున్నారా?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"అవును"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"లేదు"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi స్వయంచాలకంగా ఆన్ అవుతుంది"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fiకి ఇంటర్నెట్ యాక్సెస్ లేదు"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ఎంపికల కోసం నొక్కండి"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"కనెక్ట్ చేయబడింది"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"మీ హాట్‌స్పాట్ సెట్టింగ్‌లకు మార్పులు"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"మీ హాట్‌స్పాట్ బ్యాండ్ మార్చబడింది."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"ఈ పరికరం 5GHz కోసం మాత్రమే మీ ప్రాధాన్యతకు మద్దతు ఇవ్వదు. బదులుగా, ఈ పరికరం అందుబాటులో ఉన్నప్పుడు 5GHz బ్యాండ్‌ను ఉపయోగిస్తుంది."</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB డీబగ్గింగ్‌ను ఆఫ్ చేయడానికి నొక్కండి"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"డీబగ్గింగ్‌ని నిలిపివేయడానికి ఎంచుకోండి."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB పోర్ట్‌లో ద్రవ లేదా వ్యర్థ పదార్థాలు ఉన్నాయి"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB పోర్ట్ ఆటోమేటిక్‌గా నిలిపివేయబడింది. మరింత తెలుసుకోవడానికి నొక్కండి."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"ఇప్పుడు సురక్షితంగా USB పోర్ట్‌ని ఉపయోగించుకోవచ్చు"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"కార్యాలయ ప్రొఫైల్ అన్‌లాక్ చేయుటకు నొక్కండి"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ఫైల్‌లను వీక్షించడానికి నొక్కండి"</string>
-    <string name="pin_target" msgid="3052256031352291362">"పిన్ చేయి"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"అన్‌‌పిన్‌ ‌చేయి"</string>
     <string name="app_info" msgid="6856026610594615344">"యాప్ సమాచారం"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"డెమోను ప్రారంభిస్తోంది..."</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"రొటీన్ మోడ్ సమాచార నోటిఫికేషన్"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"మామూలుగా ఛార్జ్ చేసేలోపు బ్యాటరీ ఖాళీ కావచ్చు"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి బ్యాటరీ సేవర్ యాక్టివేట్ చేయబడింది"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"ఫోల్డర్"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android అప్లికేషన్"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ఫైల్"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 5b2541f..54d7b32 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"การโทรผ่าน Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"ปิด"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ต้องการใช้ Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ต้องการใช้อินเทอร์เน็ตมือถือ"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi เท่านั้น"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ไม่ได้โอนสาย"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"รายงานข้อบกพร่อง"</string>
     <string name="global_action_logout" msgid="935179188218826050">"จบเซสชัน"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ภาพหน้าจอ"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"ใช้รายงานข้อบกพร่อง"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"การดำเนินการนี้จะรวบรวมข้อมูลเกี่ยวกับสถานะปัจจุบันของอุปกรณ์ของคุณ โดยจะส่งไปในรูปแบบข้อความอีเมล อาจใช้เวลาสักครู่ตั้งแต่เริ่มการสร้างรายงานข้อบกพร่องจนกระทั่งเสร็จสมบูรณ์ โปรดอดทนรอ"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"รายงานแบบอินเทอร์แอกทีฟ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"ใช้ตัวเลือกนี้ได้เกือบทุกสถานการณ์ โดยจะอนุญาตให้คุณติดตามความคืบหน้าของรายงาน ป้อนรายละเอียดเพิ่มเติมของปัญหา และถ่ายภาพหน้าจอ หัวข้อที่ใช้งานน้อยแต่ใช้เวลานานในการรายงานอาจถูกข้ามไป"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"ตำแหน่ง"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"เข้าถึงตำแหน่งของอุปกรณ์นี้"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงตำแหน่งของอุปกรณ์นี้ไหม"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"แอปจะมีสิทธิ์เข้าถึงตำแหน่งได้ในขณะที่คุณกำลังใช้แอปเท่านั้น"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงตำแหน่งของอุปกรณ์นี้ทุกครั้งไหม"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"แอปจะมีสิทธิ์เข้าถึงตำแหน่งเสมอแม้ว่าคุณจะไม่ได้ใช้แอป"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"ปฏิทิน"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"เข้าถึงปฏิทิน"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงปฏิทินไหม"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงเพลงไหม"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"รูปภาพและวิดีโอ"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"เข้าถึงรูปภาพและวิดีโอ"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึงรูปภาพและวิดีโอของคุณ รวมถึงตำแหน่งที่ติดแท็กไหม"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"เรียกข้อมูลเนื้อหาของหน้าต่าง"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ตรวจสอบเนื้อหาของหน้าต่างที่คุณกำลังโต้ตอบอยู่"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"เปิด \"แตะเพื่อสำรวจ\""</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"อนุญาตให้แอปพลิเคชันสื่อสารกับแท็ก Near Field Communication (NFC) การ์ด และโปรแกรมอ่าน"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ปิดใช้งานการล็อกหน้าจอของคุณ"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"อนุญาตให้แอปพลิเคชันปิดใช้งานการล็อกปุ่มกดและการรักษาความปลอดภัยด้วยรหัสผ่านใดๆ ที่เกี่ยวข้อง ตัวอย่างเช่น โทรศัพท์ปิดใช้งานการล็อกปุ่มกดเมื่อรับสายเรียกเข้า จากนั้นจึงเปิดใช้งานการล็อกปุ่มกดใหม่หลังจากวางสาย"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ขอความซับซ้อนของการล็อกหน้าจอ"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"อนุญาตให้แอปเรียนรู้ระดับความซับซ้อนของการล็อกหน้าจอ (สูง ปานกลาง ต่ำ หรือไม่มี) ซึ่งแสดงให้เห็นช่วงความยาวและประเภทของการล็อกหน้าจอที่เป็นไปได้ นอกจากนี้แอปยังแนะนำให้ผู้ใช้อัปเดตการล็อกหน้าจอเป็นระดับหนึ่งๆ ได้ด้วย แต่ผู้ใช้จะปฏิเสธและไปยังส่วนต่างๆ ต่อได้ โปรดทราบว่าระบบไม่ได้จัดเก็บการล็อกหน้าจอไว้เป็นข้อความธรรมดา เพื่อให้แอปไม่รู้รหัสผ่าน"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"ใช้ฮาร์ดแวร์ชีวมิติ"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"อนุญาตให้แอปใช้ฮาร์ดแวร์ชีวมิติเพื่อตรวจสอบสิทธิ์"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"จัดการฮาร์ดแวร์ลายนิ้วมือ"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"อนุญาตให้แอปเรียกใช้วิธีเพิ่มและลบเทมเพลตใบหน้าสำหรับการใช้งาน"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"ใช้ฮาร์ดแวร์ตรวจสอบสิทธิ์ด้วยใบหน้า"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"อนุญาตให้แอปใช้ฮาร์ดแวร์ตรวจสอบสิทธิ์ด้วยใบหน้าเพื่อตรวจสอบสิทธิ์"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"ประมวลผลใบหน้าไม่ได้ โปรดลองอีกครั้ง"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"ใบหน้าสว่างเกินไป โปรดลดแสง"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"ใบหน้ามืดเกินไป โปรดเปิดแหล่งกำเนิดแสง"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"โปรดขยับเซ็นเซอร์ให้ห่างจากใบหน้ามากขึ้น"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"โปรดขยับเซ็นเซอร์ให้ใกล้ใบหน้ามากขึ้น"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"โปรดขยับเซ็นเซอร์ให้สูงขึ้น"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"โปรดขยับเซ็นเซอร์ให้ต่ำลง"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"โปรดขยับเซ็นเซอร์ไปทางขวา"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"โปรดขยับเซ็นเซอร์ไปทางซ้าย"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"โปรดมองที่เซ็นเซอร์"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"ไม่พบใบหน้า"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"มีการเคลื่อนไหวมากเกินไป"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"โปรดลงทะเบียนใบหน้าอีกครั้ง"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"ตรวจพบใบหน้าอื่น"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ใกล้เคียงเกินไป โปรดเปลี่ยนท่าโพส"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"โปรดมองตรงไปที่กล้อง"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"โปรดมองตรงไปที่กล้อง"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"โปรดตั้งศีรษะให้ตรง"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"โปรดอย่าปิดบังใบหน้า"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"ฮาร์ดแวร์รู้จำใบหน้าไม่พร้อมใช้งาน"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"หมดเวลาใช้ใบหน้าแล้ว โปรดลองอีกครั้ง"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"จัดเก็บข้อมูลใบหน้าไม่ได้"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ยกเลิกการดำเนินการกับใบหน้าแล้ว"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"ผู้ใช้ยกเลิกการตรวจสอบสิทธิ์ใบหน้า"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ดำเนินการหลายครั้งเกินไป ลองอีกครั้งในภายหลัง"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"ดำเนินการหลายครั้งเกินไป ปิดใช้การตรวจสอบสิทธิ์ด้วยใบหน้าแล้ว"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"ลองอีกครั้ง"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"ไม่ได้ลงทะเบียนใบหน้าไว้"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ตรวจสอบสิทธิ์ด้วยใบหน้า"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"ใบหน้า <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"เปิด <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> จะปิดโดยไม่บันทึก"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> เกินขีดจำกัดของหน่วยความจำ"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"รวบรวมฮีพดัมพ์แล้ว แตะเพื่อแชร์"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"แชร์ฮีพดัมพ์ไหม"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"กระบวนการ <xliff:g id="PROC">%1$s</xliff:g> มีขนาดเกิน <xliff:g id="SIZE">%2$s</xliff:g> ซึ่งเป็นขีดจำกัดของหน่วยความจำกระบวนการแล้ว ฮีพดัมพ์จะพร้อมให้คุณแชร์กับนักพัฒนาซอฟต์แวร์ โปรดระวัง ฮีพดัมพ์นี้สามารถเก็บข้อมูลส่วนบุคคลที่แอปพลิเคชันมีสิทธิ์เข้าถึงได้"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"เลือกการทำงานกับข้อความ"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"ระดับความดังเสียงเรียกเข้า"</string>
     <string name="volume_music" msgid="5421651157138628171">"ระดับเสียงของสื่อ"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"แตะเพื่อดูเครือข่ายทั้งหมด"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"เชื่อมต่อ"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"เครือข่ายทั้งหมด"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"เครือข่าย Wi-Fi ที่ <xliff:g id="NAME">%s</xliff:g> เสนอใช้งานได้"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"ต้องการเชื่อมต่อเครือข่ายที่ <xliff:g id="NAME">%s</xliff:g> เสนอไหม"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ใช่"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ไม่"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi จะเปิดโดยอัตโนมัติ"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"ลงชื่อเข้าใช้เครือข่าย"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi เชื่อมต่ออินเทอร์เน็ตไม่ได้"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"แตะเพื่อดูตัวเลือก"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"เชื่อมต่อแล้ว"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"มีการเปลี่ยนแปลงการตั้งค่าฮอตสปอต"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"ย่านความถี่ฮอตสปอตมีการเปลี่ยนแปลง"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"อุปกรณ์นี้ไม่รองรับค่ากำหนดของคุณเฉพาะสำหรับ 5 GHz เท่านั้น และจะใช้ย่านความถี่ 5 GHz แทน เมื่อใช้ได้"</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่องผ่าน USB แล้ว"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"แตะเพื่อปิดการแก้ไขข้อบกพร่อง USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"มีของเหลวหรือฝุ่นละอองในพอร์ต USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"พอร์ต USB ปิดใช้โดยอัตโนมัติ แตะเพื่อดูข้อมูลเพิ่มเติม"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"ใช้พอร์ต USB ได้อย่างปลอดภัย"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"แตะเพื่อปลดล็อกโปรไฟล์งาน"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"เชื่อมต่อ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"แตะเพื่อดูไฟล์"</string>
-    <string name="pin_target" msgid="3052256031352291362">"ปักหมุด"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"เลิกปักหมุด"</string>
     <string name="app_info" msgid="6856026610594615344">"ข้อมูลแอป"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"กำลังเริ่มการสาธิต…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"การแจ้งเตือนข้อมูลโหมดกิจวัตร"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"แบตเตอรี่อาจหมดก่อนการชาร์จปกติ"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"เปิดใช้งานโหมดประหยัดแบตเตอรี่แล้วเพื่อยืดอายุการใช้งานแบตเตอรี่"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"โฟลเดอร์"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"ไฟล์แอปพลิเคชัน Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"ไฟล์"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4d7e7a2..d3c7852 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Pagtawag Gamit ang WiFi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Naka-off"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Mas gusto ang Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mas gusto ang mobile"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi lang"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Hindi naipasa"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ulat sa bug"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Tapusin ang session"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Kunin ang ulat sa bug"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Mangongolekta ito ng impormasyon tungkol sa kasalukuyang katayuan ng iyong device, na ipapadala bilang mensaheng e-mail. Gugugol ito ng kaunting oras mula sa pagsisimula ng ulat sa bug hanggang sa handa na itong maipadala; mangyaring magpasensya."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interactive na ulat"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Gamitin ito sa karamihan ng sitwasyon. Nagbibigay-daan ito sa iyo na masubaybayan ang pag-usad ng ulat, makapaglagay ng higit pang mga detalye tungkol sa problema, at makakuha ng mga screenshot. Maaari itong mag-alis ng ilan sa mga hindi masyadong ginagamit na seksyon na nangangailangan ng mahabang panahon upang iulat."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Lokasyon"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"i-access ang lokasyon ng device na ito"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na i-access ang lokasyon ng device na ito?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Maa-access lang ng app ang lokasyon habang ginagamit mo ang app."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Laging payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na i-access ang lokasyon?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Palaging maa-access ng app ang lokasyon, kahit na hindi mo ginagamit ang app."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendaryo"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"i-access ang iyong kalendaryo"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na i-access ang iyong kalendaryo?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na i-access ang iyong musika?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Mga larawan at video"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"i-access ang iyong mga larawan at video"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na i-access ang iyong mga larawan at video, kasama ang mga naka-tag na lokasyon?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Kunin ang content ng window"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Siyasatin ang nilalaman ng isang window kung saan ka nakikipag-ugnayan."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"I-on ang Explore by Touch"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Pinapayagan ang app na makipag-ugnay sa Near Field Communication (NFC) na mga tag, card, at reader."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"i-disable ang iyong screen lock"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Pinapayagan ang app na i-disable ang keylock at anumang nauugnay na seguridad sa password. Halimbawa, hindi pinapagana ng telepono ang keylock kapag nakakatanggap ng papasok na tawag sa telepono, pagkatapos ay muling pinapagana ang keylock kapag tapos na ang tawag."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"humiling ng pagiging kumplikado ng lock ng screen"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Pinapayagan ang app na malaman ang antas ng pagiging kumplikado ng lock ng screen (mataas, katamtaman, mababa, o wala), na nagsasaad ng posibleng hanay ng haba at uri ng lock ng screen. Maaari ding magmungkahi ang app sa mga user na i-update nila ang lock ng screen sa isang partikular na antas ngunit malaya ang mga user na balewalain ito at mag-navigate palayo. Tandaang hindi naka-store bilang plaintext ang lock ng screen kaya hindi alam ng app ang eksaktong password."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"gumamit ng biometric hardware"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Pinapayagan ang app na gumamit ng biometric hardware para sa pag-authenticate"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"pamahalaan ang hardware ng fingerprint"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Pumapayag na mag-invoke ang app ng paraang magdagdag at mag-delete ng template ng mukha."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"gumamit ng hardware sa pag-authenticate ng mukha"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Pumapayag na gumamit ng face authentication hardware ang app para sa pag-authenticate"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Hindi maiproseso ang mukha. Pakisubukang muli."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Masyadong maliwanag. Pakisubukan sa mas madilim."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Masyadong madilim. Huwag takpan ang ilaw."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Pakilayo sa mukha ang sensor."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Pakilapit sa mukha ang sensor."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Pakitaas ang sensor."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Pakibaba ang sensor."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Pakiusog pakanan ang sensor."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Pakiusog pakaliwa ang sensor."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Tumingin sa sensor."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Walang natukoy na mukha."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Masyadong magalaw."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Paki-enroll muli ang iyong mukha."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"May na-detect na ibang mukha."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Masyadong magkatulad, pakibago ang pose mo."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Tumingin nang mas direkta sa camera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Tumingin nang mas direkta sa camera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Pakituwid ang iyong mukha."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Pakialis ang tumatakip sa iyong mukha."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Hindi available ang hardware para sa mukha."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Nag-time out ang mukha. Subukang muli."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Hindi ma-store ang mukha."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Nakansela ang operation kaugnay ng mukha."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Kinansela ng user ang pag-authenticate ng mukha."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Masyadong maraming pagsubok. Subukang muli mamaya."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Sobrang pagsubok. Bawal na: facial authentication."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Subukang muli."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Walang naka-enroll na mukha."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Walang sensor ng authentication ng mukha ang device na ito."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Mukha <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Buksan ang <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"Magsasara ang <xliff:g id="OLD_APP">%1$s</xliff:g> nang hindi nagse-save"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Lumampas ang <xliff:g id="PROC">%1$s</xliff:g> sa limitasyon ng memory"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Nakolekta ang heap dump. I-tap para ibahagi."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Ibahagi ang heap dump?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Lumampas ang proseso na <xliff:g id="PROC">%1$s</xliff:g> sa limitasyon ng memory ng proseso nito na <xliff:g id="SIZE">%2$s</xliff:g>. Available ang isang heap dump upang iyong ibahagi sa developer nito. Maging maingat: maaaring naglalaman ang heap dump na ito ng anuman sa iyong personal na impormasyon na naa-access ng application."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Pumili ng pagkilos para sa teksto"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Lakas ng tunog ng ringer"</string>
     <string name="volume_music" msgid="5421651157138628171">"Lakas ng tunog ng media"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"I-tap upang makita ang lahat ng network"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kumonekta"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Lahat ng network"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"May available na Wi‑Fi network na iminumungkahi ng <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Gusto mo bang kumonekta sa mga network na iminumungkahi ng <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oo"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hindi"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Awtomatikong mag-o-on ang Wi‑Fi"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Mag-sign in sa network"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Walang access sa internet ang Wi-Fi"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"I-tap para sa mga opsyon"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Nakakonekta"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Mga pagbabago sa mga setting ng iyong hotspot"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Nagbago ang band ng iyong hotspot."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Hindi sinusuportahan ng device na ito ang kagustuhan mong gumamit lang ng 5GHz. Sa halip, gagamitin ng device na ito ang 5GHz na band kapag available."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Nakakonekta ang pag-debug ng USB"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"I-tap para i-off ang pag-debug ng USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Piliin upang i-disable ang debugging ng USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid o debris sa USB port"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Awtomatikong na-disable ang USB port. Mag-tap para matuto pa."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Ligtas na gamitin ang USB port"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"I-unlock ang profile sa trabaho, i-tap"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Nakakonekta sa <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"I-tap upang makita ang mga file"</string>
-    <string name="pin_target" msgid="3052256031352291362">"I-pin"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"I-unpin"</string>
     <string name="app_info" msgid="6856026610594615344">"Impormasyon ng app"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Sinisimulan ang demo…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Notification ng impormasyon ng Routine Mode"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Maaaring maubos ang baterya bago ang karaniwang pag-charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Na-activate ang Pangtipid sa Baterya para patagalin ang buhay ng baterya"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Folder"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android application"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"File"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 3e1bfb8..23b6031 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Kablosuz Çağrı"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Kapalı"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Kablosuz bağlantı tercihli"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobil tercihli"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Yalnızca kablosuz"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yönlendirilmedi"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Hata raporu"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Oturumu sonlandır"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekran görüntüsü"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Hata raporu al"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Bu rapor, e-posta iletisi olarak göndermek üzere cihazınızın şu anki durumuyla ilgili bilgi toplar. Hata raporu başlatıldıktan sonra hazır olması biraz zaman alabilir, lütfen sabırlı olun."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Etkileşimli rapor"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Çoğu durumda bunu kullanın. Bu seçenek, raporun ilerleme durumunu takip etmenize, sorunla ilgili daha fazla ayrıntı girmenize ve ekran görüntüleri almanıza olanak tanır. Rapor edilmesi uzun süren ve az kullanılan bazı bölümleri yok sayabilir."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Konum"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"bu cihazın konumuna erişme"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasının bu cihazın konumuna erişmesine izin verilsin mi?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Bu uygulama konum bilgisine yalnızca kullanıldığı sırada erişebilecektir."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasının bu cihazın konumuna erişmesine her zaman izin verilsin mi?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Bu uygulama, kullanılmadığında bile konum bilgisine her zaman erişebilecektir."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Takvim"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"takviminize erişme"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasının takviminize erişmesine izin verilsin mi?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasının müziğinize erişmesine izin veriyor musunuz?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Fotoğraflar ve videolar"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"fotoğraflarınıza ve videolarınıza erişme"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasına, etiketlenmiş yerler de dahil fotoğraf ve videolarınıza erişim izni verilsin mi?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pencere içeriğini alma"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Etkileşim kurduğunuz pencerenin içeriğini inceler."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Dokunarak Keşfet\'i açma"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Uygulamaya, Near Field Communication (NFC) etiketleri, kartlar ve okuyucular ile iletişim kurma izni verir."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ekran kilidimi devre dışı bırak"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Uygulamaya, tuş kilidini ve ilişkili tüm şifreli güvenlik önlemlerini devre dışı bırakma izni verir. Örneğin, telefon, çağrı alındığında tuş kilidinin devre dışı bırakır ve sonra, görüşme bittiğinde kilidi yeniden etkinleştirir."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ekran kilidi karmaşıklığı iste"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Uygulamanın, ekran kilidi karmaşıklık seviyesini (yüksek, orta, düşük veya yok) öğrenmesini sağlar. Ekran kilidi karmaşıklık seviyesi, ekran kilidinin olası uzunluk aralığını ve türünü gösterir. Uygulama, kullanıcılara ekran kilidini belirli bir seviyeye güncellemelerini de önerebilir, ancak kullanıcılar bunu istedikleri gibi yoksayabilir ve geçebilirler. Ekran kilidi şifrelenmemiş metin olarak saklanmadığı için uygulamanın şifreyi tam olarak bilmediğini unutmayın."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"biyometrik donanım kullan"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Uygulamanın kimlik doğrulama için biyometrik donanım kullanmasına izin verir"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"parmak izi donanımını yönetme"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Uygulamanın, kullanılacak yüz şablonlarını ekleme ve silme yöntemlerini başlatmasına izin verir."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"yüz kimlik doğrulaması donanımını kullanma"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Uygulamanın yüz kimlik doğrulaması donanımı kullanmasına izin verir"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Yüz işlenemedi. Lütfen tekrar deneyin."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Yüzünüz çok parlak. Lütfen ışığı kısmayı deneyin."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Yüzünüz çok karanlık. Lütfen ışığı artırın."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Lütfen sensörü yüzünüzden biraz uzaklaştırın."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Lütfen sensörü yüzünüze yaklaştırın."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Lütfen sensörü daha yukarı kaldırın."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Lütfen sensörü daha aşağı indirin."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Lütfen sensörü sağa kaydırın."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Lütfen sensörü sola kaydırın."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Lütfen sensöre bakın."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Yüz algılanmadı."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Çok fazla hareket ediyorsunuz."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Lütfen yüzünüzü yeniden kaydedin."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Farklı yüz algılandı."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Duruşunuz çok benzer, lütfen pozunuzu değiştirin."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Lütfen kameraya daha doğrudan bakın."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Lütfen kameraya daha doğrudan bakın."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Lütfen başınızı tam dik olacak şekilde tutun."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Lütfen yüzünüzü açın."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Yüz donanımı kullanılamıyor."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Yüz için zaman aşımı oluştu. Tekrar deneyin."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Yüz kaydedilemiyor."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Yüz işlemi iptal edildi."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Yüz kimlik doğrulama işlemini kullanıcı iptal etti."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Çok fazla deneme yapıldı. Daha sonra tekrar deneyin."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Çok fazla deneme yapıldı. Yüz kimlik doğrulaması devre dışı bırakıldı."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Tekrar deneyin."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Herhangi bir yüz kaydedilmedi."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Bu cihazda yüz kimlik doğrulaması için sensör yok."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Yüz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> uygulamasını aç"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> kaydetmeden kapanacak"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> bellek sınırını aştı"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Yığın dökümü toplandı. Paylaşmak için dokunun."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Yığın dökümü paylaşılsın mı?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g>, <xliff:g id="SIZE">%2$s</xliff:g> olan işlem bellek sınırını aştı. İşlemin geliştiricisiyle paylaşabileceğiniz bir bellek yığını dökümü hazır. Dikkat: Bu bellek yığını dökümü, uygulamanın erişebildiği tüm kişisel bilgilerinizi içerebilir."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Kısa mesaj için bir işlem seçin"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Zil ses düzeyi"</string>
     <string name="volume_music" msgid="5421651157138628171">"Medya ses düzeyi"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tüm ağları görmek için dokunun"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Bağlan"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tüm ağlar"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> tarafından önerilen bir kablosuz ağ kullanılabilir"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> tarafından önerilen ağlara bağlanmak istiyor musunuz?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Evet"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hayır"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Kablosuz özelliği otomatik olarak açılacak"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ağda oturum açın"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Kablosuz bağlantının internet erişimi yok"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Seçenekler için dokunun"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Bağlandı"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Hotspot ayarlarınız değişti"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Hotspot bandı değişti."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Bu cihaz yalnızca 5 GHz bandının kullanılmasına yönelik tercihinizi desteklemiyor. Bunun yerine, bu cihaz 5 GHz bandını mevcut olduğunda kullanacak."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB hata ayıklama işlevini kapatmak için dokunun"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için seçin."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB bağlantı noktasında sıvı veya toz var"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB bağlantı noktası otomatik olarak devre dışı bırakıldı. Daha fazla bilgi için dokunun."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB bağlantı noktası güvenli bir şekilde kullanılabilir"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"İş profilinin kilidini açmak için dokunun"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> cihazına bağlandı"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dosyaları görüntülemek için dokunun"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Sabitle"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Sabitlemeyi kaldır"</string>
     <string name="app_info" msgid="6856026610594615344">"Uygulama bilgileri"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo başlatılıyor…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Rutin Modu bilgi bildirimi"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Pil normal şarjdan önce bitebilir"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Pilin ömrünü uzatmak için Pil Tasarrufu etkinleştirildi"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Klasör"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android uygulaması"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Dosya"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 9ca44d9..41ad7b5 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -143,8 +143,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Дзвінки через Wi-Fi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"Передавання голосу через Wi-Fi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Вимкнено"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi за умовчанням"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Мобільна мережа за умовчанням"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Лише Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не переслано"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -232,7 +234,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Звіт про помилки"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Завершити сеанс"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Знімок екрана"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Звіт про помилку"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Інформація про поточний стан вашого пристрою буде зібрана й надіслана електронною поштою. Підготовка звіту триватиме певний час."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Інтерактивний звіт"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Підходить для більшості випадків. Можна відстежувати, як створюється звіт, вводити більше деталей про проблему та робити знімки екрана. Можуть опускатися деякі розділи, які рідко використовуються, але довго створюються."</string>
@@ -287,9 +290,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Геодані"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"доступ до геоданих пристрою"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Надати додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ до геоданих пристрою?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Додаток матиме доступ до геоданих, лише коли ви ним користуєтеся."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Завжди надавати додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ до геоданих цього пристрою?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Додаток матиме доступ до геоданих, навіть коли ви ним не користуєтеся."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"отримувати доступ до календаря"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Надати додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ до календаря?"</string>
@@ -322,7 +328,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Надати додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ до музики?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Фотографії та відео"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"доступ до фото й відео"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Дозволити додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; отримувати доступ до ваших фотографій і відео, зокрема до позначок місцеположення?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Отримувати вміст вікна"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Перевіряти вміст вікна, з яким ви взаємодієте."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Увімкнути функцію дослідження дотиком"</string>
@@ -515,8 +524,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Дозволяє програмі обмінюватися даними з тегами, картками та читачами екрана Near Field Communication (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"вимикати блокування екрана"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Дозволяє програмі вимикати блокування клавіатури та будь-який пов’язаний паролем захист. Наприклад: телефон вимикає блокування клавіатури під час отримання вхідного дзвінка, після закінчення якого блокування клавіатури відновлюється."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"запит складності способу блокування екрана"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Дозволяє додатку визначати рівень складності способу блокування екрана (високий, середній, низький або нульовий). Враховуються кількість символів і тип блокування. Додаток також може пропонувати користувачам вибрати складніший тип блокування екрана, але це не обов’язково робити. Примітка: оскільки пароль зашифрований, додаток його не знає."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"використовувати біометричне апаратне забезпечення"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Додаток може використовувати біометричне апаратне забезпечення для автентифікації"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"керувати апаратним забезпеченням для цифрових відбитків"</string>
@@ -571,37 +582,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Додаток може активувати способи додавання й видалення шаблонів облич."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"застосовувати обладнання для автентифікації облич"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Додаток може застосовувати обладнання для автентифікації облич"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Не вдалося розпізнати обличчя. Повторіть спробу."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Обличчя засвітле. Спробуйте знизити яскравість."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Обличчя затемне. Не заступайте джерело світла."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Перемістіть сканер далі від обличчя."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Перемістіть сканер ближче до обличчя."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Перемістіть сканер вище."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Перемістіть сканер нижче."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Перемістіть сканер праворуч."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Перемістіть сканер ліворуч."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Дивіться на сканер."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Обличчя не виявлено."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Забагато рухів."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Повторно проскануйте обличчя."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Виявлено інше обличчя."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Надто схоже на попередню спробу, змініть позу."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Дивіться просто в камеру."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Дивіться просто в камеру."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Тримайте голову вертикально."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Відкрийте обличчя."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Обладнання для сканування облич недоступне."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Час очікування обличчя минув. Повторіть спробу."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Не вдається зберегти обличчя."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Дію з обличчям скасовано."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Користувач скасував автентифікацію облич."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Забагато спроб. Повторіть пізніше."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Забагато спроб. Автентифікацію обличчя вимкнено."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Повторіть спробу."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Немає зареєстрованих облич."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"На цьому пристрої немає сканера для автентифікації облич."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Обличчя <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1253,9 +1286,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Відкрийте додаток <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> закриється без зберігання"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"Процес <xliff:g id="PROC">%1$s</xliff:g> перевищив ліміт пам’яті"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Дані динамічної пам’яті зібрано. Торкніться, щоб надіслати."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Поділитися даними динамічної пам’яті?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Процес <xliff:g id="PROC">%1$s</xliff:g> перевищив ліміт пам’яті (<xliff:g id="SIZE">%2$s</xliff:g>). Ви можете поділитися даними динамічної пам’яті з розробником. Увага: ці дані можуть містити вашу особисту інформацію, до якої має доступ додаток."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Виберіть дію для тексту"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Гучність дзвінка"</string>
     <string name="volume_music" msgid="5421651157138628171">"Гучність медіа"</string>
@@ -1298,8 +1338,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Торкніться, щоб побачити всі мережі"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Під’єднатися"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Усі мережі"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Доступна мережа Wi‑Fi, запропонована додатком <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Підключатися до мереж, які пропонує <xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Так"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ні"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi вмикатиметься автоматично"</string>
@@ -1311,9 +1353,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Вхід у мережу"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Мережа Wi-Fi не має доступу до Інтернету"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Торкніться, щоб відкрити опції"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Підключено"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Зміни в налаштуваннях точки доступу"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Діапазон точки доступу змінено."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"На цьому пристрої не підтримується налаштування лише 5 ГГц. Замість цього буде використовуватися діапазон 5 ГГц, якщо доступно."</string>
@@ -1398,6 +1445,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB завершено"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Торкніться, щоб вимкнути налагоджувач USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Виберіть, щоб вимкнути налагодження за USB"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Рідина або сміття в USB-порту"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт автоматично вимкнено. Торкніться, щоб дізнатися більше."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Можна безпечно використовувати USB-порт"</string>
@@ -1440,8 +1491,7 @@
     <string name="ext_media_init_action" msgid="7952885510091978278">"Налаштувати"</string>
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"Відключити"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"Переглянути"</string>
-    <!-- no translation found for ext_media_seamless_action (6575980560886881233) -->
-    <skip />
+    <string name="ext_media_seamless_action" msgid="6575980560886881233">"Змініть вихід"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"Немає пристрою <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_missing_message" msgid="4012389235250987930">"Вставте пристрій знову"</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Переміщення додатка <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1974,8 +2024,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Торкніться, щоб розблокувати"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Під’єднано до пристрою <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Торкніться, щоб переглянути файли"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Закріпити"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Відкріпити"</string>
     <string name="app_info" msgid="6856026610594615344">"Про додаток"</string>
     <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Запуск демонстрації…"</string>
@@ -2068,6 +2116,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Сповіщення про послідовнсть дій"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Акумулятор може розрядитися раніше ніж зазвичай"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Режим економії заряду акумулятора активовано для збільшення часу його роботи"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Папка"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Додаток Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Файл"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 22fbd56..52a1bbc 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"‏Wi-Fi کالنگ"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"آف"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"‏Wi-Fi ترجیحی"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"موبائل ترجیحی"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"‏صرف Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : فارورڈ نہیں کی گئی"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"بگ کی اطلاع"</string>
     <string name="global_action_logout" msgid="935179188218826050">"سیشن ختم کریں"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"اسکرین شاٹ"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"بگ کی اطلاع لیں"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"ایک ای میل پیغام کے بطور بھیجنے کیلئے، یہ آپ کے موجودہ آلہ کی حالت کے بارے میں معلومات جمع کرے گا۔ بگ کی اطلاع شروع کرنے سے لے کر بھیجنے کیلئے تیار ہونے تک اس میں تھوڑا وقت لگے گا؛ براہ کرم تحمل سے کام لیں۔"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"متعامل رپورٹ"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"زیادہ تر حالات میں اسے استعمال کریں۔ یہ آپ کو رپورٹ کی پیش رفت کا پتہ رکھنے، مسئلہ سے متعلق زیادہ تفصیلات درج کرنے اور اسکرین شاٹس لینے کی اجازت دیتا ہے۔ شاید یہ کچھ ایسے کم استعمال ہونے والے سیکشنز کو خارج کر دے جو اطلاع کرنے میں زیادہ وقت لگاتے ہیں۔"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"مقام"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"اس آلہ کے مقام تک رسائی حاصل کریں"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو اس آلہ کے مقام تک رسائی کی اجازت دیں؟"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"جب آپ ایپ استعمال کریں گے تبھی ایپ کو مقام تک رسائی حاصل ہوگی۔"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"‏‎&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;‎ کو ہمیشہ اس آلہ کے مقام تک رسائی کرنے کی اجازت دیں؟"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"اگرچہ آپ ایپ استعمال نہ کر رہے ہوں تب بھی ایپ کو ہمیشہ مقام تک رسائی حاصل ہوگی۔"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"کیلنڈر"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"اپنے کیلنڈر تک رسائی حاصل کریں"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو آپ کے کیلنڈر تک رسائی کی اجازت دیں؟"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو آپ کی موسیقی تک رسائی کی اجازت دیں؟"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"تصاویر اور ویڈیوز"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"اپنی تصاویر اور ویڈیوز تک رسائی حاصل کریں"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو ٹیگ کردہ مقامات سمیت آپ کی تصاویر اور ویڈیوز تک رسائی کی اجازت دیں؟"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ونڈو مواد بازیافت کرنے کی"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"کسی ایسی ونڈو کے مواد کا معائنہ کریں جس کے ساتھ آپ تعامل کر رہے ہیں۔"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ٹچ کے ذریعے دریافت کریں کو آن کرنے کی"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"‏ایپ کو Near Field Communication (NFC)‎ ٹیگز، کارڈز اور ریڈرز کے ساتھ مواصلت کرنے کی اجازت دیٹا ہے۔"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"اپنے اسکرین لاک کو غیر فعال کریں"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ایپ کو کلیدی لاک اور کسی بھی متعلقہ پاس ورڈ سیکیورٹی کو غیر فعال کرنے کی اجازت دیتا ہے۔ مثلاً، کوئی آنے والی فون کال موصول ہونے کے وقت فون کلیدی لاک کو غیر فعال کرتا ہے، پھر کال پوری ہوجانے پر کلیدی لاک کو دوبارہ فعال کردیتا ہے۔"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"اسکرین لاک پیچیدگی کی درخواست کریں"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"اپپ کو اسکرین لاک کی پیچیدگی (مُشکل، درمیانی، آسان یا کوئی نہیں) کو جاننے کی اجازت دیتا ہے، جو لمبائی کی ممکنہ حد اور اسکرین لاک کے قسم کو بتاتا ہے۔ اپپ صارفین کو مشوره بھی دے سکتی ہے کہ وہ اسکرین لاک کو مخصوس لیول تک اپ ڈیٹ کرتے ہیں لیکن صارفین آزادانہ طور پر نظر انداز اور نیویگیٹ کر سکتے ہیں۔ یاد رکھیں کہ اسکرین لاک کو پلین ٹیکسٹ میں اسٹور نہیں کیا گیا ہے اس لیے اپپ صحیح پاس ورڈ نہیں جانتی ہے۔"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"بایومیٹرک ہارڈ ویئر استعمال کریں"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"ایپ کو توثیق کے لیے بایومیٹرک ہارڈ ویئر استعمال کرنے کی اجازت دیتا ہے"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"فنگر پرنٹ ہارڈ ویئر کا نظم کریں"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ایپ کو چہرے کی تمثیلات شامل اور حذف کرنے کے طریقوں کو کالعدم قرار دینے کی اجازت دیتا ہے۔"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"چہرے کی توثیق کا ہارڈویئر استعمال کریں"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"ایپ کو توثیق کیلئے چہرے کا ہارڈ ویئر استعمال کرنے کی اجازت دیتا ہے"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"چہرے پر کارروائی نہیں ہو سکی۔ دوبارہ کوشش کریں۔"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"چہرے پر بہت زیادہ روشنی ہے۔ براہ کرم کم روشنی میں کوشش کریں۔"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"چہرے پر روشنی بہت کم ہے۔ براہ کرم روشنی بڑھائیں۔"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"براہ کرم سینسر کو چہرے سے تھوڑا دور رکھیں۔"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"براہ کرم سینسر کو چہرے سے تھوڑا قریب رکھیں۔"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"براہ کرم سینسر کو تھوڑا اوپر کریں۔"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"براہ کرم سینسر کو تھوڑا نیچے کریں۔"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"براہ کرم سینسر کو دائیں طرف کریں۔"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"براہ کرم سینسر کو بائیں طرف کریں۔"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"براہ کرم سینسر کی طرف دیکھیں۔"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"کسی چہرے کا پتہ نہیں چلا۔"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"کافی حرکت ہو رہی ہے۔"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"براہ کرم اپنے چہرے کو دوبارہ مندرج کریں۔"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"کسی اور کے چہرے کا پتا چل رہا ہے۔"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"کافی ملتا جلتا ہے، براہ کرم اپنا پوز بدلیں۔"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"براہ کرم کیمرے کی طرف چہرے کو بالکل سیدھا رکھیں۔"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"براہ کرم کیمرے کی طرف چہرے کو بالکل سیدھا رکھیں۔"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"براہ کرم اپنا سر عمودی طور پر سیدھا کریں۔"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"براہ کرم اپنے چہرے سے کور ہٹائیں۔"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"چہرے کا ہارڈویئر دستیاب نہیں ہے۔"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"چہرہ پہچانے کی میعاد ختم ہو گئی۔ دوبارہ کوشش کریں۔"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"چہرے کو اسٹور نہیں کیا جا سکتا۔"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"چہرے پر ہونے والی کارروائی منسوخ ہو گئی۔"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"صارف نے چہرے کی تصدیق کو مسترد کر دیا۔"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"کافی زیادہ کوششیں کی گئیں۔ دوبارہ کوشش کریں۔"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"کافی زیادہ کوششیں کی گئیں۔ چہرے کی توثیق منسوخ ہو گئی۔"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"دوبارہ کوشش کریں۔"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"کوئی بھی چہرہ مندرج نہیں ہے۔"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"اس آلہ میں چہرے کی تصدیق کرنے والا سینسر نہیں ہے۔"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"چہرہ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> کھوليں"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> محفوظ کیے بغیر بند ہو جائے گی"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> میموری کی حد سے تجاوز کرگئی"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"ہیپ ڈمپ جمع ہو گیا ہے۔ اشتراک کرنے کیلئے تھپتھپائیں۔"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"ہیپ ڈمپ کا اشتراک کریں؟"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"کارروائی <xliff:g id="PROC">%1$s</xliff:g> اپنی کارروائی کی میموری کی حد <xliff:g id="SIZE">%2$s</xliff:g> سے تجاوز کر گئی ہے۔ آپ کیلئے ایک ہیپ ڈمپ اس کے ڈیولپر سے اشتراک کرنے کیلئے دستیاب ہے۔ احتیاط برتیں: اس ہیپ ڈمپ میں آپ کی ایسی ذاتی معلومات میں سے کوئی بھی شامل ہو سکتی ہے جس تک ایپلیکیشن کو رسائی ہے۔"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"متن کیلئے ایک کارروائی منتخب کریں"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"رنگر والیوم"</string>
     <string name="volume_music" msgid="5421651157138628171">"میڈیا والیوم"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"تمام نیٹ ورکس دیکھنے کیلئے تھپتھپائيں"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"منسلک کریں"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"سبھی نیٹ ورکس"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"‏<xliff:g id="NAME">%s</xliff:g> کا تجویز کردہ ایک Wi‑Fi نیٹ ورک دستیاب ہے"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"کیا آپ <xliff:g id="NAME">%s</xliff:g> کے تجویز کردہ نیٹ ورکس سے منسلک ہونا چاہتے ہیں؟"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ہاں"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"نہیں"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"‏Wi‑Fi از خود آن ہو جائے گا"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"نیٹ ورک میں سائن ان کریں"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"‏Wi-Fi کو انٹرنیٹ تک رسائی نہیں ہے"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"اختیارات کیلئے تھپتھپائیں"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"منسلک ہے"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"اپنے ہاٹ اسپاٹ کی ترتیبات میں تبدیلیاں"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"آپ کا ہاٹ اسپات بینڈ تبدیل ہو گیا۔"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"‏یہ آلہ صرف 5GHz کے لئے آپ کی ترجیح کا تعاون نہیں کرے گا۔ بلکہ 5GHz بینڈ کے دستیاب ہونے پر اس کا استعمال کرے گا۔"</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏USB ڈیبگ کرنا مربوط ہو گیا"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"‏USB ڈیبگنگ آف کرنے کے لیے تھپتھپائیں"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"‏USB ڈیبگ کرنے کو غیر فعال کرنے کیلئے منتخب کریں۔"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏USB پورٹ میں سیال یا دھول ہے"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏USB پورٹ خودکار طور پر غیر فعال کر دیا گیا۔ مزید جاننے کیلئے تھپتھپائیں۔"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"‏USB پورٹ کا استعمال محفوظ ہے"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"دفتری پروفائل غیر مقفل کرنے کیلئے تھپتھپائیں"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> سے منسلک"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"فائلوں کو دیکھنے کیلئے تھپتھپائیں"</string>
-    <string name="pin_target" msgid="3052256031352291362">"پن کریں"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"پن ہٹائیں"</string>
     <string name="app_info" msgid="6856026610594615344">"ایپ کی معلومات"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"ڈیمو شروع ہو رہا ہے…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"روٹین موڈ معلومات کی اطلاع"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"معمول چارج سے پہلے بیٹری ختم ہو سکتی ہے"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"بیٹری لائف کو بڑھانے کے لیے بیٹری سیور کو فعال کر دیا گیا ہے"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"فولڈر"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"‏Android ایپلیکیشن"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"فائل"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index eaf81d7..92d7675 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi chaqiruv"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWi-Fi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"O‘chiq"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi afzalligi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobil internet afzalligi"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Faqat Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yo‘naltirilmadi"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Nosozlik haqida ma’lumot berish"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Seansni yakunlash"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skrinshot"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Xatoliklar hisoboti"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Qurilmangiz holati haqidagi ma’lumotlar to‘planib, e-pochta orqali yuboriladi. Hisobotni tayyorlash biroz vaqt olishi mumkin."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktiv hisobot"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Bundan maxsus vaziyatlarda foydalaning. Bu hisobot jarayonini kuzatish imkonini beradi, muammo haqida batafsil ma’lumotlarni ko‘rishingiz va skrinshotlar olishingiz mumkin bo‘ladi. Hisobot uchun ko‘p vaqt oladigan kam ishlatiladigan bo‘limlar qoldirib ketilishi mumkin."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Joylashuv"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"shu qurilmaning joylashuvi haqidagi axborotga kirish"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uchun bu qurilmaning joylashuvi haqidagi axborotdan foydalanishiga ruxsat berilsinmi?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Bu ilovadan foydalanilayotdangina u joylashuv axborotidan foydalana oladi."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uchun bu qurilmaning joylashuvi haqidagi axborotdan foydalanishiga ruxsat berilsinmi?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Bu ilovadan foydalanilmaganda ham u doim joylashuv axborotidan foydalana oladi."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Taqvim"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"taqvimingizga kirish"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uchun taqvimingizga ruxsat berilsinmi?"</string>
@@ -314,9 +320,12 @@
     <string name="permgrouplab_aural" msgid="965607064083134896">"Musiqa"</string>
     <string name="permgroupdesc_aural" msgid="4870189506255958055">"musiqaga kirish"</string>
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uchun musiqangizga kirishga ruxsat berilsinmi?"</string>
-    <string name="permgrouplab_visual" msgid="6477382108771145134">"Surat va videolar"</string>
+    <string name="permgrouplab_visual" msgid="6477382108771145134">"Suratlar va videolar"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"surat va videolarga kirish"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ilovasi uchun surat va videolaringizga, jumladan, teglangan joylarga ham ruxsat berilsinmi?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Oynadagi kontentni o‘qiydi"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Joriy oynadagi kontent mazmunini aniqlaydi."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Teginib o‘rganish xizmatini yoqadi"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Ilova qisqa masofali aloqa (NFC) texnologiyasi yordamida NFC yorliqlari, kartalar va o‘qish moslamalari bilan ma’lumot almashishi mumkin."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ekran qulfini o‘chirib qo‘yish"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Ilovaga ekran qulfini va har qanday parol  yordamidagi xavfsizlik himoyalarini o‘chirishga ruxsat beradi. Masalan, kirish qo‘ng‘irog‘ida telefon ekran qulfini o‘chiradi va qo‘ng‘iroq tugashi bilan qulfni yoqadi."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"ekran qulfi qiyinligi darajasi haqida soʻrov"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Ilova ekran qulfining qiyinlik darajasi (yuqori, oʻrta, past yoki hech qanday), jumladan, qulf turi va parol uzunligi haqida axborotga ruxsat oladi. Bundan tashqari, foydalanuvchilarga qulflash qiyinligi darajasini oshirish taklif etiladi. Bu tavsiyalar majburiy emas. Parollar ochiq matn sifatida saqlanmaydi va ilova uni ocha olmaydi."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"biometrik sensordan foydalanish"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Haqiqiylikni tekshirish uchun biometrik sensordan foydalanish imkonini beradi"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"barmoq izi skanerini boshqarish"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Ilova foydalanish uchun yuz namunalarini qo‘shish va o‘chirish usullarini tatbiq qilishi mumkin."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"yuzni aniqlash qurilmasidan foydalanish"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Haqiqiylikni tekshirish uchun skanerdan foydalanish imkonini beradi"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Yuz aniqlanmadi. Qaytadan urining."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Yuz juda yorqin. Yorug‘likni kamaytiring."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Yuz juda xira. Yorug‘likni oshiring."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Qurilmani yuzingizdan uzoqroq tuting."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Qurilmani yuzga yaqin tuting."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Qurilmani teparoq ko‘taring."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Qurilmani pastroq tushiring."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Qurilmani o‘ngroq suring."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Qurilmani chaproq suring."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Qurilma kamerasiga qarang."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Yuz aniqlanmadi."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Qurilmani qimirlatmang."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Yuzingizni qaytadan qayd qildiring."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Boshqa yuz aniqlandi."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Yuz ifodasi oldingiday. Holatingizni oʻzgartiring."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Kameraga tik qarang."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Kameraga tik qarang."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Boshingizni tik tuting."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Yuzingizni oching."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Yuzni aniqlash uchun qurilma mavjud emas."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Yuzni aniqlash vaqti tugadi. Qaytadan urining."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Aniqlangan yuz saqlanmadi."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Yuzni aniqlash bekor qilindi."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Yuz tekshiruvi bekor qilindi."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Juda ko‘p urinildi. Keyinroq qaytadan urining."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Juda ko‘p urinildi. Skaner faolsizlantirildi."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Qaytadan urining."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Hech qanday yuz qayd qilinmagan."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Bu qurilmada yuzni aniqlash uchun skaner mavjud emas."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Yuz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"<xliff:g id="NEW_APP">%1$s</xliff:g> ilovasini ochish"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> saqlanmasdan yopiladi"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> foydalanish uchun ajratilgan xotira chegarasidan o‘tib ketdi"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Hip-damp yaratildi. Uni ulashish uchun bosing."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Hip-damp ma’lumotlari bilan ulashasizmi?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> jarayoni o‘zi uchun ajratilgan <xliff:g id="SIZE">%2$s</xliff:g> xotira chegarasidan o‘tib ketdi. Ilova dasturchisi bilan ulashishingiz uchun hip-damp ma’lumotlari yig‘ilib qoldi. Ehtiyot bo\'ling: ushbu hip-dampda ilova uchun foydalanishga ruxsat berilgan shaxsiy ma’lumotlaringiz bo‘lishi mumkin."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Matn uchun amalni tanlash"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Jiringlaganda tovush balandligi"</string>
     <string name="volume_music" msgid="5421651157138628171">"Multimedia tovushi"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Barcha tarmoqlarni ko‘rish uchun bosing"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ulanish"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Barcha tarmoqlar"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g> topgan Wi‑Fi tarmoq mavjud"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"<xliff:g id="NAME">%s</xliff:g> topgan tarmoqqa ulanishni xohlaysizmi?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ha"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Yoʻq"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi avtomatik ravishda yoqiladi"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Tarmoqqa kirish"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi tarmoqda internet aloqasi yo‘q"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Variantlarni ko‘rsatish uchun bosing"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Ulandi"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Hotspot sozlamalari o‘zgartirildi"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Hotspot chastotasi o‘zgartirildi."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Qurilma faqat 5 GGs chastotada ishlay olmaydi. Bu chastotadan imkoniyatga qarab foydalaniladi."</string>
@@ -1355,6 +1402,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozliklarni tuzatish"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"USB orqali nosozliklarni aniqlashni faolsizlantirish uchun bosing"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB orqali nosozliklarni tuzatishni o‘chirib qo‘yish uchun bosing."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB portda suyuqlik yoki parcha bor"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port avtomatik tarzda faolsizlashtirildi. Batafsil axborot olish uchun bosing."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB portdan foydalanish xavfsiz"</string>
@@ -1906,8 +1957,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Qulfini ochish uchun bosing"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> qurilmasiga ulandi"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Fayllarni ko‘rish uchun bosing"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Qadash"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Olib tashlash"</string>
     <string name="app_info" msgid="6856026610594615344">"Ilova haqida"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Demo boshlanmoqda…"</string>
@@ -1998,6 +2047,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Kun tartibi rejimi haqidagi bildirishnoma"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Batareya quvvati odatdagidan ertaroq tugashi mumkin"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Batareya quvvati uzoqroq ishlashi uchun Tejamkor rejim yoqildi"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Jild"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android ilova"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fayl"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index d7effc0..a2f8639 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WLAN 通话"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"关闭"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"首选 WLAN"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"首选移动数据网络"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"仅限 WLAN"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:无法转接"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:<xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"错误报告"</string>
     <string name="global_action_logout" msgid="935179188218826050">"结束会话"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"屏幕截图"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"提交错误报告"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"这会收集有关当前设备状态的信息,并以电子邮件的形式进行发送。从开始生成错误报告到准备好发送需要一点时间,请耐心等待。"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"互动式报告"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"在大多数情况下,建议您使用此选项,以便追踪报告的生成进度,输入与相应问题相关的更多详细信息,以及截取屏幕截图。系统可能会省略掉一些不常用的区段,从而缩短生成报告的时间。"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"位置信息"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"获取此设备的位置信息"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"要允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”获取此设备的位置信息吗?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"只有当您使用该应用时,该应用才有权获取位置信息。"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"一律允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”获取此设备的位置信息吗?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"即使您并未使用该应用,该应用也将始终有权获取位置信息。"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"日历"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"访问您的日历"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问您的日历吗?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问您的音乐吗?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"照片和视频"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"访问您的照片和视频"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问您的照片和视频(包括标记的位置)吗?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"检索窗口内容"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"检测您正访问的窗口的内容。"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"启用触摸浏览"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"允许应用与近距离无线通信(NFC)标签、卡和读取器通信。"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"停用屏幕锁定"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"允许该应用停用键锁以及任何关联的密码安全措施。例如,让手机在接听来电时停用键锁,在通话结束后重新启用键锁。"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"请求屏幕锁定复杂度"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"允许应用了解屏幕锁定复杂度(高、中、低或无),即屏幕锁定的可能长度范围和类型。应用还可以建议用户将屏幕锁定更新为特定复杂度,但用户可以随意选择忽略该建议并离开应用。请注意,系统不会以纯文字形式存储屏幕锁定选项的内容,因此应用不会知道确切密码。"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"使用生物特征硬件"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"允许该应用使用生物特征硬件进行身份验证"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"管理指纹硬件"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"允许该应用调用方法来添加和删除可用的人脸模板。"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"使用人脸身份验证硬件"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"允许该应用使用人脸身份验证硬件进行身份验证"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"无法识别此面孔,请重试。"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"面部太亮,请在光线适中的环境下重试。"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"面部太暗,请不要挡住光线。"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"请将传感器移到距离面孔较远处。"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"请将传感器靠近面孔。"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"请上移传感器。"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"请下移传感器。"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"请右移传感器。"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"请左移传感器。"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"请目视传感器。"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"未检测到任何面孔。"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"请将设备拿稳。"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"请重新注册您的面孔。"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"检测到其他面孔。"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"与先前的姿势太相近,请换一个姿势。"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"请直视相机。"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"请直视相机。"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"请将头摆正。"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"请露出整张脸。"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"无法使用面孔识别硬件"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"面孔处理操作超时,请重试。"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"无法存储面孔。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"面孔处理操作已取消。"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"用户已取消面孔验证。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"尝试次数过多,请稍后重试。"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"尝试次数过多,系统已停用人脸身份验证功能。"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"请重试。"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"未注册任何面孔。"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"此设备没有人脸身份验证传感器。"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"面孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"打开<xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g>将会在不保存的情况下关闭"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g>占用的内存已超出限制"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"已收集堆转储数据。点按即可分享。"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"要共享堆转储数据吗?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g>进程占用的内存已超出限制 (<xliff:g id="SIZE">%2$s</xliff:g>)。您可以将收集的堆转储数据共享给相应的开发者。请注意:此数据中可能包含该应用有权存取的您的个人信息。"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"选择要对文字执行的操作"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"铃声音量"</string>
     <string name="volume_music" msgid="5421651157138628171">"媒体音量"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"点按即可查看所有网络"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"连接"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"所有网络"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g>建议的 WLAN 网络可以使用"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"要连接到<xliff:g id="NAME">%s</xliff:g>建议的网络吗?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"是"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"否"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WLAN 将自动开启"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"登录到网络"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"此 WLAN 网络无法访问互联网"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"点按即可查看相关选项"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"已连接"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"您的热点设置已变更"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"您的热点频段已变更。"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"此设备不支持您的偏好设置(仅限 5GHz),而且会在 5GHz 频段可用时使用该频段。"</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到 USB 调试"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"点按即可关闭 USB 调试"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"选择即可停用 USB 调试功能。"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 端口中有液体或碎屑"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 端口已自动停用。点按即可了解详情。"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"现在可安全使用 USB 端口"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"点按即可解锁工作资料"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"已连接到<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"点按即可查看文件"</string>
-    <string name="pin_target" msgid="3052256031352291362">"固定"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"取消固定"</string>
     <string name="app_info" msgid="6856026610594615344">"应用信息"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"正在启动演示模式…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"日常安排模式信息通知"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"电池电量可能会在您平时的充电时间之前耗尽"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"已启用省电模式以延长电池续航时间"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"文件夹"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android 应用"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"文件"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 20231fc..c559ec2 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi 通話"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"關閉"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"首選 Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"流動數據優先"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"只限 Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:尚未轉接"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:<xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
     <string name="global_action_logout" msgid="935179188218826050">"結束工作階段"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"擷取螢幕畫面"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"取得錯誤報告"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"這會收集您目前裝置狀態的相關資訊,並以電郵傳送給您。從開始建立錯誤報告到準備傳送需要一段時間,請耐心等候。"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"互動報告"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"在大部分情況下,建議您使用此選項,以便追蹤報告進度、輸入更多與問題相關的詳細資料,以及擷取螢幕畫面。系統可能會省略一些不常用的部分,以縮短產生報告的時間。"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"位置資訊"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"存取此裝置的位置"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;存取此裝置的位置資訊嗎?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"只有在您使用此應用程式時,應用程式才能存取位置資訊。"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"要一律允許「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」存取此裝置的位置資訊嗎?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"即使您沒有使用此應用程式,應用程式亦一直能夠存取位置資訊。"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"日曆"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"存取您的日曆"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;存取您的日曆嗎?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"要允許「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」存取您的音樂嗎?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"相片和影片"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"存取您的相片和影片"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;存取您的相片和影片 (包括標記的位置資訊) 嗎?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查您使用中的視窗內容。"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"開啟「輕觸探索」功能"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"允許應用程式使用近距離無線通訊 (NFC) 標記、卡片及讀取程式進行通訊。"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"停用螢幕上鎖"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"允許應用程式停用按鍵鎖定以及其他相關的密碼安全措施。例如:手機收到來電時停用按鍵鎖定,通話結束後重新啟用按鍵鎖定。"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"要求螢幕鎖定複雜程度"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"允許應用程式瞭解螢幕鎖定的複雜程度 (高、中、低或無),這項資料說明了螢幕鎖定的可能長度範圍和類型。應用程式亦能建議使用者將螢幕鎖定更新至某個複雜程度,但使用者可以隨意忽略並離開。請注意,螢幕鎖定並非以純文字儲存,因此應用程式不知道確切的密碼。"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"使用生物識別硬件"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"允許應用程式使用生物識別硬件驗證"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"管理指紋硬件"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"允許應用程式調用方法,以加入和刪除可用的臉孔範本。"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"使用臉孔驗證硬件"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"允許應用程式使用臉孔驗證硬件來驗證"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"無法識別臉孔,請再試一次。"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"臉孔太光亮,請在較暗的光線下嘗試。"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"臉孔太暗,請尋找更佳光源。"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"請將感應器移離臉孔。"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"請將感應器靠近臉孔。"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"請將感應器向上移。"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"請將感應器向下移。"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"請將感應器向右移。"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"請將感應器向左移。"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"請看著感應器。"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"未偵測到任何臉孔。"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"裝置不夠穩定。"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"請重新註冊臉孔。"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"偵測到不同的臉孔。"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"臉孔位置太相近,請改變您的姿勢。"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"請以更直視的角度看著鏡頭。"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"請以更直視的角度看著鏡頭。"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"請保持頭部垂直。"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"不要遮住臉孔。"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"無法使用臉孔識別硬件。"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"臉孔操作已逾時,請再試一次。"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"無法儲存臉孔。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"臉孔操作已取消。"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"使用者已取消臉孔驗證。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"嘗試次數過多,請稍後再試。"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"嘗試次數過多,臉孔驗證已停用。"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"請再試一次。"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"未註冊任何臉孔。"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"此裝置沒有臉孔驗證感應器。"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"開啟「<xliff:g id="NEW_APP">%1$s</xliff:g>」"</string>
     <string name="new_app_description" msgid="5894852887817332322">"「<xliff:g id="OLD_APP">%1$s</xliff:g>」將會在不儲存的情況下關閉"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> 的記憶體用量已超過限額"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"已收集堆轉儲,輕按即可分享。"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"分享堆轉儲?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"這處理程序 (<xliff:g id="PROC">%1$s</xliff:g>) 的記憶體用量已超過限額 (<xliff:g id="SIZE">%2$s</xliff:g>)。您可將已收集的堆轉儲分享給開發人員。請謹慎,這堆轉儲可包含該應用程式有權存取您的任何個人資料。"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"選擇處理文字的操作"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"鈴聲音量"</string>
     <string name="volume_music" msgid="5421651157138628171">"媒體音量"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕按即可查看所有網絡"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"所有網絡"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"<xliff:g id="NAME">%s</xliff:g>建議的 Wi‑Fi 網絡現已可用"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"要連線至「<xliff:g id="NAME">%s</xliff:g>」建議的網絡嗎?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"是"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"否"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi 將會自動開啟"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"登入網絡"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi 並未連接互聯網"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"輕按即可查看選項"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"已連接"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"您的熱點設定變更"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"您的熱點頻段已變更。"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"此裝置不支援只限 5 GHz 的偏好設定,但會在 5 GHz 頻段可用時採用。"</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"輕按即可關閉 USB 偵錯功能"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取即可停用 USB 偵錯。"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或碎片"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 連接埠已自動停用。輕按即可瞭解詳情。"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"USB 連接埠可安全使用"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"輕按即可將工作設定檔解鎖"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"已連線至 <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"輕按即可查看檔案"</string>
-    <string name="pin_target" msgid="3052256031352291362">"固定"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"取消固定"</string>
     <string name="app_info" msgid="6856026610594615344">"應用程式資料"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"正在開始示範…"</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"「日常安排模式」資料通知"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"電量可能會在日常充電前耗盡"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"「省電模式」已啟用,以便延長電池壽命"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"資料夾"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android 應用程式"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"檔案"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 8fa7681..77bbcb2 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Wi-Fi 通話"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"關閉"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi 優先"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"行動網路優先"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"只限 Wi-Fi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:未轉接"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
     <string name="global_action_logout" msgid="935179188218826050">"結束"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"擷取螢幕畫面"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"取得錯誤報告"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"這會收集你目前裝置狀態的相關資訊,以便透過電子郵件傳送。從錯誤報告開始建立到準備傳送的這段過程可能需要一點時間,敬請耐心等候。"</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"互動式報告"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"在一般情況下,建議你使用這個選項,以便追蹤報告產生進度、輸入更多與問題相關的資訊,以及擷取螢幕畫面。系統可能會省略部分較少使用的區段,藉此縮短報告產生時間。"</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"位置"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"存取這台裝置的位置資訊"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」存取這個裝置的位置資訊嗎?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"該應用程式只有在你使用時,才能存取位置資訊。"</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"要一律允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;存取這個裝置的位置資訊嗎?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"該應用程式即使在你未使用時,也隨時可以存取位置資訊。"</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"日曆"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"存取你的日曆"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」存取你的日曆嗎?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;存取你的音樂嗎?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"相片和影片"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"存取你的相片和影片"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;存取你的相片和影片 (包括加上標記的地點) 嗎?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查你存取的視窗內容。"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"啟用輕觸探索功能"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"允許應用程式與近距離無線通訊 (NFC) 電子感應標籤、卡片及感應器進行通訊。"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"停用螢幕鎖定"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"允許應用程式停用按鍵鎖定以及其他相關的密碼安全性功能。例如:手機收到來電時停用按鍵鎖定,通話結束後重新啟用按鍵鎖定。"</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"要求螢幕鎖定的複雜度"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"允許應用程式記住螢幕鎖定的複雜度 (高、中、低或無),即螢幕鎖定的可能長度範圍和類型。這樣一來,應用程式還能建議使用者將螢幕鎖定更新為特定複雜度,但使用者可選擇忽略建議並離開應用程式。請注意,系統不會以純文字格式儲存螢幕鎖定選項的內容,因此應用程式不會知道確切密碼。"</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"使用生物特徵硬體"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"允許應用程式使用生物特徵硬體進行驗證"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"管理指紋硬體"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"允許應用程式呼叫方法來新增及移除可用的臉孔範本。"</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"使用臉孔驗證硬體"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"允許應用程式使用臉孔驗證硬體進行驗證"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"無法識別臉孔,請再試一次。"</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"臉孔過亮。請移至光線適中的場所,然後再試一次。"</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"臉孔過暗。請增添光源,然後再試一次。"</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"請將感應器移到距離臉孔較遠處。"</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"請將感應器靠近臉孔。"</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"請將感應器往上移動。"</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"請將感應器往下移動。"</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"請將感應器往右移動。"</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"請將感應器往左移動。"</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"請直視感應器。"</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"未偵測到任何臉孔。"</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"請將裝置拿穩。"</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"請重新註冊你的臉孔。"</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"偵測到其他臉孔。"</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"與先前的姿勢太相似,請換一個姿勢。"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"請直視鏡頭。"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"請直視鏡頭。"</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"請將頭擺正。"</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"請不要遮住臉。"</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"無法使用臉部辨識硬體。"</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"臉孔處理作業逾時,請再試一次。"</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"無法儲存臉孔。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"臉孔處理作業已取消。"</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"使用者已取消臉孔驗證。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"嘗試次數過多,請稍後再試。"</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"嘗試次數過多,臉孔驗證功能已停用。"</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"請再試一次。"</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"未登錄任何臉孔。"</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"這個裝置沒有臉孔驗證感應器。"</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"開啟「<xliff:g id="NEW_APP">%1$s</xliff:g>」"</string>
     <string name="new_app_description" msgid="5894852887817332322">"「<xliff:g id="OLD_APP">%1$s</xliff:g>」即將直接關閉不儲存"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> 已超出記憶體上限"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"已取得記憶體快照資料。輕觸即可分享。"</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"分享記憶體快照資料?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"程序「<xliff:g id="PROC">%1$s</xliff:g>」已超出 <xliff:g id="SIZE">%2$s</xliff:g> 的程序記憶體上限。系統已產生記憶體快照資料,可供你與開發人員分享。請注意:記憶體快照資料中可能包含應用程式可存取的個人資訊。"</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"選取傳送文字內容的方式"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"鈴聲音量"</string>
     <string name="volume_music" msgid="5421651157138628171">"媒體音量"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕觸即可查看所有網路"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"所有網路"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"「<xliff:g id="NAME">%s</xliff:g>」建議的 Wi‑Fi 網路可以使用"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"確定要連上「<xliff:g id="NAME">%s</xliff:g>」建議的網路嗎?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"是"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"否"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi 將自動開啟"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"登入網路"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"Wi-Fi 沒有網際網路連線"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"輕觸即可查看選項"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"已連線"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"無線基地台設定變更"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"你的無線基地台頻帶已變更。"</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"這個裝置不支援你的偏好設定 (僅限 5GHz),而是會在 5GHz 可用時使用該頻帶。"</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"輕觸即可關閉 USB 偵錯功能"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取這個選項以停用 USB 偵錯功能。"</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或灰塵"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"系統已自動停用 USB 連接埠。輕觸即可瞭解詳情。"</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"現在可安全使用 USB 連接埠"</string>
@@ -1396,8 +1447,7 @@
     <string name="ext_media_init_action" msgid="7952885510091978278">"設定"</string>
     <string name="ext_media_unmount_action" msgid="1121883233103278199">"退出"</string>
     <string name="ext_media_browse_action" msgid="8322172381028546087">"探索"</string>
-    <!-- no translation found for ext_media_seamless_action (6575980560886881233) -->
-    <skip />
+    <string name="ext_media_seamless_action" msgid="6575980560886881233">"切換輸出裝置"</string>
     <string name="ext_media_missing_title" msgid="620980315821543904">"找不到 <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_missing_message" msgid="4012389235250987930">"請再次插入裝置"</string>
     <string name="ext_media_move_specific_title" msgid="1471100343872375842">"正在移動「<xliff:g id="NAME">%s</xliff:g>」"</string>
@@ -1906,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"輕觸即可將工作資料夾解鎖"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"已連線至 <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"輕觸即可查看檔案"</string>
-    <string name="pin_target" msgid="3052256031352291362">"固定"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"取消固定"</string>
     <string name="app_info" msgid="6856026610594615344">"應用程式資訊"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"正在啟動示範模式..."</string>
@@ -1998,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"日常安排模式資訊通知"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"電池電力可能會在你平常的充電時間前耗盡"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"已啟用節約耗電量模式以延長電池續航力"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"資料夾"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Android 應用程式"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"檔案"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 93280cb..ec66a72 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -141,8 +141,10 @@
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"Ukushaya kwe-WiFi"</string>
     <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
     <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Valiwe"</string>
-    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Kuncanyelwa i-Wi-Fi"</string>
-    <string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Kuncanyelwa iselula"</string>
+    <!-- no translation found for wfc_mode_wifi_preferred_summary (7335489823608689868) -->
+    <skip />
+    <!-- no translation found for wfc_mode_cellular_preferred_summary (7081742743152286290) -->
+    <skip />
     <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"I-Wi-Fi kuphela"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Akudlulisiwe"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -228,7 +230,8 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Umbiko wephutha"</string>
     <string name="global_action_logout" msgid="935179188218826050">"Phothula isikhathi"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Isithombe-skrini"</string>
-    <string name="bugreport_title" msgid="2667494803742548533">"Thatha umbiko wesiphazamiso"</string>
+    <!-- no translation found for bugreport_title (5981047024855257269) -->
+    <skip />
     <string name="bugreport_message" msgid="398447048750350456">"Lokhu kuzoqoqa ulwazi mayelana nesimo samanje sedivayisi yakho, ukuthumela imilayezo ye-imeyili. Kuzothatha isikhathi esincane kusuka ekuqaleni umbiko wesiphazamiso uze ulungele ukuthunyelwa; sicela ubekezele."</string>
     <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Umbiko obandakanyayo"</string>
     <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Sebenzisa lokhu ngaphansi kwezimo eziningi. Kukuvumela ukuthi ulandele ukuqhubeka kombiko, ufake imininingwane engeziwe mayelana nenkinga, futhi uthathe izithombe zikrini. Ingasika okunye ukukhetha okuncane okuthatha isikhathi eside ukubika."</string>
@@ -281,9 +284,12 @@
     <string name="permgrouplab_location" msgid="7275582855722310164">"Indawo"</string>
     <string name="permgroupdesc_location" msgid="1346617465127855033">"finyelela kundawo yale divayisi"</string>
     <string name="permgrouprequest_location" msgid="3788275734953323491">"Vumela i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukuthi ingene kundawo yale divayisi?"</string>
-    <string name="permgrouprequestdetail_location" msgid="1113400215566814664">"Uhlelo lokusebenza luzoba nokufinyelela kundawo kuphela uma usebenzisa uhlelo lokusebenza."</string>
-    <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"Hlala uvumela i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukuthi ifinyelele indawo yale divayisi?"</string>
-    <string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"Uhlelo lokusebenza luzohlala lunokufinyelela kundawo, nanoma ungasebenzisi uhlelo lokusebenza."</string>
+    <!-- no translation found for permgrouprequestdetail_location (1347189607421252902) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequest_location (5039063878675613235) -->
+    <skip />
+    <!-- no translation found for permgroupbackgroundrequestdetail_location (4597006851453417387) -->
+    <skip />
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Ikhalenda"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"finyelela kukhalenda yakho"</string>
     <string name="permgrouprequest_calendar" msgid="289900767793189421">"Vumela i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukuthi ifinyelele kukhalenda yakho?"</string>
@@ -316,7 +322,10 @@
     <string name="permgrouprequest_aural" msgid="6787926123071735620">"Vumela i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukuthi ifinyelele umculo wakho?"</string>
     <string name="permgrouplab_visual" msgid="6477382108771145134">"Izithombe Namavidiyo"</string>
     <string name="permgroupdesc_visual" msgid="3415827902566663546">"finyelela izithombe zakho namavidiyo"</string>
-    <string name="permgrouprequest_visual" msgid="3043752127595243314">"Vumela &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukufinyelela izithombe zakho namavidiyo, kufaka phakathi izindawo ezimakiwe?"</string>
+    <!-- no translation found for permgrouprequest_visual (4926581398380334943) -->
+    <skip />
+    <!-- no translation found for permgrouprequestdetail_visual (3827237829805228971) -->
+    <skip />
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Thola okuqukethwe kwewindi"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Hlola okuqukethwe kwewindi ohlanganyela nalo."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vula ukuhlola ngokuthinta"</string>
@@ -509,8 +518,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Ivuela uhlelo lokusebenza ukuthi ixhumane ne-Near Field Communication (NFC) amathegi, amakhadi kanye nezinhlelo zokufunda."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"khubaza ukukhiya kwakho iskrini"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Ivumela uhlelo lokusebenza ukukhubaza ukuvala ukhiye nanoma yikuphi ukuphepha kwephasiwedi okuhlobene. Isibonelo, ifoni ikhubaza ukuvala ukhiye lapho ithola ikholi yefoni engenayo, bese inike amandla kabusha ukuvala ukhiye lapho ikholi isiqedile."</string>
-    <string name="permlab_requestScreenLockComplexity" msgid="7028982116060987169">"cela ukuxubana kokukhiya isikrini"</string>
-    <string name="permdesc_requestScreenLockComplexity" msgid="2806396846128185677">"Ivumela uhlelo lokusebenza ukufunda ileveli yokukhiywa kwesikrini (phezulu, phakathi, phansi noma lutho), okubonisa ibanga elinokwenzeka lobubanzi nohlobo lokukhiywa kwesikrini. Uhlelo lokusebenza futhi lingaphakamisa kubasebenzisi ukuthi babuyekeze ukukhiywa kwesikrini kuya kwenye ileveli kodwa abasebenzisi bangaziba kalula bese bazule. Qaphela ukuthi ukhiywa kwesikrini akulondoloziwe embalweni ocacile ukuze uhlelo lokusebenza lingazi iphasiwedi."</string>
+    <!-- no translation found for permlab_requestPasswordComplexity (202650535669249674) -->
+    <skip />
+    <!-- no translation found for permdesc_requestPasswordComplexity (4730994229754212347) -->
+    <skip />
     <string name="permlab_useBiometric" msgid="8837753668509919318">"sebenzisa izingxenyekazi zekhompyutha ze-biometric"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Ivumela uhlelo lokusebenza ukuthi lusebenzise izingxenyekazi zekhompyutha ze-biometric ukuze kuqinisekiswe"</string>
     <string name="permlab_manageFingerprint" msgid="5640858826254575638">"phatha izingxenyekazi zekhompyutha zezigxivizo zeminwe"</string>
@@ -565,37 +576,59 @@
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Ivumela uhlelo lokusebenza ukuthi luhoxise izindlela zokungeza nokususa amathempulethi obuso azosetshenziswa."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"sebenzisa izingxenyekazi zekhompuyutha zokufakazela ubuqiniso kobuso"</string>
     <string name="permdesc_useFaceAuthentication" msgid="5011118722951833089">"Ivumela uhlelo lokusebenza ukuthi lusebenzise ukufakazela ubuqiniso bobuso bezingxenyekazi ukuze kufakazelwe ubuqiniso"</string>
-    <string name="face_acquired_insufficient" msgid="5901287247766106330">"Ayikwazanga ukucubungula ubuso. Sicela uzame futhi."</string>
-    <string name="face_acquired_too_bright" msgid="610606792381297174">"Ubuso bukhanya kakhulu. Sicela uzame ekukhanyeni okuncane."</string>
-    <string name="face_acquired_too_dark" msgid="7229162716976778371">"Ubuso bumnyama kakhulu. Sicela uvule umthombo wokukhanya."</string>
-    <string name="face_acquired_too_close" msgid="1980310037427755293">"Sicela uhambise inzwa kude kunobuso."</string>
-    <string name="face_acquired_too_far" msgid="4494571381828850007">"Sicela ulethe inzwa eduze kobuso."</string>
-    <string name="face_acquired_too_high" msgid="228411096134808372">"Sicela uhambise inzwa phezulu."</string>
-    <string name="face_acquired_too_low" msgid="4539774649296349109">"Sicela uhambise inzwa ngezansi."</string>
-    <string name="face_acquired_too_right" msgid="1650292067226118760">"Sicela uhambise inzwa ngakwesokudla."</string>
-    <string name="face_acquired_too_left" msgid="2712489669456176505">"Sicela uhambise inzwa ngakwesokunxele."</string>
-    <string name="face_acquired_poor_gaze" msgid="8344973502980415859">"Sicela ubheke kunzwa."</string>
-    <string name="face_acquired_not_detected" msgid="5707782294589511391">"Abukho ubuso obutholiwe."</string>
-    <string name="face_acquired_too_much_motion" msgid="470381210701463822">"Ukunyakaza okukhulu kakhulu."</string>
+    <!-- no translation found for face_acquired_insufficient (2767330364802375742) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_bright (5005650874582450967) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_dark (1966194696381394616) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_close (1401011882624272753) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_far (1210969240069012510) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_high (3362395713403348013) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_low (488983581737550912) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_right (941726879175375970) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_left (5873592047381190672) -->
+    <skip />
+    <!-- no translation found for face_acquired_poor_gaze (8471716624377228327) -->
+    <skip />
+    <!-- no translation found for face_acquired_not_detected (4885504661626728809) -->
+    <skip />
+    <!-- no translation found for face_acquired_too_much_motion (3149332171102108851) -->
+    <skip />
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Sicela uphinde ubhalise ubuso bakho."</string>
-    <string name="face_acquired_too_different" msgid="5553210341111255124">"Ubuso obuhlukile butholiwe."</string>
+    <!-- no translation found for face_acquired_too_different (7663983770123789694) -->
+    <skip />
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"Kufana kakhulu, sicela ushintshe ukuma kwakho."</string>
-    <string name="face_acquired_pan_too_extreme" msgid="8203001424525231680">"Sicela ubheke ngokuqondile kukhamera."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="7641326344460439970">"Sicela ubheke ngokuqondile kukhamera."</string>
+    <!-- no translation found for face_acquired_pan_too_extreme (1852495480382773759) -->
+    <skip />
+    <!-- no translation found for face_acquired_tilt_too_extreme (1290820400317982049) -->
+    <skip />
     <string name="face_acquired_roll_too_extreme" msgid="1444829237745898619">"Sicela uqondise ikhanda lakho ngokumile."</string>
-    <string name="face_acquired_obscured" msgid="3055077697850272097">"Sicela uvule ubuso bakho."</string>
+    <!-- no translation found for face_acquired_obscured (5747521031647744553) -->
+    <skip />
+    <!-- no translation found for face_acquired_sensor_dirty (364493868630891300) -->
+    <skip />
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="6255891785768984615">"Izingxenyekazi zekhompuyutha zobuso azitholakali."</string>
-    <string name="face_error_timeout" msgid="4014326147867150054">"Kufinyelelwe kusikhathi sokuvala sobuso. Zama futhi."</string>
+    <!-- no translation found for face_error_timeout (2605673935810019129) -->
+    <skip />
     <string name="face_error_no_space" msgid="8224993703466381314">"Ubuso abukwazi ukugcinwa."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Umsebenzi wobuso ukhanselwe."</string>
     <string name="face_error_user_canceled" msgid="8943921120862164539">"Ukufakazela ubuqiniso kobuso kukhanselwe umsebenzisi"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Imizamo eminingi kakhulu. Zama futhi emuva kwesikhathi."</string>
     <string name="face_error_lockout_permanent" msgid="8198354656746088890">"Imizamo eminingi kakhulu. Ukufakazela ubuqiniso kobuso kukhutshaziwe."</string>
-    <string name="face_error_unable_to_process" msgid="238761109287767270">"Zama futhi."</string>
-    <string name="face_error_not_enrolled" msgid="9166792142679691323">"Abukho ubuso obubhalisiwe."</string>
-    <string name="face_error_hw_not_present" msgid="916085883581450331">"Le divayisi ayinayo inzwa yokufakazela ubuqiniso yobuso."</string>
+    <!-- no translation found for face_error_unable_to_process (4940944939691171539) -->
+    <skip />
+    <!-- no translation found for face_error_not_enrolled (4245760276260427472) -->
+    <skip />
+    <!-- no translation found for face_error_hw_not_present (5296043240874659926) -->
+    <skip />
     <string name="face_name_template" msgid="7004562145809595384">"Ubuso be-<xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1213,9 +1246,16 @@
     <string name="new_app_action" msgid="6694851182870774403">"Vula i-<xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="5894852887817332322">"<xliff:g id="OLD_APP">%1$s</xliff:g> izovala ngaphandle kokulondoloza"</string>
     <string name="dump_heap_notification" msgid="2618183274836056542">"I-<xliff:g id="PROC">%1$s</xliff:g> idlule umkhawulo wememori"</string>
+    <!-- no translation found for dump_heap_ready_notification (1162196579925048701) -->
+    <skip />
     <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Ukulahlwa kwehipu kuqoqiwe. Thepha ukuze wabelane."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Yabelana ngokulahlwa kwehipu?"</string>
-    <string name="dump_heap_text" msgid="4809417337240334941">"Inqubo engu-<xliff:g id="PROC">%1$s</xliff:g> idlule inqubo yayo yomkhawulo wememori ongu-<xliff:g id="SIZE">%2$s</xliff:g>. Ukulahlwa kwehipu kuyatholakala kuwe ukuze wabelane nonjiniyela wayo. Qaphela: lokhu kulahlwa kwehipu kungaqukatha noma yiluphi ulwazi lakho lomuntu siqu uhlelo lokusebenza elinokufinyelela kukho."</string>
+    <!-- no translation found for dump_heap_text (8546022920319781701) -->
+    <skip />
+    <!-- no translation found for dump_heap_system_text (1205466256312104134) -->
+    <skip />
+    <!-- no translation found for dump_heap_ready_text (6759394977904051000) -->
+    <skip />
     <string name="sendText" msgid="5209874571959469142">"Khetha okufanele kwenziwe okomqhafazo"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Ivolumu yesishayeli"</string>
     <string name="volume_music" msgid="5421651157138628171">"Ivolumu yemidiya"</string>
@@ -1254,8 +1294,10 @@
     <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Thepha ukuze ubone onke amanethiwekhi"</string>
     <string name="wifi_available_action_connect" msgid="2635699628459488788">"Xhuma"</string>
     <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Onke amanethiwekhi"</string>
-    <string name="wifi_suggestion_title" msgid="8951405130379148709">"Inethiwekhi ye-Wi-Fi ephakanyiswe u-<xliff:g id="NAME">%s</xliff:g> iyatholakala"</string>
-    <string name="wifi_suggestion_content" msgid="2658317015552324848">"Uyafuna ukuxhumeka kumanethiwekhi aphakanyiswe u-<xliff:g id="NAME">%s</xliff:g>?"</string>
+    <!-- no translation found for wifi_suggestion_title (9099832833531486167) -->
+    <skip />
+    <!-- no translation found for wifi_suggestion_content (5883181205841582873) -->
+    <skip />
     <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yebo"</string>
     <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Cha"</string>
     <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"I-Wi-Fi izovuleka ngokuzenzakalela"</string>
@@ -1267,9 +1309,14 @@
     <string name="network_available_sign_in" msgid="1848877297365446605">"Ngena ngemvume kunethiwekhi"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <string name="wifi_no_internet" msgid="8938267198124654938">"I-Wi-Fi ayinakho ukufinyelela kwe-inthanethi"</string>
+    <!-- no translation found for wifi_no_internet (5198100389964214865) -->
+    <skip />
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Thepha ukuze uthole izinketho"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Kuxhunyiwe"</string>
+    <!-- no translation found for network_partial_connectivity (7774883385494762741) -->
+    <skip />
+    <!-- no translation found for network_partial_connectivity_detailed (1959697814165325217) -->
+    <skip />
     <string name="wifi_softap_config_change" msgid="8475911871165857607">"Ushintsho kuzilungiselelo zakho ze-hotspot"</string>
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"Ibhendi yakho ye-hotspot ishintshile."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"Le divayisi ayisekeli okuncamelayo kwe-5GHz kuphela. Kunalokho, le divayisi izosebenzisa ibhendi ye-5GHz uma itholakala."</string>
@@ -1354,6 +1401,10 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ukulungisa iphutha le-USB kuxhunyiwe"</string>
     <string name="adb_active_notification_message" msgid="7463062450474107752">"Thepha ukuze uvale ukulungisa amaphutha kwe-USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Khetha ukuvimbela ukulungisa iphutha le-USB."</string>
+    <!-- no translation found for test_harness_mode_notification_title (2216359742631914387) -->
+    <skip />
+    <!-- no translation found for test_harness_mode_notification_message (1343197173054407119) -->
+    <skip />
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Uketshezi noma ama-debris kumbobo ye-USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Imbobo ye-USB inqanyulwa ngokuzenzakalela. Thepha ukuze ufunde kabanzi."</string>
     <string name="usb_contaminant_not_detected_title" msgid="4202417484434906086">"Kuphephile ukusebenzisa imbobo ye-USB"</string>
@@ -1905,8 +1956,6 @@
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Thepha ukuze uvule iphrofayela yomsebenzi"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Kuxhumekile ku-<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Thepha ukuze ubuke onke amafayela"</string>
-    <string name="pin_target" msgid="3052256031352291362">"Phina"</string>
-    <string name="unpin_target" msgid="3556545602439143442">"Susa ukuphina"</string>
     <string name="app_info" msgid="6856026610594615344">"Ulwazi lohlelo lokusebenza"</string>
     <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="5268556852031489931">"Iqalisa i-demo..."</string>
@@ -1997,6 +2046,22 @@
     <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"Isaziso solwazi lwe-Routine Mode"</string>
     <string name="dynamic_mode_notification_title" msgid="508815255807182035">"Ibhethri lingaphela ngaphambi kokushaja okuvamile"</string>
     <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Isilondolozi sebhethri siyasebenza ngaphandle kwempilo yebhethri"</string>
+    <!-- no translation found for battery_saver_notification_channel_name (2083316159716201806) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_title (6376147579378764641) -->
+    <skip />
+    <!-- no translation found for battery_saver_sticky_disabled_notification_summary (8090192609249817945) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (2960978289873161288) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (7555713825806482451) -->
+    <skip />
+    <!-- no translation found for battery_saver_charged_notification_title (5954873381559605660) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_notification_summary (1374222493681267143) -->
+    <skip />
+    <!-- no translation found for battery_saver_off_alternative_notification_summary (4340727818546508436) -->
+    <skip />
     <string name="mime_type_folder" msgid="7111951698626315204">"Ifolda"</string>
     <string name="mime_type_apk" msgid="5518003630972506900">"Uhlelo lokusebenza lwe-Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Ifayela"</string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index fe2c665..8f3f25a 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1673,9 +1673,31 @@
              This flag is turned on by default. <em>This attribute is usable only by system apps.
              </em> -->
         <attr name="allowClearUserDataOnFailedRestore"/>
-        <!-- If {@code true} the app's non sensitive audio can be capture by other apps.
-             The default value is true. -->
+        <!-- If {@code true} the app's non sensitive audio can be capture by other apps with
+             {@code AudioPlaybackCaptureConfiguration} and a {@code MediaProjection}.
+
+             <p>
+             Non sensitive audio is defined as audio whose {@code AttributeUsage} is
+             {@code USAGE_UNKNOWN}), {@code USAGE_MEDIA}) or {@code USAGE_GAME}).
+             All other usages (eg. {@code USAGE_VOICE_COMMUNICATION}) will not be captured.
+
+             <p>
+             The default value is:
+                 - {@code true} for apps with targetSdkVersion >= 29 (Q).
+                 - {@code false} for apps with targetSdkVersion < 29.
+             -->
         <attr name="allowAudioPlaybackCapture" format="boolean" />
+        <!-- If {@code true} this app allows shared/external storage media to be
+             a sandboxed view that only contains files owned by the app.
+             <p>
+             Sandboxed apps can continue to discover and read media belonging to other
+             apps via {@code MediaStore}.
+             <p>
+             The default value is:
+                 - {@code true} for apps with targetSdkVersion >= 29 (Q).
+                 - {@code false} for apps with targetSdkVersion < 29.
+             -->
+        <attr name="allowExternalStorageSandbox" format="boolean" />
     </declare-styleable>
     <!-- The <code>permission</code> tag declares a security permission that can be
          used to control access from other packages to specific components or
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index 7209103..5af3c2a 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -35,6 +35,7 @@
 
     <color name="accent_device_default_light">@color/accent_material_light</color>
     <color name="accent_device_default_dark">@color/accent_material_dark</color>
+    <color name="accent_device_default">@color/accent_device_default_light</color>
 
     <color name="background_device_default_dark">@color/background_material_dark</color>
     <color name="background_device_default_light">@color/background_material_light</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index dc0ec03..ec2a6ae 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2442,6 +2442,16 @@
     <!-- Maximum number of users we allow to be running at a time -->
     <integer name="config_multiuserMaxRunningUsers">3</integer>
 
+    <!-- Whether to delay user data locking for background user.
+         If false, user switched-out from user switching will still be in running state until
+         config_multiuserMaxRunningUsers is reached. Once config_multiuserMaxRunningUsers is
+         reached, user will be stopped and user data is locked.
+         If true, user switched out from user switching will always be stopped but its user data
+         is not locked. Total number of unlocked users will be limited by
+         config_multiuserMaxRunningUsers. Once that limit is reached, least recently stopped user
+         will be locked. -->
+    <bool name="config_multiuserDelayUserDataLocking">false</bool>
+
     <!-- Whether UI for multi user should be shown -->
     <bool name="config_enableMultiUserUI">false</bool>
 
@@ -3237,6 +3247,16 @@
          2: gestures only for back, home and overview -->
     <integer name="config_navBarInteractionMode">0</integer>
 
+    <!-- Controls whether the nav bar can move from the bottom to the side in landscape.
+         Only applies if the device display is not square. -->
+    <bool name="config_navBarCanMove">true</bool>
+
+    <!-- Controls whether the navigation bar lets through taps. -->
+    <bool name="config_navBarTapThrough">false</bool>
+
+    <!-- Controls the size of the back gesture inset. -->
+    <dimen name="config_backGestureInset">0dp</dimen>
+
     <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
          These values are in DPs and will be converted to pixel sizes internally. -->
     <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">16x16</string>
@@ -3961,7 +3981,7 @@
         M5,17.5 V12 H3 L7,4.5 V10 h2 L5,17.5 z
     </string>
     <string name="config_batterymeterPowersavePath" translatable="false">
-		M9.75,10l-2.5,0l0,-2.5l-2.5,0l0,2.5l-2.5,0l0,2.5l2.5,0l0,2.5l2.5,0l0,-2.5l2.5,0z
+        M9,10l-2,0l0,-2l-2,0l0,2l-2,0l0,2l2,0l0,2l2,0l0,-2l2,0z
     </string>
 
     <!-- A dual tone battery meter draws the perimeter path twice - once to define the shape
@@ -3975,4 +3995,33 @@
     <!-- The type of the light sensor to be used by the display framework for things like
          auto-brightness. If unset, then it just gets the default sensor of type TYPE_LIGHT. -->
     <string name="config_displayLightSensorType" translatable="false" />
+
+    <!-- Whether or not to enable automatic heap dumps for the system server on debuggable builds. -->
+    <bool name="config_debugEnableAutomaticSystemServerHeapDumps">false</bool>
+
+    <!-- Trigger a heap dump if the system server pss usage exceeds this threshold. 400 MB -->
+    <integer name="config_debugSystemServerPssThresholdBytes">419430400</integer>
+
+    <!-- See DropBoxManagerService.
+         The minimum period in milliseconds between broadcasts for entries with low priority
+         dropbox tags. -->
+    <integer name="config_dropboxLowPriorityBroadcastRateLimitPeriod">2000</integer>
+
+    <!-- See DropBoxManagerService.
+         An array of dropbox entry tags to marked as low priority. Low priority broadcasts will be
+         rated limited to a period defined by config_dropboxLowPriorityBroadcastRateLimitPeriod
+         (high frequency broadcasts for the tag will be dropped) -->
+    <string-array name="config_dropboxLowPriorityTags" translatable="false">
+        <item>data_app_strictmode</item>
+        <item>data_app_wtf</item>
+        <item>keymaster</item>
+        <item>netstats</item>
+        <item>system_app_strictmode</item>
+        <item>system_app_wtf</item>
+        <item>system_server_strictmode</item>
+        <item>system_server_wtf</item>
+    </string-array>
+
+    <!-- Which binder services to include in incident reports containing restricted images. -->
+    <string-array name="config_restrictedImagesServices" translatable="false"/>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 023fbad..c646fef 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -47,6 +47,9 @@
     <dimen name="navigation_bar_height_landscape">48dp</dimen>
     <!-- Width of the navigation bar when it is placed vertically on the screen -->
     <dimen name="navigation_bar_width">48dp</dimen>
+    <!-- How much we expand the touchable region of the status bar below the notch to catch touches
+         that just start below the notch. -->
+    <dimen name="display_cutout_touchable_region_size">12dp</dimen>
 
     <!-- EXPERIMENT BEGIN -->
     <!-- Height of the bottom navigation bar frame; this is different than navigation_bar_height
@@ -725,4 +728,5 @@
     <dimen name="resolver_icon_size">42dp</dimen>
     <dimen name="resolver_badge_size">18dp</dimen>
     <dimen name="chooser_target_width">76dp</dimen>
+    <dimen name="chooser_max_collapsed_height">288dp</dimen>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3505994..3bbc03f 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2942,6 +2942,7 @@
         <public name="allowClearUserDataOnFailedRestore"/>
         <public name="allowAudioPlaybackCapture"/>
         <public name="secureElementName" />
+        <public name="allowExternalStorageSandbox"/>
     </public-group>
 
     <public-group type="drawable" first-id="0x010800b4">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index bb47370..4b8a96c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -747,12 +747,12 @@
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to record audio?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]-->
-    <string name="permgrouplab_activityRecognition">Activity recognition</string>
+    <string name="permgrouplab_activityRecognition">Physical activity</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]-->
-    <string name="permgroupdesc_activityRecognition">recognize activity</string>
+    <string name="permgroupdesc_activityRecognition">access your physical activity</string>
     <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
     <string name="permgrouprequest_activityRecognition">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to recognize your physical activity?</string>
+        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your physical activity?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_camera">Camera</string>
@@ -786,24 +786,6 @@
     <string name="permgrouprequest_sensors">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access sensor data about your vital signs?</string>
 
-    <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permgrouplab_aural">Music</string>
-    <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permgroupdesc_aural">access your music</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_aural">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your music?</string>
-
-    <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permgrouplab_visual">Photos &amp; videos</string>
-    <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permgroupdesc_visual">access your photos &amp; videos</string>
-    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
-    <string name="permgrouprequest_visual">Allow
-        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your photos and videos?</string>
-    <!-- Subtitle of the message shown to the user when the apps requests permission to access photos and videos [CHAR LIMIT=150]-->
-    <string name="permgrouprequestdetail_visual">This includes any locations tagged in your photos and videos</string>
-
     <!-- Title for the capability of an accessibility service to retrieve window content. -->
     <string name="capability_title_canRetrieveWindowContent">Retrieve window content</string>
     <!-- Description for the capability of an accessibility service to retrieve window content. -->
@@ -1432,28 +1414,16 @@
     <string name="permdesc_useFingerprint">Allows the app to use fingerprint hardware for authentication</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permlab_audioRead">read your music collection</string>
-    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_audioRead">Allows the app to read your music collection.</string>
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_audioWrite">modify your music collection</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_audioWrite">Allows the app to modify your music collection.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permlab_videoRead">read your video collection</string>
-    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_videoRead">Allows the app to read your video collection.</string>
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_videoWrite">modify your video collection</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_videoWrite">Allows the app to modify your video collection.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permlab_imagesRead">read your photo collection</string>
-    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_imagesRead">Allows the app to read your photo collection.</string>
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_imagesWrite">modify your photo collection</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_imagesWrite">Allows the app to modify your photo collection.</string>
@@ -1582,25 +1552,25 @@
     </string-array>
 
     <!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=50] -->
-    <string name="face_error_hw_not_available">Face hardware not available.</string>
+    <string name="face_error_hw_not_available">Can\u2019t verify face. Hardware not available.</string>
     <!-- Error message shown when the face hardware timer has expired and the user needs to restart the operation. [CHAR LIMIT=50] -->
     <string name="face_error_timeout">Face timeout reached. Try again.</string>
-    <!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=50] -->
-    <string name="face_error_no_space">Face can\u2019t be stored.</string>
+    <!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=60] -->
+    <string name="face_error_no_space">Can\u2019t store new face data. Delete an old one first.</string>
     <!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] -->
-    <string name="face_error_canceled">Face operation canceled.</string>
+    <string name="face_error_canceled">Face operation canceled</string>
     <!-- Generic error message shown when the face authentication operation is canceled due to user input. Generally not shown to the user [CHAR LIMIT=50] -->
-    <string name="face_error_user_canceled">Face authentication canceled by user.</string>
+    <string name="face_error_user_canceled">Face authentication canceled by user</string>
     <!-- Generic error message shown when the face operation fails because too many attempts have been made. [CHAR LIMIT=50] -->
     <string name="face_error_lockout">Too many attempts. Try again later.</string>
-    <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=50] -->
-    <string name="face_error_lockout_permanent">Too many attempts. Facial authentication disabled.</string>
+    <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=60] -->
+    <string name="face_error_lockout_permanent">Too many attempts. Face authentication disabled.</string>
     <!-- Generic error message shown when the face hardware can't recognize the face. [CHAR LIMIT=50] -->
     <string name="face_error_unable_to_process">Can\u2019t verify face. Try again.</string>
-    <!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=50] -->
-    <string name="face_error_not_enrolled">You haven\u2019t set up face authentication.</string>
+    <!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=52] -->
+    <string name="face_error_not_enrolled">You haven\u2019t set up face authentication</string>
     <!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=60] -->
-    <string name="face_error_hw_not_present">Face authentication is not supported on this device.</string>
+    <string name="face_error_hw_not_present">Face authentication is not supported on this device</string>
 
     <!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] -->
     <string name="face_name_template">Face <xliff:g id="faceId" example="1">%d</xliff:g></string>
@@ -3305,13 +3275,13 @@
         <xliff:g id="proc" example="Android System">%1$s</xliff:g> process has exceeded
         its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available
         for you to share. Be careful: this heap dump can contain any sensitive personal information
-        that the process has access to.</string>
+        that the process has access to, which may include things you\u2019ve typed.</string>
 
     <!-- Text of dialog prompting the user to share a heap dump that they initiated [CHAR LIMIT=NONE] -->
     <string name="dump_heap_ready_text">A heap dump of
         <xliff:g id="proc" example="com.android.example">%1$s</xliff:g>\u2019s process is available
         for you to share. Be careful: this heap dump may contain any sensitive personal information
-        that the process has access to.</string>
+        that the process has access to, which may include things you\u2019ve typed.</string>
 
     <!-- Displayed in the title of the chooser for things to do with text that
          is to be sent to another application. For example, I can send
@@ -4325,10 +4295,10 @@
 
     <!-- Activity starter -->
     <!-- Toast message for blocking background activity starts feature running in permissive mode -->
-    <string name="activity_starter_block_bg_activity_starts_permissive">This background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> will be blocked in future Q builds. See go/q-bg-block.</string>
+    <string name="activity_starter_block_bg_activity_starts_permissive">This background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock.</string>
 
     <!-- Toast message for blocking background activity starts feature running in enforcing mode -->
-    <string name="activity_starter_block_bg_activity_starts_enforcing">Background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> blocked. See go/q-bg-block. </string>
+    <string name="activity_starter_block_bg_activity_starts_enforcing">Background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> blocked. See g.co/dev/bgblock. </string>
 
     <!-- Keyguard strings -->
     <!-- Message shown in pattern unlock after some number of unsuccessful attempts -->
@@ -4835,7 +4805,7 @@
     <string name="package_deleted_device_owner">Deleted by your admin</string>
 
     <!-- [CHAR LIMIT=25] String for confirmation button to enable a feature gated by the battery saver warning-->
-    <string name="confirm_battery_saver">Confirm</string>
+    <string name="confirm_battery_saver">OK</string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
     <string name="battery_saver_description_with_learn_more">Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life. <annotation id="url">Learn More</annotation></string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ae54a6a..3e23640 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -498,6 +498,7 @@
   <java-symbol type="integer" name="config_lockSoundVolumeDb" />
   <java-symbol type="integer" name="config_multiuserMaximumUsers" />
   <java-symbol type="integer" name="config_multiuserMaxRunningUsers" />
+  <java-symbol type="bool" name="config_multiuserDelayUserDataLocking" />
   <java-symbol type="integer" name="config_safe_media_volume_index" />
   <java-symbol type="integer" name="config_safe_media_volume_usb_mB" />
   <java-symbol type="integer" name="config_mobile_mtu" />
@@ -1443,6 +1444,11 @@
   <java-symbol type="drawable" name="ic_instant_icon_badge_bolt" />
   <java-symbol type="drawable" name="emulator_circular_window_overlay" />
   <java-symbol type="drawable" name="ic_qs_battery_saver" />
+  <java-symbol type="drawable" name="ic_qs_bluetooth" />
+  <java-symbol type="drawable" name="ic_qs_airplane" />
+  <java-symbol type="drawable" name="ic_qs_flashlight" />
+  <java-symbol type="drawable" name="ic_qs_auto_rotate" />
+  <java-symbol type="drawable" name="ic_qs_dnd" />
 
   <java-symbol type="drawable" name="sim_light_blue" />
   <java-symbol type="drawable" name="sim_light_green" />
@@ -1745,6 +1751,7 @@
   <java-symbol type="dimen" name="navigation_bar_height_landscape_car_mode" />
   <java-symbol type="dimen" name="navigation_bar_width_car_mode" />
   <java-symbol type="dimen" name="status_bar_height" />
+  <java-symbol type="dimen" name="display_cutout_touchable_region_size" />
   <java-symbol type="dimen" name="quick_qs_offset_height" />
   <java-symbol type="dimen" name="quick_qs_total_height" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_off" />
@@ -2771,6 +2778,7 @@
   <java-symbol type="dimen" name="chooser_edge_margin_normal" />
   <java-symbol type="dimen" name="chooser_preview_image_font_size"/>
   <java-symbol type="dimen" name="chooser_preview_width" />
+  <java-symbol type="dimen" name="chooser_max_collapsed_height" />
   <java-symbol type="layout" name="chooser_grid" />
   <java-symbol type="layout" name="chooser_grid_preview_text" />
   <java-symbol type="layout" name="chooser_grid_preview_image" />
@@ -2837,6 +2845,9 @@
   <java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" />
   <java-symbol type="integer" name="config_navBarOpacityMode" />
   <java-symbol type="integer" name="config_navBarInteractionMode" />
+  <java-symbol type="bool" name="config_navBarCanMove" />
+  <java-symbol type="bool" name="config_navBarTapThrough" />
+  <java-symbol type="dimen" name="config_backGestureInset" />
   <java-symbol type="color" name="system_bar_background_semi_transparent" />
 
   <!-- EditText suggestion popup. -->
@@ -3222,6 +3233,9 @@
   <java-symbol type="string" name="config_batterymeterPowersavePath" />
   <java-symbol type="bool" name="config_batterymeterDualTone" />
 
+  <java-symbol type="bool" name="config_debugEnableAutomaticSystemServerHeapDumps" />
+  <java-symbol type="integer" name="config_debugSystemServerPssThresholdBytes" />
+
   <!-- Accessibility Shortcut -->
   <java-symbol type="string" name="accessibility_shortcut_warning_dialog_title" />
   <java-symbol type="string" name="accessibility_shortcut_toogle_warning" />
@@ -3601,6 +3615,7 @@
   <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" />
 
   <java-symbol type="string" name="battery_saver_description_with_learn_more" />
+  <java-symbol type="string" name="confirm_battery_saver" />
 
   <java-symbol type="attr" name="opticalInsetLeft" />
   <java-symbol type="attr" name="opticalInsetTop" />
@@ -3676,6 +3691,7 @@
   <java-symbol type="integer" name="config_attentionApiTimeout" />
 
   <java-symbol type="string" name="config_incidentReportApproverPackage" />
+  <java-symbol type="array" name="config_restrictedImagesServices" />
 
   <!-- Display White-Balance -->
   <java-symbol type="integer" name="config_displayWhiteBalanceBrightnessSensorRate" />
@@ -3727,4 +3743,7 @@
   <java-symbol type="dimen" name="resolver_icon_size"/>
   <java-symbol type="dimen" name="resolver_badge_size"/>
 
+  <!-- For DropBox -->
+  <java-symbol type="integer" name="config_dropboxLowPriorityBroadcastRateLimitPeriod" />
+  <java-symbol type="array" name="config_dropboxLowPriorityTags" />
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 9a95ecc..9f20ee6 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1390,6 +1390,8 @@
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
+    <style name="Theme.DeviceDefault.Dialog.Alert.DayNight" parent="Theme.DeviceDefault.Light.Dialog.Alert" />
+
     <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar">
         <!-- Color palette -->
         <item name="colorPrimary">@color/primary_device_default_light</item>
diff --git a/core/tests/coretests/res/raw/com_android_tzdata.apex b/core/tests/coretests/res/raw/com_android_tzdata.apex
index 72294de..ca89bf6 100644
--- a/core/tests/coretests/res/raw/com_android_tzdata.apex
+++ b/core/tests/coretests/res/raw/com_android_tzdata.apex
Binary files differ
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
index 52b2658..3d252fb 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
@@ -30,6 +30,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link ClientTransaction}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:ClientTransactionTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index ad28d13..447f28e 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -42,6 +42,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link ObjectPool}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:ObjectPoolTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index f730a24..1cca799 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -26,9 +26,8 @@
 import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
 import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
 
-import static junit.framework.Assert.assertEquals;
-
 import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.inOrder;
@@ -61,7 +60,15 @@
 import java.util.Map;
 import java.util.stream.Collectors;
 
-/** Test {@link TransactionExecutor} logic. */
+/**
+ * Test {@link TransactionExecutor} logic.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:TransactionExecutorTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index d73c174..d117b40 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -21,8 +21,8 @@
 import static android.app.servertransaction.TestUtils.referrerIntentList;
 import static android.app.servertransaction.TestUtils.resultInfoList;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.app.IApplicationThread;
 import android.app.IInstrumentationWatcher;
@@ -64,7 +64,15 @@
 import java.util.List;
 import java.util.Map;
 
-/** Test parcelling and unparcelling of transactions and transaction items. */
+/**
+ * Test parcelling and unparcelling of transactions and transaction items.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:TransactionParcelTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
index aa0e0cd..50e915d 100644
--- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java
+++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
@@ -499,19 +499,21 @@
     public void testApexPackageInfoGeneration() throws Exception {
         File apexFile = copyRawResourceToFile("com.android.tzdata.apex",
                 R.raw.com_android_tzdata);
-        PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexFile, false);
-        assertEquals("com.google.android.tzdata", pi.packageName);
+        int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES;
+        PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexFile, flags);
         assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
-        assertEquals(1, pi.getLongVersionCode());
-        assertEquals(1, pi.applicationInfo.longVersionCode);
-        assertNull(pi.signingInfo);
+        assertTrue(pi.applicationInfo.enabled);
+        assertEquals(28, pi.applicationInfo.targetSdkVersion);
+        assertEquals(191000070, pi.applicationInfo.longVersionCode);
+        assertNotNull(pi.applicationInfo.metaData);
+        assertEquals(apexFile.getPath(), pi.applicationInfo.sourceDir);
+        assertEquals("Bundle[{com.android.vending.derived.apk.id=1}]",
+                pi.applicationInfo.metaData.toString());
 
-        pi = PackageParser.generatePackageInfoFromApex(apexFile, true);
         assertEquals("com.google.android.tzdata", pi.packageName);
-        assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
-        assertEquals(1, pi.getLongVersionCode());
-        assertEquals(1, pi.applicationInfo.longVersionCode);
+        assertEquals(191000070, pi.getLongVersionCode());
         assertNotNull(pi.signingInfo);
         assertTrue(pi.signingInfo.getApkContentsSigners().length > 0);
+        assertTrue(pi.isApex);
     }
 }
diff --git a/core/tests/coretests/src/android/database/TranslatingCursorTest.java b/core/tests/coretests/src/android/database/TranslatingCursorTest.java
new file mode 100644
index 0000000..baca7ef
--- /dev/null
+++ b/core/tests/coretests/src/android/database/TranslatingCursorTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.database;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.database.TranslatingCursor.Translator;
+import android.net.Uri;
+
+import junit.framework.TestCase;
+
+public class TranslatingCursorTest extends TestCase {
+
+    public void testDuplicateColumnName() {
+        MatrixCursor base = new MatrixCursor(new String[] {"_id", "colA", "colB", "colA"});
+        base.addRow(new Object[] { 0, "r1_a", "r1_b", "r1_a"});
+        base.addRow(new Object[] { 1, "r2_a", "r2_b", "r2_a"});
+        Translator translator = (data, idIndex, matchingColumn, cursor) -> data.toUpperCase();
+        TranslatingCursor.Config config = new TranslatingCursor.Config(Uri.EMPTY, "_id", "colA");
+        TranslatingCursor translating = new TranslatingCursor(base, config, translator, false);
+
+        translating.moveToNext();
+        String[] expected = new String[] { "ignored", "R1_A", "r1_b", "R1_A" };
+        for (int i = 1; i < translating.getColumnCount(); i++) {
+            assertThat(translating.getString(i)).isEqualTo(expected[i]);
+        }
+        translating.moveToNext();
+        expected = new String[] { "ignored", "R2_A", "r2_b", "R2_A" };
+        for (int i = 1; i < translating.getColumnCount(); i++) {
+            assertThat(translating.getString(i)).isEqualTo(expected[i]);
+        }
+    }
+
+}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 8fc6a96..c36ca82 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -131,7 +131,6 @@
                     Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
                     Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
                     Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
-                    Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST,
                     Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
                     Settings.Global.BROADCAST_BG_CONSTANTS,
                     Settings.Global.BROADCAST_FG_CONSTANTS,
@@ -287,8 +286,6 @@
                     Settings.Global.HDMI_CONTROL_ENABLED,
                     Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
                     Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
-                    Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE,
-                    Settings.Global.HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE,
                     Settings.Global.HIDDEN_API_POLICY,
                     Settings.Global.HIDE_ERROR_DIALOGS,
                     Settings.Global.HTTP_PROXY,
@@ -490,6 +487,7 @@
                     Settings.Global.GPU_DEBUG_APP,
                     Settings.Global.GPU_DEBUG_LAYERS,
                     Settings.Global.GPU_DEBUG_LAYERS_GLES,
+                    Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE,
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE,
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS,
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES,
@@ -612,7 +610,6 @@
                  Settings.Secure.BACKUP_ENABLED,
                  Settings.Secure.BACKUP_PROVISIONED,
                  Settings.Secure.BACKUP_TRANSPORT,
-                 Settings.Secure.CALL_REDIRECTION_DEFAULT_APPLICATION,
                  Settings.Secure.CALL_SCREENING_DEFAULT_COMPONENT,
                  Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED, // Candidate for backup?
                  Settings.Secure.CARRIER_APPS_HANDLED,
diff --git a/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java
index 08f9de6..8081e9e 100644
--- a/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsValidatorsTest.java
@@ -16,6 +16,8 @@
 
 package android.provider;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -26,6 +28,8 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import org.json.JSONException;
+import org.json.JSONObject;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -218,6 +222,31 @@
     }
 
     @Test
+    public void testJSONObjectValidator() throws JSONException {
+        Validator v = SettingsValidators.JSON_OBJECT_VALIDATOR;
+
+        assertThat(v.validate(new JSONObject().toString())).isTrue();
+        assertThat(v.validate("{}")).isTrue();
+        assertThat(v.validate(new JSONObject().put("foo", "bar").toString()))
+                .isTrue();
+        assertThat(v.validate("{\"foo\": \"bar\"}")).isTrue();
+
+        assertThat(v.validate("random string")).isFalse();
+        assertThat(v.validate("random: string")).isFalse();
+        assertThat(v.validate("{random: }")).isFalse();
+    }
+
+    @Test
+    public void testJSONObjectValidator_onNullValue_returnsFalse() {
+        assertThat(SettingsValidators.JSON_OBJECT_VALIDATOR.validate(null)).isFalse();
+    }
+
+    @Test
+    public void testJSONObjectValidator_onEmptyString_returnsFalse() {
+        assertThat(SettingsValidators.JSON_OBJECT_VALIDATOR.validate("")).isFalse();
+    }
+
+    @Test
     public void ensureAllBackedUpSystemSettingsHaveValidators() {
         String offenders = getOffenders(concat(Settings.System.SETTINGS_TO_BACKUP,
                 Settings.System.LEGACY_RESTORE_SETTINGS), Settings.System.VALIDATORS);
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index dd50af877..182fe78 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -44,6 +44,15 @@
 import java.util.Arrays;
 import java.util.Collections;
 
+/**
+ * Tests for {@link DisplayCutout}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:DisplayCutoutTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 23ab05e..ebbbdec 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -18,18 +18,15 @@
 
 import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.TYPE_TOP_BAR;
-
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.WindowInsets.Type.sideBars;
 import static android.view.WindowInsets.Type.systemBars;
-import static android.view.WindowInsets.Type.topBar;
-import static junit.framework.Assert.assertEquals;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -55,6 +52,15 @@
 
 import java.util.List;
 
+/**
+ * Tests for {@link InsetsAnimationControlImpl}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsAnimationControlImplTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index d71bde83..4d8d3f6 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -19,13 +19,13 @@
 import static android.view.InsetsState.TYPE_IME;
 import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.TYPE_TOP_BAR;
-
 import static android.view.WindowInsets.Type.topBar;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
@@ -53,6 +53,15 @@
 
 import java.util.concurrent.CountDownLatch;
 
+/**
+ * Tests for {@link InsetsController}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsControllerTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 4266ba9f..a32fa77 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -43,6 +43,15 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+/**
+ * Tests for {@link InsetsSourceConsumer}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsSourceConsumerTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java
index 98ab3e7..b55a9c6 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java
@@ -18,7 +18,7 @@
 
 import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
 
-import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertEquals;
 
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -31,6 +31,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link InsetsSource}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsSourceTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java
index bd036b0..8e167da 100644
--- a/core/tests/coretests/src/android/view/InsetsStateTest.java
+++ b/core/tests/coretests/src/android/view/InsetsStateTest.java
@@ -24,14 +24,13 @@
 import static android.view.InsetsState.TYPE_SIDE_BAR_2;
 import static android.view.InsetsState.TYPE_SIDE_BAR_3;
 import static android.view.InsetsState.TYPE_TOP_BAR;
-
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -47,6 +46,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link InsetsState}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsStateTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/ViewGroupTest.java b/core/tests/coretests/src/android/view/ViewGroupTest.java
new file mode 100644
index 0000000..979a839
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ViewGroupTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static androidx.test.InstrumentationRegistry.getContext;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.graphics.Region;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+
+/**
+ * Test basic functions of ViewGroup.
+ *
+ * Build/Install/Run:
+ *     atest FrameworksCoreTests:ViewGroupTest
+ */
+@Presubmit
+@SmallTest
+public class ViewGroupTest {
+
+    /**
+     * Test if {@link ViewGroup#subtractObscuredTouchableRegion} works as expected.
+     *
+     * The view hierarchy:
+     *   A---B---C
+     *    \   \
+     *     \   --D
+     *      \
+     *       E---F
+     *
+     * The layer and bounds of each view:
+     *   F -- (invisible)
+     *   E --
+     *   D ----
+     *   C ----------
+     *   B ------
+     *   A --------
+     */
+    @Test
+    public void testSubtractObscuredTouchableRegion() {
+        final Context context = getContext();
+        final TestView viewA = new TestView(context, 8 /* right */);
+        final TestView viewB = new TestView(context, 6 /* right */);
+        final TestView viewC = new TestView(context, 10 /* right */);
+        final TestView viewD = new TestView(context, 4 /* right */);
+        final TestView viewE = new TestView(context, 2 /* right */);
+        final TestView viewF = new TestView(context, 2 /* right */);
+
+        viewA.addView(viewB);
+        viewA.addView(viewE);
+        viewB.addView(viewC);
+        viewB.addView(viewD);
+        viewE.addView(viewF);
+
+        viewF.setVisibility(View.INVISIBLE);
+
+        final Region r = new Region();
+
+        getUnobscuredTouchableRegion(r, viewA);
+        assertRegionContainPoint(1 /* x */, r, true /* contain */);
+        assertRegionContainPoint(3 /* x */, r, true /* contain */);
+        assertRegionContainPoint(5 /* x */, r, true /* contain */);
+        assertRegionContainPoint(7 /* x */, r, true /* contain */);
+        assertRegionContainPoint(9 /* x */, r, false /* contain */); // Outside of bounds
+
+        getUnobscuredTouchableRegion(r, viewB);
+        assertRegionContainPoint(1 /* x */, r, false /* contain */); // Obscured by E
+        assertRegionContainPoint(3 /* x */, r, true /* contain */);
+        assertRegionContainPoint(5 /* x */, r, true /* contain */);
+        assertRegionContainPoint(7 /* x */, r, false /* contain */); // Outside of bounds
+
+        getUnobscuredTouchableRegion(r, viewC);
+        assertRegionContainPoint(1 /* x */, r, false /* contain */); // Obscured by D and E
+        assertRegionContainPoint(3 /* x */, r, false /* contain */); // Obscured by D
+        assertRegionContainPoint(5 /* x */, r, true /* contain */);
+        assertRegionContainPoint(7 /* x */, r, false /* contain */); // Outside of parent bounds
+
+        getUnobscuredTouchableRegion(r, viewD);
+        assertRegionContainPoint(1 /* x */, r, false /* contain */); // Obscured by E
+        assertRegionContainPoint(3 /* x */, r, true /* contain */);
+        assertRegionContainPoint(5 /* x */, r, false /* contain */); // Outside of bounds
+
+        getUnobscuredTouchableRegion(r, viewE);
+        assertRegionContainPoint(1 /* x */, r, true /* contain */);
+        assertRegionContainPoint(3 /* x */, r, false /* contain */); // Outside of bounds
+    }
+
+    private static void getUnobscuredTouchableRegion(Region outRegion, View view) {
+        outRegion.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
+        final ViewParent parent = view.getParent();
+        if (parent != null) {
+            parent.subtractObscuredTouchableRegion(outRegion, view);
+        }
+    }
+
+    private static void assertRegionContainPoint(int x, Region region, boolean contain) {
+        assertEquals(String.format("Touchable region must%s contain (%s, 0).",
+                (contain ? "" : " not"), x), contain, region.contains(x, 0 /* y */));
+    }
+
+    private static class TestView extends ViewGroup {
+        TestView(Context context, int right) {
+            super(context);
+            setFrame(0 /* left */, 0 /* top */, right, 1 /* bottom */);
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int l, int t, int r, int b) {
+            // We don't layout this view.
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
index 1cb71f9..1a22a70 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
@@ -45,7 +45,6 @@
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
@@ -61,16 +60,12 @@
 
     AccessibilityCache mAccessibilityCache;
     AccessibilityCache.AccessibilityNodeRefresher mAccessibilityNodeRefresher;
-    AtomicInteger mNumA11yNodeInfosInUse = new AtomicInteger(0);
-    AtomicInteger mNumA11yWinInfosInUse = new AtomicInteger(0);
 
     @Before
     public void setUp() {
         mAccessibilityNodeRefresher = mock(AccessibilityCache.AccessibilityNodeRefresher.class);
         when(mAccessibilityNodeRefresher.refreshNode(anyObject(), anyBoolean())).thenReturn(true);
         mAccessibilityCache = new AccessibilityCache(mAccessibilityNodeRefresher);
-        AccessibilityNodeInfo.setNumInstancesInUseCounter(mNumA11yNodeInfosInUse);
-        AccessibilityWindowInfo.setNumInstancesInUseCounter(mNumA11yWinInfosInUse);
     }
 
     @After
@@ -78,8 +73,6 @@
         // Make sure we're recycling all of our window and node infos
         mAccessibilityCache.clear();
         AccessibilityInteractionClient.getInstance().clearCache();
-        assertEquals(0, mNumA11yWinInfosInUse.get());
-        assertEquals(0, mNumA11yNodeInfosInUse.get());
     }
 
     @Test
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
index 2416de1..2008537 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
@@ -49,13 +49,15 @@
 
     private static final LocusId ID = new LocusId("WHATEVER");
 
+    private static final int NO_SESSION_ID = 0;
+
     // Not using @Mock because it's final - no need to be fancy here....
     private final ContentCaptureContext mClientContext =
             new ContentCaptureContext.Builder(ID).build();
 
     @Test
     public void testSetAutofillId_null() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED);
 
         assertThrows(NullPointerException.class, () -> event.setAutofillId(null));
         assertThat(event.getId()).isNull();
@@ -64,7 +66,7 @@
 
     @Test
     public void testSetAutofillIds_null() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED);
 
         assertThrows(NullPointerException.class, () -> event.setAutofillIds(null));
         assertThat(event.getId()).isNull();
@@ -73,7 +75,7 @@
 
     @Test
     public void testAddAutofillId_null() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED);
 
         assertThrows(NullPointerException.class, () -> event.addAutofillId(null));
         assertThat(event.getId()).isNull();
@@ -82,7 +84,7 @@
 
     @Test
     public void testSetAutofillId() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED);
 
         final AutofillId id = new AutofillId(108);
         event.setAutofillId(id);
@@ -92,7 +94,7 @@
 
     @Test
     public void testSetAutofillIds() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED);
 
         final AutofillId id = new AutofillId(108);
         final ArrayList<AutofillId> ids = new ArrayList<>(1);
@@ -104,7 +106,7 @@
 
     @Test
     public void testAddAutofillId() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED);
 
         final AutofillId id1 = new AutofillId(108);
         event.addAutofillId(id1);
@@ -119,7 +121,7 @@
 
     @Test
     public void testAddAutofillId_afterSetId() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED);
 
         final AutofillId id1 = new AutofillId(108);
         event.setAutofillId(id1);
@@ -134,7 +136,7 @@
 
     @Test
     public void testAddAutofillId_afterSetIds() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED);
 
         final AutofillId id1 = new AutofillId(108);
         final ArrayList<AutofillId> ids = new ArrayList<>(1);
@@ -163,9 +165,9 @@
     }
 
     private ContentCaptureEvent newEventForSessionStarted() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_STARTED)
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_SESSION_STARTED)
                 .setClientContext(mClientContext)
-                .setParentSessionId("108");
+                .setParentSessionId(108);
         assertThat(event).isNotNull();
         return event;
     }
@@ -173,8 +175,8 @@
     private void assertSessionStartedEvent(ContentCaptureEvent event) {
         assertThat(event.getType()).isEqualTo(TYPE_SESSION_STARTED);
         assertThat(event.getEventTime()).isAtLeast(MY_EPOCH);
-        assertThat(event.getSessionId()).isEqualTo("42");
-        assertThat(event.getParentSessionId()).isEqualTo("108");
+        assertThat(event.getSessionId()).isEqualTo(42);
+        assertThat(event.getParentSessionId()).isEqualTo(108);
         assertThat(event.getId()).isNull();
         assertThat(event.getIds()).isNull();
         assertThat(event.getText()).isNull();
@@ -186,17 +188,17 @@
 
     @Test
     public void testSessionFinished_directly() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_FINISHED)
-                .setParentSessionId("108");
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_SESSION_FINISHED)
+                .setParentSessionId(108);
         assertThat(event).isNotNull();
         assertSessionFinishedEvent(event);
     }
 
     @Test
     public void testSessionFinished_throughParcel() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_FINISHED)
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_SESSION_FINISHED)
                 .setClientContext(mClientContext) // should not be writting to parcel
-                .setParentSessionId("108");
+                .setParentSessionId(108);
         assertThat(event).isNotNull();
         final ContentCaptureEvent clone = cloneThroughParcel(event);
         assertSessionFinishedEvent(clone);
@@ -205,8 +207,8 @@
     private void assertSessionFinishedEvent(ContentCaptureEvent event) {
         assertThat(event.getType()).isEqualTo(TYPE_SESSION_FINISHED);
         assertThat(event.getEventTime()).isAtLeast(MY_EPOCH);
-        assertThat(event.getSessionId()).isEqualTo("42");
-        assertThat(event.getParentSessionId()).isEqualTo("108");
+        assertThat(event.getSessionId()).isEqualTo(42);
+        assertThat(event.getParentSessionId()).isEqualTo(108);
         assertThat(event.getId()).isNull();
         assertThat(event.getIds()).isNull();
         assertThat(event.getText()).isNull();
@@ -216,7 +218,7 @@
 
     @Test
     public void testContextUpdated_directly() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_CONTEXT_UPDATED)
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_CONTEXT_UPDATED)
                 .setClientContext(mClientContext);
         assertThat(event).isNotNull();
         assertContextUpdatedEvent(event);
@@ -224,7 +226,7 @@
 
     @Test
     public void testContextUpdated_throughParcel() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_CONTEXT_UPDATED)
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_CONTEXT_UPDATED)
                 .setClientContext(mClientContext);
         assertThat(event).isNotNull();
         final ContentCaptureEvent clone = cloneThroughParcel(event);
@@ -233,9 +235,9 @@
 
     @Test
     public void testMergeEvent_typeViewTextChanged() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_TEXT_CHANGED)
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_TEXT_CHANGED)
                 .setText("test");
-        final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_TEXT_CHANGED)
+        final ContentCaptureEvent event2 = new ContentCaptureEvent(43, TYPE_VIEW_TEXT_CHANGED)
                 .setText("empty");
 
         event.mergeEvent(event2);
@@ -244,14 +246,14 @@
 
     @Test
     public void testMergeEvent_typeViewDisappeared() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED)
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED)
                 .setAutofillId(new AutofillId(1));
-        final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_DISAPPEARED)
+        final ContentCaptureEvent event2 = new ContentCaptureEvent(43, TYPE_VIEW_DISAPPEARED)
                 .setAutofillId(new AutofillId(2));
         final ArrayList<AutofillId> autofillIds = new ArrayList<>();
         autofillIds.add(new AutofillId(3));
         autofillIds.add(new AutofillId(4));
-        final ContentCaptureEvent event3 = new ContentCaptureEvent("17", TYPE_VIEW_DISAPPEARED)
+        final ContentCaptureEvent event3 = new ContentCaptureEvent(17, TYPE_VIEW_DISAPPEARED)
                 .setAutofillIds(autofillIds);
 
         event.mergeEvent(event2);
@@ -264,24 +266,24 @@
 
     @Test
     public void testMergeEvent_typeViewDisappeared_noIds() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED)
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED)
                 .setAutofillId(new AutofillId(1));
-        final ContentCaptureEvent event2 = new ContentCaptureEvent("43", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event2 = new ContentCaptureEvent(43, TYPE_VIEW_DISAPPEARED);
 
         assertThrows(IllegalArgumentException.class, () -> event.mergeEvent(event2));
     }
 
     @Test
     public void testMergeEvent_nullArgument() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED);
         assertThrows(NullPointerException.class, () -> event.mergeEvent(null));
     }
 
     @Test
     public void testMergeEvent_differentEventTypes() {
-        final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED)
+        final ContentCaptureEvent event = new ContentCaptureEvent(42, TYPE_VIEW_DISAPPEARED)
                 .setText("test").setAutofillId(new AutofillId(1));
-        final ContentCaptureEvent event2 = new ContentCaptureEvent("17", TYPE_VIEW_TEXT_CHANGED)
+        final ContentCaptureEvent event2 = new ContentCaptureEvent(17, TYPE_VIEW_TEXT_CHANGED)
                 .setText("empty").setAutofillId(new AutofillId(2));
 
         event.mergeEvent(event2);
@@ -296,8 +298,8 @@
     private void assertContextUpdatedEvent(ContentCaptureEvent event) {
         assertThat(event.getType()).isEqualTo(TYPE_CONTEXT_UPDATED);
         assertThat(event.getEventTime()).isAtLeast(MY_EPOCH);
-        assertThat(event.getSessionId()).isEqualTo("42");
-        assertThat(event.getParentSessionId()).isNull();
+        assertThat(event.getSessionId()).isEqualTo(42);
+        assertThat(event.getParentSessionId()).isEqualTo(NO_SESSION_ID);
         assertThat(event.getId()).isNull();
         assertThat(event.getIds()).isNull();
         assertThat(event.getText()).isNull();
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
index 013408e..81ce15a 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
@@ -39,9 +39,9 @@
 @RunWith(MockitoJUnitRunner.class)
 public class ContentCaptureSessionTest {
 
-    private ContentCaptureSession mSession1 = new MyContentCaptureSession("111");
+    private ContentCaptureSession mSession1 = new MyContentCaptureSession(111);
 
-    private ContentCaptureSession mSession2 = new MyContentCaptureSession("2222");
+    private ContentCaptureSession mSession2 = new MyContentCaptureSession(2222);
 
     @Mock
     private View mMockView;
@@ -60,12 +60,12 @@
         assertThat(childId.getViewId()).isEqualTo(42);
         assertThat(childId.getVirtualChildLongId()).isEqualTo(108L);
         assertThat(childId.getVirtualChildIntId()).isEqualTo(View.NO_ID);
-        assertThat(childId.getSessionId()).isEqualTo(mSession1.getIdAsInt());
+        assertThat(childId.getSessionId()).isEqualTo(mSession1.getId());
     }
 
     @Test
     public void testNewAutofillId_differentSessions() {
-        assertThat(mSession1.getIdAsInt()).isNotSameAs(mSession2.getIdAsInt()); //sanity check
+        assertThat(mSession1.getId()).isNotEqualTo(mSession2.getId()); //sanity check
         final AutofillId parentId = new AutofillId(42);
         final AutofillId childId1 = mSession1.newAutofillId(parentId, 108L);
         final AutofillId childId2 = mSession2.newAutofillId(parentId, 108L);
@@ -117,7 +117,7 @@
     // Cannot use @Spy because we need to pass the session id on constructor
     private class MyContentCaptureSession extends ContentCaptureSession {
 
-        private MyContentCaptureSession(String id) {
+        private MyContentCaptureSession(int id) {
             super(id);
         }
 
diff --git a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
index 67423c8..db5f82a 100644
--- a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
@@ -263,6 +263,7 @@
                                         "title",
                                         null,
                                         "description",
+                                        null,
                                         Intent.ACTION_VIEW,
                                         Uri.parse("http://www.android.com").toString(),
                                         null,
diff --git a/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
index 1b3c724..f1cfe24 100644
--- a/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
@@ -26,6 +26,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -58,6 +59,7 @@
     }
 
     @Test
+    @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized
     public void getBoolean_deviceConfig() {
         DeviceConfig.setProperty(
                 DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
@@ -77,6 +79,7 @@
     }
 
     @Test
+    @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized
     public void getInt_deviceConfig() {
         DeviceConfig.setProperty(
                 DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
@@ -94,6 +97,7 @@
     }
 
     @Test
+    @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized
     public void getFloat_deviceConfig() {
         DeviceConfig.setProperty(
                 DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
@@ -111,6 +115,7 @@
     }
 
     @Test
+    @Ignore // TODO: Re-enable once ConfigParser#ENABLE_DEVICE_CONFIG is finalized
     public void getString_deviceConfig() {
         DeviceConfig.setProperty(
                 DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
diff --git a/core/tests/coretests/src/android/view/textclassifier/FakeContextBuilder.java b/core/tests/coretests/src/android/view/textclassifier/FakeContextBuilder.java
index 2674e37..11bea0c 100644
--- a/core/tests/coretests/src/android/view/textclassifier/FakeContextBuilder.java
+++ b/core/tests/coretests/src/android/view/textclassifier/FakeContextBuilder.java
@@ -54,6 +54,7 @@
     private final PackageManager mPackageManager;
     private final ContextWrapper mContext;
     private final Map<String, ComponentName> mComponents = new HashMap<>();
+    private final Map<String, CharSequence> mAppLabels = new HashMap<>();
     private @Nullable ComponentName mAllIntentComponent;
 
     public FakeContextBuilder() {
@@ -79,6 +80,14 @@
         return this;
     }
 
+    /**
+     * Sets the app label res for a specified package.
+     */
+    public FakeContextBuilder setAppLabel(String packageName, @Nullable CharSequence appLabel) {
+        Preconditions.checkNotNull(packageName);
+        mAppLabels.put(packageName, appLabel);
+        return this;
+    }
 
     /**
      * Sets the component name of an activity to handle all intents.
@@ -102,6 +111,11 @@
                             : mAllIntentComponent;
                     return getResolveInfo(component);
                 });
+        when(mPackageManager.getApplicationLabel(any(ApplicationInfo.class))).thenAnswer(
+                (Answer<CharSequence>) invocation -> {
+                    ApplicationInfo applicationInfo = invocation.getArgument(0);
+                    return mAppLabels.get(applicationInfo.packageName);
+                });
         return mContext;
     }
 
@@ -125,6 +139,7 @@
             info.activityInfo.name = component.getClassName();
             info.activityInfo.exported = true;
             info.activityInfo.applicationInfo = new ApplicationInfo();
+            info.activityInfo.applicationInfo.packageName = component.getPackageName();
             info.activityInfo.applicationInfo.icon = 0;
         }
         return info;
diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/LabeledIntentTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/LabeledIntentTest.java
index 857408f..3ad26f5 100644
--- a/core/tests/coretests/src/android/view/textclassifier/intent/LabeledIntentTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/intent/LabeledIntentTest.java
@@ -20,6 +20,7 @@
 
 import static org.testng.Assert.assertThrows;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
@@ -40,17 +41,21 @@
     private static final String TITLE_WITHOUT_ENTITY = "Map";
     private static final String TITLE_WITH_ENTITY = "Map NW14D1";
     private static final String DESCRIPTION = "Check the map";
+    private static final String DESCRIPTION_WITH_APP_NAME = "Use %1$s to open map";
     private static final Intent INTENT =
             new Intent(Intent.ACTION_VIEW).setDataAndNormalize(Uri.parse("http://www.android.com"));
     private static final int REQUEST_CODE = 42;
     private static final Bundle TEXT_LANGUAGES_BUNDLE = Bundle.EMPTY;
+    private static final String APP_LABEL = "fake";
 
     private Context mContext;
 
     @Before
     public void setup() {
+        final ComponentName component = FakeContextBuilder.DEFAULT_COMPONENT;
         mContext = new FakeContextBuilder()
-                .setIntentComponent(Intent.ACTION_VIEW, FakeContextBuilder.DEFAULT_COMPONENT)
+                .setIntentComponent(Intent.ACTION_VIEW, component)
+                .setAppLabel(component.getPackageName(), APP_LABEL)
                 .build();
     }
 
@@ -60,6 +65,7 @@
                 TITLE_WITHOUT_ENTITY,
                 TITLE_WITH_ENTITY,
                 DESCRIPTION,
+                null,
                 INTENT,
                 REQUEST_CODE
         );
@@ -82,6 +88,7 @@
                 TITLE_WITHOUT_ENTITY,
                 null,
                 DESCRIPTION,
+                null,
                 INTENT,
                 REQUEST_CODE
         );
@@ -103,6 +110,7 @@
                 TITLE_WITHOUT_ENTITY,
                 null,
                 DESCRIPTION,
+                null,
                 INTENT,
                 REQUEST_CODE
         );
@@ -124,6 +132,7 @@
                 TITLE_WITHOUT_ENTITY,
                 null,
                 DESCRIPTION,
+                null,
                 INTENT,
                 REQUEST_CODE
         );
@@ -148,6 +157,7 @@
                                 null,
                                 null,
                                 DESCRIPTION,
+                                null,
                                 INTENT,
                                 REQUEST_CODE
                         ));
@@ -161,6 +171,7 @@
                 TITLE_WITHOUT_ENTITY,
                 null,
                 DESCRIPTION,
+                null,
                 unresolvableIntent,
                 REQUEST_CODE);
 
@@ -168,4 +179,22 @@
 
         assertThat(result).isNull();
     }
+
+    @Test
+    public void resolve_descriptionWithAppName() {
+        LabeledIntent labeledIntent = new LabeledIntent(
+                TITLE_WITHOUT_ENTITY,
+                TITLE_WITH_ENTITY,
+                DESCRIPTION,
+                DESCRIPTION_WITH_APP_NAME,
+                INTENT,
+                REQUEST_CODE
+        );
+
+        LabeledIntent.Result result = labeledIntent.resolve(
+                mContext, /*titleChooser*/ null, TEXT_LANGUAGES_BUNDLE);
+
+        assertThat(result).isNotNull();
+        assertThat(result.remoteAction.getContentDescription()).isEqualTo("Use fake to open map");
+    }
 }
diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
index 2e97e63..b9a1a8c 100644
--- a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
@@ -50,6 +50,7 @@
     private static final String TEXT = "text";
     private static final String TITLE_WITHOUT_ENTITY = "Map";
     private static final String DESCRIPTION = "Opens in Maps";
+    private static final String DESCRIPTION_WITH_APP_NAME = "Use %1$s to open Map";
     private static final String ACTION = Intent.ACTION_VIEW;
 
     @Mock
@@ -219,6 +220,7 @@
                         TITLE_WITHOUT_ENTITY,
                         null,
                         DESCRIPTION,
+                        DESCRIPTION_WITH_APP_NAME,
                         ACTION,
                         null,
                         null,
diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateIntentFactoryTest.java
index 6e3de2d..a33c358 100644
--- a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateIntentFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateIntentFactoryTest.java
@@ -41,6 +41,7 @@
     private static final String TITLE_WITHOUT_ENTITY = "Map";
     private static final String TITLE_WITH_ENTITY = "Map NW14D1";
     private static final String DESCRIPTION = "Check the map";
+    private static final String DESCRIPTION_WITH_APP_NAME = "Use %1$s to open map";
     private static final String ACTION = Intent.ACTION_VIEW;
     private static final String DATA = Uri.parse("http://www.android.com").toString();
     private static final String TYPE = "text/html";
@@ -73,6 +74,7 @@
                 TITLE_WITHOUT_ENTITY,
                 TITLE_WITH_ENTITY,
                 DESCRIPTION,
+                DESCRIPTION_WITH_APP_NAME,
                 ACTION,
                 DATA,
                 TYPE,
@@ -91,6 +93,7 @@
         assertThat(labeledIntent.titleWithoutEntity).isEqualTo(TITLE_WITHOUT_ENTITY);
         assertThat(labeledIntent.titleWithEntity).isEqualTo(TITLE_WITH_ENTITY);
         assertThat(labeledIntent.description).isEqualTo(DESCRIPTION);
+        assertThat(labeledIntent.descriptionWithAppName).isEqualTo(DESCRIPTION_WITH_APP_NAME);
         assertThat(labeledIntent.requestCode).isEqualTo(REQUEST_CODE);
         Intent intent = labeledIntent.intent;
         assertThat(intent.getAction()).isEqualTo(ACTION);
@@ -109,6 +112,7 @@
                 TITLE_WITHOUT_ENTITY,
                 TITLE_WITH_ENTITY,
                 DESCRIPTION,
+                DESCRIPTION_WITH_APP_NAME,
                 ACTION,
                 "HTTp://www.android.com",
                 TYPE,
@@ -132,6 +136,7 @@
                 TITLE_WITHOUT_ENTITY,
                 null,
                 DESCRIPTION,
+                null,
                 ACTION,
                 null,
                 null,
@@ -177,6 +182,7 @@
                 TITLE_WITHOUT_ENTITY,
                 TITLE_WITH_ENTITY,
                 DESCRIPTION,
+                DESCRIPTION_WITH_APP_NAME,
                 ACTION,
                 DATA,
                 TYPE,
@@ -199,6 +205,7 @@
                 null,
                 null,
                 DESCRIPTION,
+                DESCRIPTION_WITH_APP_NAME,
                 ACTION,
                 null,
                 null,
@@ -221,6 +228,7 @@
                 TITLE_WITHOUT_ENTITY,
                 TITLE_WITH_ENTITY,
                 null,
+                null,
                 ACTION,
                 null,
                 null,
@@ -243,6 +251,7 @@
                 TITLE_WITHOUT_ENTITY,
                 TITLE_WITH_ENTITY,
                 DESCRIPTION,
+                DESCRIPTION_WITH_APP_NAME,
                 null,
                 null,
                 null,
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 8c2375e..185fa07 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -599,7 +599,7 @@
 
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
-        verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
+        verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
         // First invocation is from onCreate
         assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
                 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
@@ -629,7 +629,7 @@
         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
-        verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
+        verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
         // First invocation is from onCreate
         assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
                 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index 7430c7a..453bddd 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -23,6 +23,7 @@
 import static androidx.test.espresso.matcher.ViewMatchers.withId;
 import static androidx.test.espresso.matcher.ViewMatchers.withText;
 
+import static com.android.internal.app.ResolverDataProvider.createPackageManagerMockedInfo;
 import static com.android.internal.app.ResolverWrapperActivity.sOverrides;
 
 import static org.hamcrest.CoreMatchers.is;
@@ -32,6 +33,7 @@
 
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
+import android.text.TextUtils;
 import android.view.View;
 import android.widget.RelativeLayout;
 
@@ -40,7 +42,10 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.R;
+import com.android.internal.app.ResolverActivity.ActivityInfoPresentationGetter;
+import com.android.internal.app.ResolverActivity.ResolveInfoPresentationGetter;
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
+import com.android.internal.app.ResolverDataProvider.PackageManagerMockedInfo;
 import com.android.internal.widget.ResolverDrawerLayout;
 
 import org.junit.Before;
@@ -319,6 +324,50 @@
         assertThat(chosen[0], is(toChoose));
     }
 
+    @Test
+    public void getActivityLabelAndSubLabel() throws Exception {
+        ActivityInfoPresentationGetter pg;
+        PackageManagerMockedInfo info;
+
+        info = createPackageManagerMockedInfo(false);
+        pg = new ActivityInfoPresentationGetter(
+                info.ctx, 0, info.activityInfo);
+        assertThat("Label should match app label", pg.getLabel().equals(
+                info.setAppLabel));
+        assertThat("Sublabel should match activity label if set",
+                pg.getSubLabel().equals(info.setActivityLabel));
+
+        info = createPackageManagerMockedInfo(true);
+        pg = new ActivityInfoPresentationGetter(
+                info.ctx, 0, info.activityInfo);
+        assertThat("With override permission label should match activity label if set",
+                pg.getLabel().equals(info.setActivityLabel));
+        assertThat("With override permission sublabel should be empty",
+                TextUtils.isEmpty(pg.getSubLabel()));
+    }
+
+    @Test
+    public void getResolveInfoLabelAndSubLabel() throws Exception {
+        ResolveInfoPresentationGetter pg;
+        PackageManagerMockedInfo info;
+
+        info = createPackageManagerMockedInfo(false);
+        pg = new ResolveInfoPresentationGetter(
+                info.ctx, 0, info.resolveInfo);
+        assertThat("Label should match app label", pg.getLabel().equals(
+                info.setAppLabel));
+        assertThat("Sublabel should match resolve info label if set",
+                pg.getSubLabel().equals(info.setResolveInfoLabel));
+
+        info = createPackageManagerMockedInfo(true);
+        pg = new ResolveInfoPresentationGetter(
+                info.ctx, 0, info.resolveInfo);
+        assertThat("With override permission label should match resolve info label if set",
+                pg.getLabel().equals(info.setResolveInfoLabel));
+        assertThat("With override permission sublabel should be empty",
+                TextUtils.isEmpty(pg.getSubLabel()));
+    }
+
     private Intent createSendImageIntent() {
         Intent sendIntent = new Intent();
         sendIntent.setAction(Intent.ACTION_SEND);
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java b/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java
index 850b466..59634f6 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java
@@ -17,11 +17,17 @@
 package com.android.internal.app;
 
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.os.UserHandle;
+import android.test.mock.MockContext;
+import android.test.mock.MockPackageManager;
+import android.test.mock.MockResources;
 
 /**
  * Utility class used by resolver tests to create mock data
@@ -71,6 +77,86 @@
         return ai;
     }
 
+    static class PackageManagerMockedInfo {
+        public Context ctx;
+        public ApplicationInfo appInfo;
+        public ActivityInfo activityInfo;
+        public ResolveInfo resolveInfo;
+        public String setAppLabel;
+        public String setActivityLabel;
+        public String setResolveInfoLabel;
+    }
+
+    static PackageManagerMockedInfo createPackageManagerMockedInfo(boolean hasOverridePermission) {
+        final String appLabel = "app_label";
+        final String activityLabel = "activity_label";
+        final String resolveInfoLabel = "resolve_info_label";
+
+        MockContext ctx = new MockContext() {
+            @Override
+            public PackageManager getPackageManager() {
+                return new MockPackageManager() {
+                    @Override
+                    public int checkPermission(String permName, String pkgName) {
+                        if (hasOverridePermission) return PERMISSION_GRANTED;
+                        return PERMISSION_DENIED;
+                    }
+                };
+            }
+
+            @Override
+            public Resources getResources() {
+                return new MockResources() {
+                    @Override
+                    public String getString(int id) throws NotFoundException {
+                        if (id == 1) return appLabel;
+                        if (id == 2) return activityLabel;
+                        if (id == 3) return resolveInfoLabel;
+                        return null;
+                    }
+                };
+            }
+        };
+
+        ApplicationInfo appInfo = new ApplicationInfo() {
+            @Override
+            public CharSequence loadLabel(PackageManager pm) {
+                return appLabel;
+            }
+        };
+        appInfo.labelRes = 1;
+
+        ActivityInfo activityInfo = new ActivityInfo() {
+            @Override
+            public CharSequence loadLabel(PackageManager pm) {
+                return activityLabel;
+            }
+        };
+        activityInfo.labelRes = 2;
+        activityInfo.applicationInfo = appInfo;
+
+        ResolveInfo resolveInfo = new ResolveInfo() {
+            @Override
+            public CharSequence loadLabel(PackageManager pm) {
+                return resolveInfoLabel;
+            }
+        };
+        resolveInfo.activityInfo = activityInfo;
+        resolveInfo.resolvePackageName = "super.fake.packagename";
+        resolveInfo.labelRes = 3;
+
+        PackageManagerMockedInfo mockedInfo = new PackageManagerMockedInfo();
+        mockedInfo.activityInfo = activityInfo;
+        mockedInfo.appInfo = appInfo;
+        mockedInfo.ctx = ctx;
+        mockedInfo.resolveInfo = resolveInfo;
+        mockedInfo.setAppLabel = appLabel;
+        mockedInfo.setActivityLabel = activityLabel;
+        mockedInfo.setResolveInfoLabel = resolveInfoLabel;
+
+        return mockedInfo;
+    }
+
     static Intent createResolverIntent(int i) {
         return new Intent("intentAction" + i);
     }
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java
new file mode 100644
index 0000000..b45f8d2
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mockitoSession;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertThrows;
+
+import static java.util.stream.Collectors.toList;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KernelCpuThreadReaderDiffTest {
+
+    private MockitoSession mMockingSessions;
+    @Mock KernelCpuThreadReader mMockReader;
+
+    @Before
+    public void setUp() {
+        mMockingSessions = mockitoSession().initMocks(this).startMocking();
+    }
+
+    @After
+    public void tearDown() {
+        if (mMockingSessions != null) {
+            mMockingSessions.finishMocking();
+        }
+    }
+
+    @Test
+    public void test_empty() {
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 0);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isEmpty();
+    }
+
+    @Test
+    public void test_simple() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {100, 100, 100}))
+                .thenReturn(createProcess(new int[] {150, 160, 170}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 0);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+        assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()))
+                .containsExactly(Arrays.asList(50, 60, 70));
+    }
+
+    @Test
+    public void test_failure() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {1}))
+                .thenReturn(createProcess(new int[] {2}))
+                .thenThrow(new RuntimeException())
+                .thenReturn(createProcess(new int[] {4}))
+                .thenReturn(createProcess(new int[] {6}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 0);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+        assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()))
+                .containsExactly(Collections.singletonList(1));
+        assertThrows(
+                RuntimeException.class,
+                () -> cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()));
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+        assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()))
+                .containsExactly(Collections.singletonList(2));
+    }
+
+    @Test
+    public void test_twoFailures() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {1}))
+                .thenReturn(createProcess(new int[] {2}))
+                .thenThrow(new RuntimeException())
+                .thenThrow(new RuntimeException())
+                .thenReturn(createProcess(new int[] {4}))
+                .thenReturn(createProcess(new int[] {6}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 0);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+        assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()))
+                .containsExactly(Collections.singletonList(1));
+        assertThrows(
+                RuntimeException.class,
+                () -> cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()));
+        assertThrows(
+                RuntimeException.class,
+                () -> cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()));
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+        assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()))
+                .containsExactly(Collections.singletonList(2));
+    }
+
+    @Test
+    public void test_negativeDiff() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {2}))
+                .thenReturn(createProcess(new int[] {1}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 0);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+        assertThat(cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()))
+                .containsExactly(Collections.singletonList(-1));
+    }
+
+    @Test
+    public void test_threshold() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {1}))
+                .thenReturn(createProcess(new int[] {10}))
+                .thenReturn(createProcess(new int[] {12}))
+                .thenReturn(createProcess(new int[] {20}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 5);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes1 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes1)).containsExactly(Collections.singletonList(9));
+        assertThat(threadNames(processes1)).containsExactly("thread0");
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes2 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes2)).containsExactly(Collections.singletonList(2));
+        assertThat(threadNames(processes2)).containsExactly("__OTHER_THREADS");
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes3 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes3)).containsExactly(Collections.singletonList(8));
+        assertThat(threadNames(processes3)).containsExactly("thread0");
+    }
+
+    @Test
+    public void test_newThread() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {1}))
+                .thenReturn(createProcess(new int[] {2}))
+                .thenReturn(createProcess(new int[] {4}, new int[] {5}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 0);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes1 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes1)).containsExactly(Collections.singletonList(1));
+        assertThat(threadNames(processes1)).containsExactly("thread0");
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes2 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes2))
+                .containsExactly(Collections.singletonList(2), Collections.singletonList(5));
+        assertThat(threadNames(processes2)).containsExactly("thread0", "thread1");
+    }
+
+    @Test
+    public void test_stoppedThread() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {1}, new int[] {1}))
+                .thenReturn(createProcess(new int[] {2}, new int[] {3}))
+                .thenReturn(createProcess(new int[] {4}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 0);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes1 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes1))
+                .containsExactly(Collections.singletonList(1), Collections.singletonList(2));
+        assertThat(threadNames(processes1)).containsExactly("thread0", "thread1");
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes2 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes2)).containsExactly(Collections.singletonList(2));
+        assertThat(threadNames(processes2)).containsExactly("thread0");
+    }
+
+    @Test
+    public void test_nonNegativeOtherThreads() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {0}, new int[] {0}))
+                .thenReturn(createProcess(new int[] {4}, new int[] {4}))
+                .thenReturn(createProcess(new int[] {10}, new int[] {7}))
+                .thenReturn(createProcess(new int[] {20}, new int[] {15}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 5);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes1 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes1)).containsExactly(Collections.singletonList(8));
+        assertThat(threadNames(processes1)).containsExactly("__OTHER_THREADS");
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes2 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes2))
+                .containsExactly(Collections.singletonList(6), Collections.singletonList(3));
+        assertThat(threadNames(processes2)).containsExactly("thread0", "__OTHER_THREADS");
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes3 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes3))
+                .containsExactly(Collections.singletonList(10), Collections.singletonList(8));
+        assertThat(threadNames(processes3)).containsExactly("thread0", "thread1");
+    }
+
+    @Test
+    public void test_otherThreadsOnZeroDiff() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {0}))
+                .thenReturn(createProcess(new int[] {0}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 5);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes1 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes1)).containsExactly(Collections.singletonList(0));
+        assertThat(threadNames(processes1)).containsExactly("__OTHER_THREADS");
+    }
+
+    @Test
+    public void test_failureAndNewThread() {
+        when(mMockReader.getProcessCpuUsage())
+                .thenReturn(createProcess(new int[] {0}))
+                .thenThrow(new RuntimeException())
+                .thenReturn(createProcess(new int[] {1}, new int[] {10}))
+                .thenReturn(createProcess(new int[] {2}, new int[] {12}));
+        KernelCpuThreadReaderDiff kernelCpuThreadReaderDiff =
+                new KernelCpuThreadReaderDiff(mMockReader, 0);
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+
+        assertThrows(
+                RuntimeException.class,
+                () -> cpuUsages(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()));
+        assertThat(kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed()).isNull();
+
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processes1 =
+                kernelCpuThreadReaderDiff.getProcessCpuUsageDiffed();
+        assertThat(cpuUsages(processes1))
+                .containsExactly(Collections.singletonList(1), Collections.singletonList(2));
+        assertThat(threadNames(processes1)).containsExactly("thread0", "thread1");
+    }
+
+    private ArrayList<KernelCpuThreadReader.ProcessCpuUsage> createProcess(
+            int[]... cpuUsageMillis) {
+        ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages = new ArrayList<>();
+        for (int i = 0; i < cpuUsageMillis.length; i++) {
+            int[] cpuUsage = cpuUsageMillis[i];
+            threadCpuUsages.add(
+                    new KernelCpuThreadReader.ThreadCpuUsage(0, "thread" + i, cpuUsage));
+        }
+        return new ArrayList<>(
+                Collections.singletonList(
+                        new KernelCpuThreadReader.ProcessCpuUsage(
+                                0, "process", 0, threadCpuUsages)));
+    }
+
+    private Collection<Collection<Integer>> cpuUsages(
+            Collection<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages) {
+        return processCpuUsages.stream()
+                .flatMap(p -> p.threadCpuUsages.stream())
+                .map(t -> Arrays.stream(t.usageTimesMillis).boxed().collect(toList()))
+                .collect(toList());
+    }
+
+    private Collection<String> threadNames(
+            Collection<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages) {
+        return processCpuUsages.stream()
+                .flatMap(p -> p.threadCpuUsages.stream())
+                .map(t -> t.threadName)
+                .collect(toList());
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
index 1c84829..d43989c 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
@@ -35,6 +35,7 @@
 import java.time.Duration;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.OptionalDouble;
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Consumer;
@@ -124,19 +125,23 @@
 
         // Get thread data from KernelCpuThreadReader
         final KernelCpuThreadReader kernelCpuThreadReader =
-                KernelCpuThreadReader.create(8, uid -> uid == Process.myUid(), 0);
+                KernelCpuThreadReader.create(8, uid -> uid == Process.myUid());
         assertNotNull(kernelCpuThreadReader);
-        final ProcessCpuUsage currentProcessCpuUsage =
-                kernelCpuThreadReader.getCurrentProcessCpuUsage();
+        kernelCpuThreadReader.setUidPredicate(uid -> uid == Process.myUid());
+        final Optional<ProcessCpuUsage> currentProcessCpuUsage =
+                kernelCpuThreadReader.getProcessCpuUsage().stream()
+                        .filter(p -> p.processId == Process.myPid())
+                        .findFirst();
+        assertTrue(currentProcessCpuUsage.isPresent());
 
         // Threads can terminate, as we've finished crawling them from /proc
         threadFinishedLatch.countDown();
 
         // Check that we've got times for every thread we spawned
-        final List<ThreadCpuUsage> threadCpuUsages = currentProcessCpuUsage.threadCpuUsages
-                .stream()
-                .filter((thread) -> thread.threadName.startsWith(tag))
-                .collect(Collectors.toList());
+        final List<ThreadCpuUsage> threadCpuUsages =
+                currentProcessCpuUsage.get().threadCpuUsages.stream()
+                        .filter((thread) -> thread.threadName.startsWith(tag))
+                        .collect(Collectors.toList());
         assertEquals(
                 "Incorrect number of threads returned by KernelCpuThreadReader",
                 numSamples, threadCpuUsages.size());
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
index e6e7a85..c3e4014 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
@@ -25,6 +25,7 @@
 
 import android.content.Context;
 import android.os.FileUtils;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -44,27 +45,10 @@
 import java.util.Comparator;
 import java.util.function.Predicate;
 
+@Presubmit
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class KernelCpuThreadReaderTest {
-
-    private static final int UID = 1000;
-    private static final int PROCESS_ID = 1234;
-    private static final int[] THREAD_IDS = {0, 1000, 1235, 4321};
-    private static final String PROCESS_NAME = "test_process";
-    private static final String[] THREAD_NAMES = {
-            "test_thread_1", "test_thread_2", "test_thread_3", "test_thread_4"
-    };
-    private static final int[] THREAD_CPU_FREQUENCIES = {
-            1000, 2000, 3000, 4000,
-    };
-    private static final int[][] THREAD_CPU_TIMES = {
-            {1, 0, 0, 1},
-            {0, 0, 0, 0},
-            {1000, 1000, 1000, 1000},
-            {0, 1, 2, 3},
-    };
-
     private File mProcDirectory;
 
     @Before
@@ -79,41 +63,6 @@
     }
 
     @Test
-    public void testReader_currentProcess() throws IOException {
-        KernelCpuThreadReader.Injector processUtils =
-                new KernelCpuThreadReader.Injector() {
-                    @Override
-                    public int myPid() {
-                        return PROCESS_ID;
-                    }
-
-                    @Override
-                    public int myUid() {
-                        return UID;
-                    }
-
-                    @Override
-                    public int getUidForPid(int pid) {
-                        return 0;
-                    }
-                };
-        setupDirectory(mProcDirectory.toPath().resolve("self"), THREAD_IDS, PROCESS_NAME,
-                THREAD_NAMES, THREAD_CPU_FREQUENCIES, THREAD_CPU_TIMES);
-
-        final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
-                8,
-                uid -> 1000 <= uid && uid < 2000,
-                0,
-                mProcDirectory.toPath(),
-                mProcDirectory.toPath().resolve("self/task/" + THREAD_IDS[0] + "/time_in_state"),
-                processUtils);
-        final KernelCpuThreadReader.ProcessCpuUsage processCpuUsage =
-                kernelCpuThreadReader.getCurrentProcessCpuUsage();
-        checkResults(processCpuUsage, kernelCpuThreadReader.getCpuFrequenciesKhz(), UID, PROCESS_ID,
-                THREAD_IDS, PROCESS_NAME, THREAD_NAMES, THREAD_CPU_FREQUENCIES, THREAD_CPU_TIMES);
-    }
-
-    @Test
     public void testReader_byUids() throws IOException {
         int[] uids = new int[]{0, 2, 3, 4, 5, 6000};
         Predicate<Integer> uidPredicate = uid -> uid == 0 || uid >= 4;
@@ -121,16 +70,6 @@
         KernelCpuThreadReader.Injector processUtils =
                 new KernelCpuThreadReader.Injector() {
                     @Override
-                    public int myPid() {
-                        return 0;
-                    }
-
-                    @Override
-                    public int myUid() {
-                        return 0;
-                    }
-
-                    @Override
                     public int getUidForPid(int pid) {
                         return pid;
                     }
@@ -145,12 +84,11 @@
         final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
                 8,
                 uidPredicate,
-                0,
                 mProcDirectory.toPath(),
                 mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"),
                 processUtils);
         ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsageByUids =
-                kernelCpuThreadReader.getProcessCpuUsageByUids();
+                kernelCpuThreadReader.getProcessCpuUsage();
         processCpuUsageByUids.sort(Comparator.comparing(usage -> usage.processId));
 
         assertEquals(expectedUids.length, processCpuUsageByUids.size());
@@ -164,105 +102,6 @@
         }
     }
 
-    @Test
-    public void testReader_filtersLowUsage() throws IOException {
-        int[] uids = new int[]{0, 1, 2, 3, 4};
-        int[] cpuUsage = new int[]{10, 0, 2, 100, 3};
-        int[] expectedUids = new int[]{0, 3, 4};
-        Predicate<Integer> uidPredicate = uid -> true;
-        KernelCpuThreadReader.Injector processUtils =
-                new KernelCpuThreadReader.Injector() {
-                    @Override
-                    public int myPid() {
-                        return 0;
-                    }
-
-                    @Override
-                    public int myUid() {
-                        return 0;
-                    }
-
-                    @Override
-                    public int getUidForPid(int pid) {
-                        return pid;
-                    }
-                };
-
-        for (int i = 0; i < uids.length; i++) {
-            int uid = uids[i];
-            setupDirectory(
-                    mProcDirectory.toPath().resolve(String.valueOf(uid)),
-                    new int[]{uid * 10},
-                    "process" + uid,
-                    new String[]{"thread" + uid},
-                    new int[]{1000},
-                    new int[][]{{cpuUsage[i]}});
-        }
-        final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
-                8,
-                uidPredicate,
-                30,
-                mProcDirectory.toPath(),
-                mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"),
-                processUtils);
-        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsageByUids =
-                kernelCpuThreadReader.getProcessCpuUsageByUids();
-        processCpuUsageByUids.sort(Comparator.comparing(usage -> usage.uid));
-
-        assertEquals(expectedUids.length, processCpuUsageByUids.size());
-        for (int i = 0; i < expectedUids.length; i++) {
-            KernelCpuThreadReader.ProcessCpuUsage processCpuUsage =
-                    processCpuUsageByUids.get(i);
-            assertEquals(expectedUids[i], processCpuUsage.uid);
-        }
-
-    }
-
-    @Test
-    public void testReader_otherThreads() throws IOException {
-        final Path processPath = mProcDirectory.toPath().resolve("self");
-        setupDirectory(
-                processPath,
-                new int[]{1, 2, 3},
-                "process",
-                new String[]{"thread1", "thread2", "thread3"},
-                new int[]{1000, 2000},
-                new int[][]{{0, 100}, {10, 0}, {0, 300}});
-        final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
-                8,
-                i -> true,
-                2000,
-                mProcDirectory.toPath(),
-                processPath.resolve("task/1/time_in_state"),
-                new KernelCpuThreadReader.Injector() {
-                    @Override
-                    public int myPid() {
-                        return 1000;
-                    }
-
-                    @Override
-                    public int myUid() {
-                        return 0;
-                    }
-
-                    @Override
-                    public int getUidForPid(int pid) {
-                        return 0;
-                    }
-                });
-        checkResults(
-                kernelCpuThreadReader.getCurrentProcessCpuUsage(),
-                kernelCpuThreadReader.getCpuFrequenciesKhz(),
-                0,
-                1000,
-                new int[]{-1, 3},
-                "process",
-                new String[]{"__OTHER_THREADS", "thread3"},
-                new int[]{1000, 2000},
-                new int[][]{{100, 1000}, {0, 3000}}
-        );
-    }
-
     private void setupDirectory(Path processPath, int[] threadIds, String processName,
             String[] threadNames, int[] cpuFrequencies, int[][] cpuTimes) throws IOException {
         // Make /proc/$PID
@@ -289,8 +128,7 @@
             final OutputStream timeInStateStream =
                     Files.newOutputStream(threadPath.resolve("time_in_state"));
             for (int j = 0; j < cpuFrequencies.length; j++) {
-                final String line = String.valueOf(cpuFrequencies[j]) + " "
-                        + String.valueOf(cpuTimes[i][j]) + "\n";
+                final String line = cpuFrequencies[j] + " " + cpuTimes[i][j] + "\n";
                 timeInStateStream.write(line.getBytes());
             }
             timeInStateStream.close();
@@ -338,10 +176,10 @@
                 frequencies, 4);
         assertArrayEquals(
                 new int[]{1, 3, 1, 3},
-                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
+                frequencyBucketCreator.bucketFrequencies(frequencies));
         assertArrayEquals(
                 new int[]{2, 2, 2, 2},
-                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
+                frequencyBucketCreator.bucketValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
     }
 
     @Test
@@ -352,10 +190,10 @@
                 frequencies, 4);
         assertArrayEquals(
                 new int[]{1, 3, 5, 7},
-                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
+                frequencyBucketCreator.bucketFrequencies(frequencies));
         assertArrayEquals(
                 new int[]{2, 2, 2, 2},
-                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
+                frequencyBucketCreator.bucketValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
     }
 
     @Test
@@ -366,10 +204,10 @@
                 frequencies, 4);
         assertArrayEquals(
                 new int[]{1, 3, 1, 2},
-                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
+                frequencyBucketCreator.bucketFrequencies(frequencies));
         assertArrayEquals(
                 new int[]{2, 3, 1, 2},
-                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
+                frequencyBucketCreator.bucketValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
     }
 
     @Test
@@ -380,10 +218,10 @@
                 frequencies, 4);
         assertArrayEquals(
                 new int[]{1, 2, 1, 3},
-                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
+                frequencyBucketCreator.bucketFrequencies(frequencies));
         assertArrayEquals(
                 new int[]{1, 2, 2, 3},
-                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
+                frequencyBucketCreator.bucketValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
     }
 
     @Test
@@ -394,10 +232,10 @@
                 frequencies, 8);
         assertArrayEquals(
                 new int[]{1, 2, 3, 4, 1, 2, 3, 4},
-                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
+                frequencyBucketCreator.bucketFrequencies(frequencies));
         assertArrayEquals(
                 new int[]{1, 1, 1, 1, 1, 1, 1, 1},
-                frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
+                frequencyBucketCreator.bucketValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
     }
 
     @Test
@@ -408,10 +246,10 @@
                 frequencies, 8);
         assertArrayEquals(
                 new int[]{1, 3, 5, 7, 1, 2, 3},
-                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
+                frequencyBucketCreator.bucketFrequencies(frequencies));
         assertArrayEquals(
                 new int[]{2, 2, 2, 3, 1, 1, 1},
-                frequencyBucketCreator.getBucketedValues(
+                frequencyBucketCreator.bucketValues(
                         new long[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}));
     }
 
@@ -423,39 +261,37 @@
                 frequencies, 1);
         assertArrayEquals(
                 new int[]{1},
-                frequencyBucketCreator.getBucketMinFrequencies(frequencies));
+                frequencyBucketCreator.bucketFrequencies(frequencies));
         assertArrayEquals(
                 new int[]{8},
-                frequencyBucketCreator.getBucketedValues(
+                frequencyBucketCreator.bucketValues(
                         new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
     }
 
     @Test
-    public void testGetBigFrequenciesStartIndex_simple() {
-        assertEquals(
-                3, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
-                        new long[]{1, 2, 3, 1, 2, 3}));
+    public void testBucketSetup_threeClusters() {
+        long[] frequencies = {1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6};
+        KernelCpuThreadReader.FrequencyBucketCreator frequencyBucketCreator =
+                new KernelCpuThreadReader.FrequencyBucketCreator(frequencies, 6);
+        assertArrayEquals(
+                new int[] {1, 3, 2, 4, 3, 5},
+                frequencyBucketCreator.bucketFrequencies(frequencies));
+        assertArrayEquals(
+                new int[] {2, 2, 2, 2, 2, 2},
+                frequencyBucketCreator.bucketValues(
+                        new long[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}));
     }
 
     @Test
-    public void testGetBigFrequenciesStartIndex_moreLittle() {
-        assertEquals(
-                4, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
-                        new long[]{1, 2, 3, 4, 1, 2}));
-    }
-
-    @Test
-    public void testGetBigFrequenciesStartIndex_moreBig() {
-        assertEquals(
-                2, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
-                        new long[]{1, 2, 1, 2, 3, 4}));
-    }
-
-    @Test
-    public void testGetBigFrequenciesStartIndex_noBig() {
-        assertEquals(
-                4, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
-                        new long[]{1, 2, 3, 4}));
+    public void testBucketSetup_moreClustersThanBuckets() {
+        long[] frequencies = {1, 1, 1, 1, 1, 1, 1, 1};
+        KernelCpuThreadReader.FrequencyBucketCreator frequencyBucketCreator =
+                new KernelCpuThreadReader.FrequencyBucketCreator(frequencies, 4);
+        assertArrayEquals(
+                new int[] {1, 1, 1, 1}, frequencyBucketCreator.bucketFrequencies(frequencies));
+        assertArrayEquals(
+                new int[] {1, 1, 1, 5},
+                frequencyBucketCreator.bucketValues(new long[] {1, 1, 1, 1, 1, 1, 1, 1}));
     }
 
     @Test
diff --git a/core/tests/featureflagtests/Android.bp b/core/tests/featureflagtests/Android.bp
new file mode 100644
index 0000000..8730b70
--- /dev/null
+++ b/core/tests/featureflagtests/Android.bp
@@ -0,0 +1,19 @@
+android_test {
+    name: "FrameworksCoreFeatureFlagTests",
+    // We only want this apk build for tests.
+    // Include all test java files.
+    srcs: ["src/**/*.java"],
+    dxflags: ["--core-library"],
+    static_libs: [
+        "android-common",
+        "frameworks-core-util-lib",
+        "androidx.test.rules",
+    ],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+    platform_apis: true,
+    certificate: "platform",
+    test_suites: ["device-tests"],
+}
diff --git a/core/tests/featureflagtests/Android.mk b/core/tests/featureflagtests/Android.mk
deleted file mode 100644
index ce7cb18..0000000
--- a/core/tests/featureflagtests/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, src)
-
-LOCAL_DX_FLAGS := --core-library
-LOCAL_STATIC_JAVA_LIBRARIES := android-common frameworks-core-util-lib androidx.test.rules
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
-LOCAL_PACKAGE_NAME := FrameworksCoreFeatureFlagTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/device/Android.mk b/core/tests/overlaytests/device/Android.mk
index 5630749..c6d2a51 100644
--- a/core/tests/overlaytests/device/Android.mk
+++ b/core/tests/overlaytests/device/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
 LOCAL_COMPATIBILITY_SUITE := device-tests
-LOCAL_TARGET_REQUIRED_MODULES := \
+LOCAL_REQUIRED_MODULES := \
     OverlayDeviceTests_AppOverlayOne \
     OverlayDeviceTests_AppOverlayTwo \
     OverlayDeviceTests_FrameworkOverlay
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk b/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
index 97a3d00..fa15241 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
@@ -19,7 +19,6 @@
 LOCAL_PACKAGE_NAME := OverlayDeviceTests_AppOverlayOne
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
-LOCAL_CERTIFICATE := platform
 LOCAL_USE_AAPT2 := true
 LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml
index 8ac6953..7d28408 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml
@@ -19,5 +19,5 @@
         android:versionCode="1"
         android:versionName="1.0">
         <application android:hasCode="false" />
-        <overlay android:targetPackage="com.android.overlaytest" android:priority="1" />
+        <overlay android:targetPackage="com.android.overlaytest" />
 </manifest>
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
index a347025..ada9b3c 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
@@ -19,7 +19,6 @@
 LOCAL_PACKAGE_NAME := OverlayDeviceTests_AppOverlayTwo
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
-LOCAL_CERTIFICATE := platform
 LOCAL_USE_AAPT2 := true
 LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/AndroidManifest.xml b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/AndroidManifest.xml
index f3c39cc..6e75a350 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/AndroidManifest.xml
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/AndroidManifest.xml
@@ -19,5 +19,5 @@
         android:versionCode="1"
         android:versionName="1.0">
         <application android:hasCode="false" />
-        <overlay android:targetPackage="com.android.overlaytest" android:priority="2" />
+        <overlay android:targetPackage="com.android.overlaytest" />
 </manifest>
diff --git a/core/tests/overlaytests/host/Android.mk b/core/tests/overlaytests/host/Android.mk
index b48a46b..e7348d5 100644
--- a/core/tests/overlaytests/host/Android.mk
+++ b/core/tests/overlaytests/host/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_JAVA_LIBRARIES := tradefed
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_TARGET_REQUIRED_MODULES := \
-    OverlayHostTests_BadSignatureOverlay \
+    OverlayHostTests_NonPlatformSignatureOverlay \
     OverlayHostTests_PlatformSignatureStaticOverlay \
     OverlayHostTests_PlatformSignatureOverlay \
     OverlayHostTests_UpdateOverlay \
diff --git a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
index f9672d2..99b6421 100644
--- a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
+++ b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java
@@ -67,10 +67,10 @@
     }
 
     @Test
-    public void failToInstallNonPlatformSignedOverlay() throws Exception {
+    public void failToInstallNonPlatformSignedOverlayTargetPreQ() throws Exception {
         try {
-            installPackage("OverlayHostTests_BadSignatureOverlay.apk");
-            fail("installed a non-platform signed overlay");
+            installPackage("OverlayHostTests_NonPlatformSignatureOverlay.apk");
+            fail("installed a non-platform signed overlay with targetSdkVersion < Q");
         } catch (Exception e) {
             // Expected.
         }
@@ -155,9 +155,17 @@
         }
     }
 
+    @Test
+    public void instantAppsNotVisibleToOMS() throws Exception {
+        installInstantPackage("OverlayHostTests_AppOverlayV1.apk");
+        assertFalse(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
+        installConvertExistingInstantPackageToFull(APP_OVERLAY_PACKAGE_NAME);
+        assertTrue(overlayManagerContainsPackage(APP_OVERLAY_PACKAGE_NAME));
+    }
+
     private void delay() {
         try {
-            Thread.sleep(100);
+            Thread.sleep(1000);
         } catch (InterruptedException e) {
         }
     }
@@ -167,6 +175,15 @@
         delay();
     }
 
+    private void installInstantPackage(String pkg) throws Exception {
+        super.installPackage(pkg, "--instant");
+        delay();
+    }
+
+    private void installConvertExistingInstantPackageToFull(String pkg) throws Exception {
+        getDevice().executeShellCommand("cmd package install-existing --wait --full " + pkg);
+    }
+
     private void setPackageEnabled(String pkg, boolean enabled) throws Exception {
         getDevice().executeShellCommand("cmd package " + (enabled ? "enable " : "disable ") + pkg);
         delay();
diff --git a/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk
index 3d2410d..cc7704b 100644
--- a/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/SignatureOverlay/Android.mk
@@ -18,7 +18,7 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE_TAGS := tests
-LOCAL_PACKAGE_NAME := OverlayHostTests_BadSignatureOverlay
+LOCAL_PACKAGE_NAME := OverlayHostTests_NonPlatformSignatureOverlay
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_bad
diff --git a/core/tests/overlaytests/host/test-apps/SignatureOverlay/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/SignatureOverlay/AndroidManifest.xml
index 26b3875..67592f8 100644
--- a/core/tests/overlaytests/host/test-apps/SignatureOverlay/AndroidManifest.xml
+++ b/core/tests/overlaytests/host/test-apps/SignatureOverlay/AndroidManifest.xml
@@ -16,6 +16,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.server.om.hosttest.signature_overlay">
+    <uses-sdk android:targetSdkVersion="28" />
     <application android:hasCode="false" />
     <overlay android:targetPackage="android" />
 </manifest>
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
index c7b2dd1..f8607f4 100644
--- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
@@ -58,7 +58,6 @@
 LOCAL_PACKAGE_NAME := OverlayHostTests_AppOverlayV1
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
-LOCAL_CERTIFICATE := platform
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
 LOCAL_AAPT_FLAGS += --version-code 1 --version-name v1
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v1/res
@@ -70,7 +69,6 @@
 LOCAL_PACKAGE_NAME := OverlayHostTests_AppOverlayV2
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
-LOCAL_CERTIFICATE := platform
 LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v2
 LOCAL_AAPT_FLAGS += --version-code 2 --version-name v2
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v2/res
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml
index f1a3981..b6ff0c3 100644
--- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml
@@ -17,6 +17,5 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.server.om.hosttest.app_overlay">
     <application android:hasCode="false" />
-    <overlay android:targetPackage="com.android.server.om.hosttest.update_overlay_test"
-        android:category="android.theme" />
+    <overlay android:targetPackage="com.android.server.om.hosttest.update_overlay_test" />
 </manifest>
diff --git a/core/xsd/Android.bp b/core/xsd/Android.bp
index 81669eb..738f330 100644
--- a/core/xsd/Android.bp
+++ b/core/xsd/Android.bp
@@ -2,5 +2,5 @@
     name: "permission",
     srcs: ["permission.xsd"],
     api_dir: "schema",
-    package_name: "com.android.xml.permission",
+    package_name: "com.android.xml.permission.configfile",
 }
diff --git a/core/xsd/permission.xsd b/core/xsd/permission.xsd
index d90863b..2ef2d04 100644
--- a/core/xsd/permission.xsd
+++ b/core/xsd/permission.xsd
@@ -60,8 +60,6 @@
         <xs:attribute name="uid" type="xs:int"/>
     </xs:complexType>
     <xs:complexType name="split-permission">
-        <xs:attribute name="name" type="xs:string"/>
-        <xs:attribute name="targetSdk" type="xs:int"/>
         <xs:sequence>
             <xs:element name="library" maxOccurs="unbounded">
                 <xs:complexType>
@@ -69,6 +67,8 @@
                 </xs:complexType>
             </xs:element>
         </xs:sequence>
+        <xs:attribute name="name" type="xs:string"/>
+        <xs:attribute name="targetSdk" type="xs:int"/>
     </xs:complexType>
     <xs:complexType name="library">
         <xs:attribute name="name" type="xs:string"/>
@@ -78,6 +78,7 @@
     <xs:complexType name="feature">
         <xs:attribute name="name" type="xs:string"/>
         <xs:attribute name="notLowRam" type="xs:string"/>
+        <xs:attribute name="version" type="xs:int"/>
     </xs:complexType>
     <xs:complexType name="unavailable-feature">
         <xs:attribute name="name" type="xs:string"/>
@@ -124,7 +125,6 @@
         <xs:attribute name="package" type="xs:string"/>
     </xs:complexType>
     <xs:complexType name="privapp-permissions">
-        <xs:attribute name="package" type="xs:string"/>
         <xs:sequence>
             <xs:element name="permission" maxOccurs="unbounded">
                 <xs:complexType>
@@ -137,9 +137,9 @@
                 </xs:complexType>
             </xs:element>
         </xs:sequence>
+        <xs:attribute name="package" type="xs:string"/>
     </xs:complexType>
     <xs:complexType name="oem-permissions">
-        <xs:attribute name="package" type="xs:string"/>
         <xs:sequence>
             <xs:element name="permission" maxOccurs="unbounded">
                 <xs:complexType>
@@ -152,6 +152,7 @@
                 </xs:complexType>
             </xs:element>
         </xs:sequence>
+        <xs:attribute name="package" type="xs:string"/>
     </xs:complexType>
     <xs:complexType name="hidden-api-whitelisted-app">
         <xs:attribute name="package" type="xs:string"/>
diff --git a/core/xsd/schema/current.txt b/core/xsd/schema/current.txt
index 82bb0fea..c25bc14 100644
--- a/core/xsd/schema/current.txt
+++ b/core/xsd/schema/current.txt
@@ -1,5 +1,5 @@
 // Signature format: 2.0
-package com.android.xml.permission {
+package com.android.xml.permission.configfile {
 
   public class AllowAssociation {
     ctor public AllowAssociation();
@@ -97,8 +97,10 @@
     ctor public Feature();
     method public String getName();
     method public String getNotLowRam();
+    method public int getVersion();
     method public void setName(String);
     method public void setNotLowRam(String);
+    method public void setVersion(int);
   }
 
   public class Group {
@@ -125,8 +127,8 @@
 
   public class OemPermissions {
     ctor public OemPermissions();
-    method public java.util.List<com.android.xml.permission.OemPermissions.DenyPermission> getDenyPermission();
-    method public java.util.List<com.android.xml.permission.OemPermissions.Permission> getPermission();
+    method public java.util.List<com.android.xml.permission.configfile.OemPermissions.DenyPermission> getDenyPermission();
+    method public java.util.List<com.android.xml.permission.configfile.OemPermissions.Permission> getPermission();
     method public String get_package();
     method public void set_package(String);
   }
@@ -151,37 +153,37 @@
 
   public class Permissions {
     ctor public Permissions();
-    method public java.util.List<com.android.xml.permission.AllowAssociation> getAllowAssociation();
-    method public java.util.List<com.android.xml.permission.AllowIgnoreLocationSettings> getAllowIgnoreLocationSettings();
-    method public java.util.List<com.android.xml.permission.AllowImplicitBroadcast> getAllowImplicitBroadcast();
-    method public java.util.List<com.android.xml.permission.AllowInDataUsageSave> getAllowInDataUsageSave();
-    method public java.util.List<com.android.xml.permission.AllowInPowerSave> getAllowInPowerSave();
-    method public java.util.List<com.android.xml.permission.AllowInPowerSaveExceptIdle> getAllowInPowerSaveExceptIdle();
-    method public java.util.List<com.android.xml.permission.AllowUnthrottledLocation> getAllowUnthrottledLocation();
-    method public java.util.List<com.android.xml.permission.AppLink> getAppLink();
-    method public java.util.List<com.android.xml.permission.AssignPermission> getAssignPermission();
-    method public java.util.List<com.android.xml.permission.BackupTransportWhitelistedService> getBackupTransportWhitelistedService();
-    method public java.util.List<com.android.xml.permission.BugreportWhitelisted> getBugreportWhitelisted();
-    method public java.util.List<com.android.xml.permission.DefaultEnabledVrApp> getDefaultEnabledVrApp();
-    method public java.util.List<com.android.xml.permission.DisabledUntilUsedPreinstalledCarrierApp> getDisabledUntilUsedPreinstalledCarrierApp();
-    method public java.util.List<com.android.xml.permission.DisabledUntilUsedPreinstalledCarrierAssociatedApp> getDisabledUntilUsedPreinstalledCarrierAssociatedApp();
-    method public java.util.List<com.android.xml.permission.Feature> getFeature();
-    method public java.util.List<com.android.xml.permission.Group> getGroup();
-    method public java.util.List<com.android.xml.permission.HiddenApiWhitelistedApp> getHiddenApiWhitelistedApp();
-    method public java.util.List<com.android.xml.permission.Library> getLibrary();
-    method public java.util.List<com.android.xml.permission.OemPermissions> getOemPermissions();
-    method public java.util.List<com.android.xml.permission.Permission> getPermission();
-    method public java.util.List<com.android.xml.permission.PrivappPermissions> getPrivappPermissions();
-    method public java.util.List<com.android.xml.permission.SplitPermission> getSplitPermission();
-    method public java.util.List<com.android.xml.permission.SystemUserBlacklistedApp> getSystemUserBlacklistedApp();
-    method public java.util.List<com.android.xml.permission.SystemUserWhitelistedApp> getSystemUserWhitelistedApp();
-    method public java.util.List<com.android.xml.permission.UnavailableFeature> getUnavailableFeature();
+    method public java.util.List<com.android.xml.permission.configfile.AllowAssociation> getAllowAssociation();
+    method public java.util.List<com.android.xml.permission.configfile.AllowIgnoreLocationSettings> getAllowIgnoreLocationSettings();
+    method public java.util.List<com.android.xml.permission.configfile.AllowImplicitBroadcast> getAllowImplicitBroadcast();
+    method public java.util.List<com.android.xml.permission.configfile.AllowInDataUsageSave> getAllowInDataUsageSave();
+    method public java.util.List<com.android.xml.permission.configfile.AllowInPowerSave> getAllowInPowerSave();
+    method public java.util.List<com.android.xml.permission.configfile.AllowInPowerSaveExceptIdle> getAllowInPowerSaveExceptIdle();
+    method public java.util.List<com.android.xml.permission.configfile.AllowUnthrottledLocation> getAllowUnthrottledLocation();
+    method public java.util.List<com.android.xml.permission.configfile.AppLink> getAppLink();
+    method public java.util.List<com.android.xml.permission.configfile.AssignPermission> getAssignPermission();
+    method public java.util.List<com.android.xml.permission.configfile.BackupTransportWhitelistedService> getBackupTransportWhitelistedService();
+    method public java.util.List<com.android.xml.permission.configfile.BugreportWhitelisted> getBugreportWhitelisted();
+    method public java.util.List<com.android.xml.permission.configfile.DefaultEnabledVrApp> getDefaultEnabledVrApp();
+    method public java.util.List<com.android.xml.permission.configfile.DisabledUntilUsedPreinstalledCarrierApp> getDisabledUntilUsedPreinstalledCarrierApp();
+    method public java.util.List<com.android.xml.permission.configfile.DisabledUntilUsedPreinstalledCarrierAssociatedApp> getDisabledUntilUsedPreinstalledCarrierAssociatedApp();
+    method public java.util.List<com.android.xml.permission.configfile.Feature> getFeature();
+    method public java.util.List<com.android.xml.permission.configfile.Group> getGroup();
+    method public java.util.List<com.android.xml.permission.configfile.HiddenApiWhitelistedApp> getHiddenApiWhitelistedApp();
+    method public java.util.List<com.android.xml.permission.configfile.Library> getLibrary();
+    method public java.util.List<com.android.xml.permission.configfile.OemPermissions> getOemPermissions();
+    method public java.util.List<com.android.xml.permission.configfile.Permission> getPermission();
+    method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions> getPrivappPermissions();
+    method public java.util.List<com.android.xml.permission.configfile.SplitPermission> getSplitPermission();
+    method public java.util.List<com.android.xml.permission.configfile.SystemUserBlacklistedApp> getSystemUserBlacklistedApp();
+    method public java.util.List<com.android.xml.permission.configfile.SystemUserWhitelistedApp> getSystemUserWhitelistedApp();
+    method public java.util.List<com.android.xml.permission.configfile.UnavailableFeature> getUnavailableFeature();
   }
 
   public class PrivappPermissions {
     ctor public PrivappPermissions();
-    method public java.util.List<com.android.xml.permission.PrivappPermissions.DenyPermission> getDenyPermission();
-    method public java.util.List<com.android.xml.permission.PrivappPermissions.Permission> getPermission();
+    method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions.DenyPermission> getDenyPermission();
+    method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions.Permission> getPermission();
     method public String get_package();
     method public void set_package(String);
   }
@@ -200,7 +202,7 @@
 
   public class SplitPermission {
     ctor public SplitPermission();
-    method public java.util.List<com.android.xml.permission.SplitPermission.Library> getLibrary();
+    method public java.util.List<com.android.xml.permission.configfile.SplitPermission.Library> getLibrary();
     method public String getName();
     method public int getTargetSdk();
     method public void setName(String);
@@ -233,7 +235,7 @@
 
   public class XmlParser {
     ctor public XmlParser();
-    method public static com.android.xml.permission.Permissions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static com.android.xml.permission.configfile.Permissions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
   }
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index bb47658..3968f84 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -66,6 +66,14 @@
 }
 
 prebuilt_etc {
+    name: "privapp_whitelist_com.android.emergency",
+    product_specific: true,
+    sub_dir: "permissions",
+    src: "com.android.emergency.xml",
+    filename_from_src: true,
+}
+
+prebuilt_etc {
     name: "privapp_whitelist_com.android.launcher3",
     product_specific: true,
     sub_dir: "permissions",
diff --git a/data/etc/com.android.emergency.xml b/data/etc/com.android.emergency.xml
new file mode 100644
index 0000000..28f99dd
--- /dev/null
+++ b/data/etc/com.android.emergency.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<permissions>
+    <privapp-permissions package="com.android.emergency">
+        <!-- Required to place emergency calls from emergency info screen. -->
+        <permission name="android.permission.CALL_PRIVILEGED"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+    </privapp-permissions>
+</permissions>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 28d311e..0e957df 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -202,36 +202,6 @@
         <new-permission name="android.permission.ACCESS_BACKGROUND_LOCATION" />
     </split-permission>
 
-    <!-- STOPSHIP: change targetSdk to Q when SDK version finalised -->
-    <!-- Old apps might not understand the modern permission model, hence their view needs to be expanded -->
-    <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
-                      targetSdk="10000">
-        <new-permission name="android.permission.READ_MEDIA_AUDIO" />
-        <new-permission name="android.permission.READ_MEDIA_VIDEO" />
-        <new-permission name="android.permission.READ_MEDIA_IMAGES" />
-    </split-permission>
-    <!-- STOPSHIP: change targetSdk to Q when SDK version finalised -->
-    <split-permission name="android.permission.WRITE_EXTERNAL_STORAGE"
-                      targetSdk="10000">
-        <new-permission name="android.permission.READ_MEDIA_AUDIO" />
-        <new-permission name="android.permission.READ_MEDIA_VIDEO" />
-        <new-permission name="android.permission.READ_MEDIA_IMAGES" />
-    </split-permission>
-
-    <!-- An app using the typed media permissions might be grandfathered and then uses the old storage model -->
-    <split-permission name="android.permission.READ_MEDIA_AUDIO">
-        <new-permission name="android.permission.READ_EXTERNAL_STORAGE" />
-        <new-permission name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    </split-permission>
-    <split-permission name="android.permission.READ_MEDIA_VIDEO">
-        <new-permission name="android.permission.READ_EXTERNAL_STORAGE" />
-        <new-permission name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    </split-permission>
-    <split-permission name="android.permission.READ_MEDIA_IMAGES">
-        <new-permission name="android.permission.READ_EXTERNAL_STORAGE" />
-        <new-permission name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    </split-permission>
-
     <!-- This is a list of all the libraries available for application
          code to link against. -->
 
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index afb5071..ed198e6 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -50,12 +50,6 @@
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
     </privapp-permissions>
 
-    <privapp-permissions package="com.android.emergency">
-        <!-- Required to place emergency calls from emergency info screen. -->
-        <permission name="android.permission.CALL_PRIVILEGED"/>
-        <permission name="android.permission.MANAGE_USERS"/>
-    </privapp-permissions>
-
     <privapp-permissions package="com.android.externalstorage">
         <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
@@ -124,6 +118,7 @@
         <permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"/>
         <permission name="android.permission.APPROVE_INCIDENT_REPORTS"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
+        <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.phone">
@@ -263,6 +258,7 @@
         <permission name="android.permission.ACTIVITY_EMBEDDING"/>
         <permission name="android.permission.FORCE_STOP_PACKAGES"/>
         <permission name="android.permission.GET_APP_OPS_STATS"/>
+        <permission name="android.permission.INSTALL_DYNAMIC_SYSTEM"/>
         <permission name="android.permission.INSTALL_LOCATION_PROVIDER"/>
         <permission name="android.permission.INSTALL_PACKAGES"/>
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
@@ -276,7 +272,10 @@
         <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
         <permission name="android.permission.MOVE_PACKAGE"/>
         <permission name="android.permission.OBSERVE_APP_USAGE"/>
+        <permission name="android.permission.NETWORK_SCAN"/>
         <permission name="android.permission.PACKAGE_USAGE_STATS" />
+        <!-- Needed for test only -->
+        <permission name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
         <permission name="android.permission.POWER_SAVER" />
         <permission name="android.permission.READ_FRAME_BUFFER"/>
         <permission name="android.permission.READ_LOWPAN_CREDENTIAL"/>
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index fd37735..c9431e3 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -112,14 +112,14 @@
     public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
         throwIfCannotDraw(bitmap);
         throwIfHasHwBitmapInSwMode(paint);
-        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
+        nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top,
                 paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
                 bitmap.mDensity);
     }
 
     public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
         throwIfHasHwBitmapInSwMode(paint);
-        nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
+        nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap.getNativeInstance(), matrix.ni(),
                 paint != null ? paint.getNativeInstance() : 0);
     }
 
@@ -144,7 +144,7 @@
             bottom = src.bottom;
         }
 
-        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+        nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top, right, bottom,
                 dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
                 bitmap.mDensity);
     }
@@ -170,7 +170,7 @@
             bottom = src.bottom;
         }
 
-        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+        nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top, right, bottom,
                 dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
                 bitmap.mDensity);
     }
@@ -229,7 +229,7 @@
             // no mul by 2, since we need only 1 color per vertex
             checkRange(colors.length, colorOffset, count);
         }
-        nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
+        nDrawBitmapMesh(mNativeCanvasWrapper, bitmap.getNativeInstance(), meshWidth, meshHeight,
                 verts, vertOffset, colors, colorOffset,
                 paint != null ? paint.getNativeInstance() : 0);
     }
@@ -240,7 +240,7 @@
     }
 
     public void drawColor(@ColorInt int color) {
-        nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
+        nDrawColor(mNativeCanvasWrapper, color, BlendMode.SRC_OVER.getXfermode().porterDuffMode);
     }
 
     /**
@@ -664,10 +664,11 @@
         }
     }
 
-    private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
-            long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
+    private static native void nDrawBitmap(long nativeCanvas, long bitmapHandle, float left,
+            float top, long nativePaintOrZero, int canvasDensity, int screenDensity,
+            int bitmapDensity);
 
-    private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float srcLeft,
+    private static native void nDrawBitmap(long nativeCanvas, long bitmapHandle, float srcLeft,
             float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
             float dstBottom, long nativePaintOrZero, int screenDensity, int bitmapDensity);
@@ -726,10 +727,10 @@
             float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero,
             int screenDensity, int bitmapDensity);
 
-    private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap,
+    private static native void nDrawBitmapMatrix(long nativeCanvas, long bitmapHandle,
             long nativeMatrix, long nativePaint);
 
-    private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth,
+    private static native void nDrawBitmapMesh(long nativeCanvas, long bitmapHandle, int meshWidth,
             int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset,
             long nativePaint);
 
diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java
index 3e11741..028b784 100644
--- a/graphics/java/android/graphics/BaseRecordingCanvas.java
+++ b/graphics/java/android/graphics/BaseRecordingCanvas.java
@@ -67,7 +67,7 @@
     public final void drawBitmap(@NonNull Bitmap bitmap, float left, float top,
             @Nullable Paint paint) {
         throwIfCannotDraw(bitmap);
-        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
+        nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top,
                 paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
                 bitmap.mDensity);
     }
@@ -75,7 +75,7 @@
     @Override
     public final void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix,
             @Nullable Paint paint) {
-        nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
+        nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap.getNativeInstance(), matrix.ni(),
                 paint != null ? paint.getNativeInstance() : 0);
     }
 
@@ -100,7 +100,7 @@
             bottom = src.bottom;
         }
 
-        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+        nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top, right, bottom,
                 dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
                 bitmap.mDensity);
     }
@@ -126,7 +126,7 @@
             bottom = src.bottom;
         }
 
-        nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+        nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top, right, bottom,
                 dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
                 bitmap.mDensity);
     }
@@ -188,7 +188,7 @@
             // no mul by 2, since we need only 1 color per vertex
             checkRange(colors.length, colorOffset, count);
         }
-        nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
+        nDrawBitmapMesh(mNativeCanvasWrapper, bitmap.getNativeInstance(), meshWidth, meshHeight,
                 verts, vertOffset, colors, colorOffset,
                 paint != null ? paint.getNativeInstance() : 0);
     }
@@ -200,7 +200,7 @@
 
     @Override
     public final void drawColor(@ColorInt int color) {
-        nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
+        nDrawColor(mNativeCanvasWrapper, color, BlendMode.SRC_OVER.getXfermode().porterDuffMode);
     }
 
     /**
@@ -581,11 +581,12 @@
     }
 
     @FastNative
-    private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
-            long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
+    private static native void nDrawBitmap(long nativeCanvas, long bitmapHandle, float left,
+            float top, long nativePaintOrZero, int canvasDensity, int screenDensity,
+            int bitmapDensity);
 
     @FastNative
-    private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap,
+    private static native void nDrawBitmap(long nativeCanvas, long bitmapHandle,
             float srcLeft, float srcTop, float srcRight, float srcBottom,
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             long nativePaintOrZero, int screenDensity, int bitmapDensity);
@@ -663,11 +664,11 @@
             int screenDensity, int bitmapDensity);
 
     @FastNative
-    private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap,
+    private static native void nDrawBitmapMatrix(long nativeCanvas, long bitmapHandle,
             long nativeMatrix, long nativePaint);
 
     @FastNative
-    private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth,
+    private static native void nDrawBitmapMesh(long nativeCanvas, long bitmapHandle, int meshWidth,
             int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset,
             long nativePaint);
 
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 4bd344f..170dec2 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1813,21 +1813,22 @@
     }
 
     /**
-     * Fills the bitmap's pixels with the specified {@link Color}.
+     * Fills the bitmap's pixels with the specified {@code ColorLong}.
      *
+     * @param color The color to fill as packed by the {@link Color} class.
      * @throws IllegalStateException if the bitmap is not mutable.
-     * @throws IllegalArgumentException if the color space encoded in the long
-     *                                  is invalid or unknown.
+     * @throws IllegalArgumentException if the color space encoded in the
+     *                                  {@code ColorLong} is invalid or unknown.
      *
      */
-    public void eraseColor(@ColorLong long c) {
+    public void eraseColor(@ColorLong long color) {
         checkRecycled("Can't erase a recycled bitmap");
         if (!isMutable()) {
             throw new IllegalStateException("cannot erase immutable bitmaps");
         }
 
-        ColorSpace cs = Color.colorSpace(c);
-        nativeErase(mNativePtr, cs.getNativeInstance(), c);
+        ColorSpace cs = Color.colorSpace(color);
+        nativeErase(mNativePtr, cs.getNativeInstance(), color);
     }
 
     /**
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 49c3a3b..5623a8a 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -436,9 +436,15 @@
         static void validate(Options opts) {
             if (opts == null) return;
 
-            if (opts.inBitmap != null && opts.inBitmap.getConfig() == Bitmap.Config.HARDWARE) {
-                throw new IllegalArgumentException(
-                        "Bitmaps with Config.HARDWARE are always immutable");
+            if (opts.inBitmap != null) {
+                if (opts.inBitmap.getConfig() == Bitmap.Config.HARDWARE) {
+                    throw new IllegalArgumentException(
+                            "Bitmaps with Config.HARDWARE are always immutable");
+                }
+                if (opts.inBitmap.isRecycled()) {
+                    throw new IllegalArgumentException(
+                            "Cannot reuse a recycled Bitmap");
+                }
             }
 
             if (opts.inMutable && opts.inPreferredConfig == Bitmap.Config.HARDWARE) {
@@ -459,6 +465,17 @@
         }
 
         /**
+         *  Helper for passing inBitmap's native pointer to native.
+         */
+        static long nativeInBitmap(Options opts) {
+            if (opts == null || opts.inBitmap == null) {
+                return 0;
+            }
+
+            return opts.inBitmap.getNativeInstance();
+        }
+
+        /**
          *  Helper for passing SkColorSpace pointer to native.
          *
          *  @throws IllegalArgumentException if the ColorSpace is not Rgb or does
@@ -646,6 +663,7 @@
         Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
         try {
             bm = nativeDecodeByteArray(data, offset, length, opts,
+                    Options.nativeInBitmap(opts),
                     Options.nativeColorSpace(opts));
 
             if (bm == null && opts != null && opts.inBitmap != null) {
@@ -741,7 +759,8 @@
         try {
             if (is instanceof AssetManager.AssetInputStream) {
                 final long asset = ((AssetManager.AssetInputStream) is).getNativeAsset();
-                bm = nativeDecodeAsset(asset, outPadding, opts, Options.nativeColorSpace(opts));
+                bm = nativeDecodeAsset(asset, outPadding, opts, Options.nativeInBitmap(opts),
+                    Options.nativeColorSpace(opts));
             } else {
                 bm = decodeStreamInternal(is, outPadding, opts);
             }
@@ -769,6 +788,7 @@
         if (opts != null) tempStorage = opts.inTempStorage;
         if (tempStorage == null) tempStorage = new byte[DECODE_BUFFER_SIZE];
         return nativeDecodeStream(is, tempStorage, outPadding, opts,
+                Options.nativeInBitmap(opts),
                 Options.nativeColorSpace(opts));
     }
 
@@ -813,6 +833,7 @@
         try {
             if (nativeIsSeekable(fd)) {
                 bm = nativeDecodeFileDescriptor(fd, outPadding, opts,
+                        Options.nativeInBitmap(opts),
                         Options.nativeColorSpace(opts));
             } else {
                 FileInputStream fis = new FileInputStream(fd);
@@ -850,15 +871,15 @@
 
     @UnsupportedAppUsage
     private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
-            Rect padding, Options opts, long colorSpaceHandle);
+            Rect padding, Options opts, long inBitmapHandle, long colorSpaceHandle);
     @UnsupportedAppUsage
     private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
-            Rect padding, Options opts, long colorSpaceHandle);
+            Rect padding, Options opts, long inBitmapHandle, long colorSpaceHandle);
     @UnsupportedAppUsage
     private static native Bitmap nativeDecodeAsset(long nativeAsset, Rect padding, Options opts,
-            long colorSpaceHandle);
+            long inBitmapHandle, long colorSpaceHandle);
     @UnsupportedAppUsage
     private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
-            int length, Options opts, long colorSpaceHandle);
+            int length, Options opts, long inBitmapHandle, long colorSpaceHandle);
     private static native boolean nativeIsSeekable(FileDescriptor fd);
 }
diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java
index 1410423..629d8c1 100644
--- a/graphics/java/android/graphics/BitmapRegionDecoder.java
+++ b/graphics/java/android/graphics/BitmapRegionDecoder.java
@@ -196,6 +196,7 @@
                 throw new IllegalArgumentException("rectangle is outside the image");
             return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top,
                     rect.right - rect.left, rect.bottom - rect.top, options,
+                    BitmapFactory.Options.nativeInBitmap(options),
                     BitmapFactory.Options.nativeColorSpace(options));
         }
     }
@@ -266,7 +267,8 @@
 
     private static native Bitmap nativeDecodeRegion(long lbm,
             int start_x, int start_y, int width, int height,
-            BitmapFactory.Options options, long colorSpaceHandle);
+            BitmapFactory.Options options, long inBitmapHandle,
+            long colorSpaceHandle);
     private static native int nativeGetWidth(long lbm);
     private static native int nativeGetHeight(long lbm);
     private static native void nativeClean(long lbm);
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index eb0f2e1..198d1e7 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -62,9 +62,9 @@
 
     @Override
     long createNativeInstance(long nativeMatrix) {
-        return nativeCreate(nativeMatrix, mBitmap, mTileX, mTileY);
+        return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY);
     }
 
-    private static native long nativeCreate(long nativeMatrix, Bitmap bitmap,
+    private static native long nativeCreate(long nativeMatrix, long bitmapHandle,
             int shaderTileModeX, int shaderTileModeY);
 }
diff --git a/graphics/java/android/graphics/BlendMode.java b/graphics/java/android/graphics/BlendMode.java
index 39392c8..0b26704 100644
--- a/graphics/java/android/graphics/BlendMode.java
+++ b/graphics/java/android/graphics/BlendMode.java
@@ -454,6 +454,64 @@
         return null;
     }
 
+    /**
+     * @hide
+     */
+    public static int toValue(BlendMode mode) {
+        return mode.getXfermode().porterDuffMode;
+    }
+
+    /**
+     * @hide
+     */
+    public static @Nullable PorterDuff.Mode blendModeToPorterDuffMode(@Nullable BlendMode mode) {
+        if (mode != null) {
+            switch (mode) {
+                case CLEAR:
+                    return PorterDuff.Mode.CLEAR;
+                case SRC:
+                    return PorterDuff.Mode.SRC;
+                case DST:
+                    return PorterDuff.Mode.DST;
+                case SRC_OVER:
+                    return PorterDuff.Mode.SRC_OVER;
+                case DST_OVER:
+                    return PorterDuff.Mode.DST_OVER;
+                case SRC_IN:
+                    return PorterDuff.Mode.SRC_IN;
+                case DST_IN:
+                    return PorterDuff.Mode.DST_IN;
+                case SRC_OUT:
+                    return PorterDuff.Mode.SRC_OUT;
+                case DST_OUT:
+                    return PorterDuff.Mode.DST_OUT;
+                case SRC_ATOP:
+                    return PorterDuff.Mode.SRC_ATOP;
+                case DST_ATOP:
+                    return PorterDuff.Mode.DST_ATOP;
+                case XOR:
+                    return PorterDuff.Mode.XOR;
+                case DARKEN:
+                    return PorterDuff.Mode.DARKEN;
+                case LIGHTEN:
+                    return PorterDuff.Mode.LIGHTEN;
+                // b/73224934 PorterDuff Multiply maps to Skia Modulate
+                case MODULATE:
+                    return PorterDuff.Mode.MULTIPLY;
+                case SCREEN:
+                    return PorterDuff.Mode.SCREEN;
+                case PLUS:
+                    return PorterDuff.Mode.ADD;
+                case OVERLAY:
+                    return PorterDuff.Mode.OVERLAY;
+                default:
+                    return null;
+            }
+        } else {
+            return null;
+        }
+    }
+
     @NonNull
     private final Xfermode mXfermode;
 
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 7b3f3da..6f00fc9 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -95,7 +95,7 @@
     public Canvas() {
         if (!isHardwareAccelerated()) {
             // 0 means no native bitmap
-            mNativeCanvasWrapper = nInitRaster(null);
+            mNativeCanvasWrapper = nInitRaster(0);
             mFinalizer = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
                     this, mNativeCanvasWrapper);
         } else {
@@ -117,7 +117,7 @@
             throw new IllegalStateException("Immutable bitmap passed to Canvas constructor");
         }
         throwIfCannotDraw(bitmap);
-        mNativeCanvasWrapper = nInitRaster(bitmap);
+        mNativeCanvasWrapper = nInitRaster(bitmap.getNativeInstance());
         mFinalizer = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
                 this, mNativeCanvasWrapper);
         mBitmap = bitmap;
@@ -185,7 +185,7 @@
         }
 
         if (bitmap == null) {
-            nSetBitmap(mNativeCanvasWrapper, null);
+            nSetBitmap(mNativeCanvasWrapper, 0);
             mDensity = Bitmap.DENSITY_NONE;
         } else {
             if (!bitmap.isMutable()) {
@@ -193,7 +193,7 @@
             }
             throwIfCannotDraw(bitmap);
 
-            nSetBitmap(mNativeCanvasWrapper, bitmap);
+            nSetBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance());
             mDensity = bitmap.mDensity;
         }
 
@@ -1364,14 +1364,16 @@
 
     private static native void nFreeCaches();
     private static native void nFreeTextLayoutCaches();
-    private static native long nInitRaster(Bitmap bitmap);
     private static native long nGetNativeFinalizer();
     private static native void nSetCompatibilityVersion(int apiLevel);
 
     // ---------------- @FastNative -------------------
 
     @FastNative
-    private static native void nSetBitmap(long canvasHandle, Bitmap bitmap);
+    private static native long nInitRaster(long bitmapHandle);
+
+    @FastNative
+    private static native void nSetBitmap(long canvasHandle, long bitmapHandle);
 
     @FastNative
     private static native boolean nGetClipBounds(long nativeCanvas, Rect bounds);
@@ -1683,8 +1685,9 @@
      * Fill the entire canvas' bitmap (restricted to the current clip) with the specified color,
      * using srcover porterduff mode.
      *
-     * @param color the color to draw onto the canvas
-     * @throws IllegalArgumentException if the color space encoded in the long
+     * @param color the {@code ColorLong} to draw onto the canvas. See the {@link Color}
+     *              class for details about {@code ColorLong}s.
+     * @throws IllegalArgumentException if the color space encoded in the {@code ColorLong}
      *                                  is invalid or unknown.
      */
     public void drawColor(@ColorLong long color) {
@@ -1695,7 +1698,7 @@
      * Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and
      * porter-duff xfermode.
      *
-     * @param color the color to draw with
+     * @param color the color to draw onto the canvas
      * @param mode the porter-duff mode to apply to the color
      *
      * @deprecated use {@link #drawColor(int, BlendMode)} instead
@@ -1709,7 +1712,7 @@
      * Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and
      * blendmode.
      *
-     * @param color the color to draw with
+     * @param color the color to draw onto the canvas
      * @param mode the blendmode to apply to the color
      */
     public void drawColor(@ColorInt int color, @NonNull BlendMode mode) {
@@ -1720,9 +1723,10 @@
      * Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and
      * blendmode.
      *
-     * @param color the color to draw with
+     * @param color the {@code ColorLong} to draw onto the canvas. See the {@link Color}
+     *              class for details about {@code ColorLong}s.
      * @param mode the blendmode to apply to the color
-     * @throws IllegalArgumentException if the color space encoded in the long
+     * @throws IllegalArgumentException if the color space encoded in the {@code ColorLong}
      *                                  is invalid or unknown.
      */
     public void drawColor(@ColorLong long color, @NonNull BlendMode mode) {
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 189e174..93ddb10 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -39,7 +39,10 @@
      * @param shaderB  The colors from this shader are seen as the "src" by the mode
      * @param mode     The mode that combines the colors from the two shaders. If mode
      *                 is null, then SRC_OVER is assumed.
+     *
+     * @deprecated use {@link #ComposeShader(Shader, Shader, BlendMode)} instead
     */
+    @Deprecated
     public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode) {
         this(shaderA, shaderB, mode.porterDuffMode);
     }
@@ -52,12 +55,29 @@
      * @param shaderA  The colors from this shader are seen as the "dst" by the mode
      * @param shaderB  The colors from this shader are seen as the "src" by the mode
      * @param mode     The PorterDuff mode that combines the colors from the two shaders.
-    */
+     *
+     * @deprecated use {@link #ComposeShader(Shader, Shader, BlendMode)} instead
+     */
+    @Deprecated
     public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB,
             @NonNull PorterDuff.Mode mode) {
         this(shaderA, shaderB, mode.nativeInt);
     }
 
+    /**
+     * Create a new compose shader, given shaders A, B, and a combining PorterDuff mode.
+     * When the mode is applied, it will be given the result from shader A as its
+     * "dst", and the result from shader B as its "src".
+     *
+     * @param shaderA  The colors from this shader are seen as the "dst" by the mode
+     * @param shaderB  The colors from this shader are seen as the "src" by the mode
+     * @param blendMode The blend mode that combines the colors from the two shaders.
+    */
+    public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB,
+            @NonNull BlendMode blendMode) {
+        this(shaderA, shaderB, blendMode.getXfermode().porterDuffMode);
+    }
+
     private ComposeShader(Shader shaderA, Shader shaderB, int nativeMode) {
         if (shaderA == null || shaderB == null) {
             throw new IllegalArgumentException("Shader parameters must not be null");
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index bc744cc..b6b2d4e 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -682,8 +682,8 @@
 
     /** @hide */
     public boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
-        return nCopyLayerInto(mNativeProxy,
-                layer.getDeferredLayerUpdater(), bitmap);
+        return nCopyLayerInto(mNativeProxy, layer.getDeferredLayerUpdater(),
+            bitmap.getNativeInstance());
     }
 
     /**
@@ -910,10 +910,10 @@
     public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
         if (srcRect == null) {
             // Empty rect means entire surface
-            return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap);
+            return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap.getNativeInstance());
         } else {
             return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
-                    srcRect.right, srcRect.bottom, bitmap);
+                    srcRect.right, srcRect.bottom, bitmap.getNativeInstance());
         }
     }
 
@@ -1115,7 +1115,7 @@
 
     private static native void nBuildLayer(long nativeProxy, long node);
 
-    private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
+    private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle);
 
     private static native void nPushLayerUpdate(long nativeProxy, long layer);
 
@@ -1162,7 +1162,7 @@
     private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
 
     private static native int nCopySurfaceInto(Surface surface,
-            int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
+            int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle);
 
     private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
 
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 800247a..c4c1eac 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -261,7 +261,8 @@
      * that are transparent.
      */
     public final Region getTransparentRegion(Rect bounds) {
-        long r = nativeGetTransparentRegion(mBitmap, mNativeChunk, bounds);
+        long r = nativeGetTransparentRegion(mBitmap.getNativeInstance(),
+                mNativeChunk, bounds);
         return r != 0 ? new Region(r) : null;
     }
 
@@ -282,5 +283,6 @@
      */
     private static native long validateNinePatchChunk(byte[] chunk);
     private static native void nativeFinalize(long chunk);
-    private static native long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location);
+    private static native long nativeGetTransparentRegion(long bitmapHandle, long chunk,
+        Rect location);
 }
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index c485461..db5f065 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1029,9 +1029,8 @@
      * premultiplied, meaning that alpha can be any value, regardless of the
      * values of r,g,b. See the {@link Color} class for more details.
      *
-     * @see Color for APIs that help manipulate a color long.
-     *
-     * @return the paint's color (and alpha).
+     * @return the paint's color, alpha, and {@code ColorSpace} encoded as a
+     *      {@code ColorLong}
      */
     @ColorLong
     public long getColorLong() {
@@ -1052,7 +1051,7 @@
     }
 
     /**
-     * Set the paint's color with a {@link ColorLong}. Note that the color is
+     * Set the paint's color with a {@code ColorLong}. Note that the color is
      * a long with an encoded {@link ColorSpace} as well as alpha and r,g,b.
      * These values are not premultiplied, meaning that alpha can be any value,
      * regardless of the values of r,g,b. See the {@link Color} class for more
@@ -1060,8 +1059,8 @@
      *
      * @param color The new color (including alpha and {@link ColorSpace})
      *      to set in the paint.
-     * @throws IllegalArgumentException if the color space encoded in the long
-     *      is invalid or unknown.
+     * @throws IllegalArgumentException if the color space encoded in the
+     *      {@code ColorLong} is invalid or unknown.
      */
     public void setColor(@ColorLong long color) {
         ColorSpace cs = Color.colorSpace(color);
@@ -1491,8 +1490,8 @@
      * The alpha of the shadow will be the paint's alpha if the shadow color is
      * opaque, or the alpha from the shadow color if not.
      *
-     * @throws IllegalArgumentException if the color space encoded in the long
-     *      is invalid or unknown.
+     * @throws IllegalArgumentException if the color space encoded in the
+     *      {@code ColorLong} is invalid or unknown.
      */
     public void setShadowLayer(float radius, float dx, float dy, @ColorLong long shadowColor) {
         ColorSpace cs = Color.colorSpace(shadowColor);
@@ -1559,8 +1558,11 @@
 
     /**
      * Returns the color of the shadow layer.
+     *
+     * @return the shadow layer's color encoded as a {@link ColorLong}.
      * @see #setShadowLayer(float,float,float,int)
      * @see #setShadowLayer(float,float,float,long)
+     * @see Color
      */
     public @ColorLong long getShadowLayerColorLong() {
         return mShadowLayerColor;
diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java
index fba5043..459291b 100644
--- a/graphics/java/android/graphics/PorterDuff.java
+++ b/graphics/java/android/graphics/PorterDuff.java
@@ -23,7 +23,10 @@
  * that can be passed to {@link PorterDuffXfermode}, a specialized implementation
  * of {@link Paint}'s {@link Paint#setXfermode(Xfermode) transfer mode}.
  * All the available modes can be found in the {@link Mode} enum.</p>
+ *
+ * @deprecated Use {@link BlendMode} with {@link Paint#setBlendMode(BlendMode)} instead
  */
+@Deprecated
 public class PorterDuff {
     /**
      * {@usesMathJax}
diff --git a/graphics/java/android/graphics/PorterDuffXfermode.java b/graphics/java/android/graphics/PorterDuffXfermode.java
index 84d953d..5b933c4 100644
--- a/graphics/java/android/graphics/PorterDuffXfermode.java
+++ b/graphics/java/android/graphics/PorterDuffXfermode.java
@@ -21,6 +21,11 @@
  * {@link Paint#setXfermode(Xfermode) transfer mode}. Refer to the
  * documentation of the {@link PorterDuff.Mode} enum for more
  * information on the available alpha compositing and blending modes.</p>
+ *
+ *  @deprecated Consider using {@link BlendMode} instead as it supports a wider
+ * set of blend modes than those defined in {@link PorterDuff.Mode}
+ *
+ * @see Paint#setBlendMode(BlendMode)
  */
 public class PorterDuffXfermode extends Xfermode {
     /**
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 9b4f2c1..ae7fe6c 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -284,9 +284,10 @@
 
     private static final class CompositePositionUpdateListener implements PositionUpdateListener {
         private final PositionUpdateListener[] mListeners;
+        private static final PositionUpdateListener[] sEmpty = new PositionUpdateListener[0];
 
         CompositePositionUpdateListener(PositionUpdateListener... listeners) {
-            mListeners = listeners;
+            mListeners = listeners != null ? listeners : sEmpty;
         }
 
         public CompositePositionUpdateListener with(PositionUpdateListener listener) {
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index cb12a7c..7def322 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -27,6 +27,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
+import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
@@ -35,7 +36,6 @@
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.Shader;
@@ -701,13 +701,13 @@
     }
 
     @Override
-    public void setTintMode(Mode tintMode) {
+    public void setTintMode(@NonNull BlendMode blendMode) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.N_CHILDREN;
         for (int i = 0; i < N; i++) {
             final Drawable dr = array[i].mDrawable;
             if (dr != null) {
-                dr.setTintMode(tintMode);
+                dr.setTintMode(blendMode);
             }
         }
     }
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index d9dab98..f45bf9b 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -33,12 +33,12 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Insets;
 import android.graphics.Outline;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
 import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 import android.graphics.RenderNode;
@@ -477,8 +477,8 @@
     }
 
     @Override
-    public void setTintMode(PorterDuff.Mode tintMode) {
-        mAnimatedVectorState.mVectorDrawable.setTintMode(tintMode);
+    public void setTintMode(@NonNull BlendMode blendMode) {
+        mAnimatedVectorState.mVectorDrawable.setTintMode(blendMode);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 9761901..6b30158 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -25,6 +25,8 @@
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.ImageDecoder;
@@ -33,9 +35,7 @@
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
 import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.graphics.Xfermode;
@@ -90,7 +90,7 @@
 
     @UnsupportedAppUsage
     private BitmapState mBitmapState;
-    private PorterDuffColorFilter mTintFilter;
+    private BlendModeColorFilter mBlendModeFilter;
 
     @UnsupportedAppUsage
     private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -527,8 +527,8 @@
         }
 
         final boolean clearColorFilter;
-        if (mTintFilter != null && paint.getColorFilter() == null) {
-            paint.setColorFilter(mTintFilter);
+        if (mBlendModeFilter != null && paint.getColorFilter() == null) {
+            paint.setColorFilter(mBlendModeFilter);
             clearColorFilter = true;
         } else {
             clearColorFilter = false;
@@ -678,17 +678,19 @@
         final BitmapState state = mBitmapState;
         if (state.mTint != tint) {
             state.mTint = tint;
-            mTintFilter = updateTintFilter(mTintFilter, tint, mBitmapState.mTintMode);
+            mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, tint,
+                      mBitmapState.mBlendMode);
             invalidateSelf();
         }
     }
 
     @Override
-    public void setTintMode(PorterDuff.Mode tintMode) {
+    public void setTintMode(@NonNull BlendMode blendMode) {
         final BitmapState state = mBitmapState;
-        if (state.mTintMode != tintMode) {
-            state.mTintMode = tintMode;
-            mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, tintMode);
+        if (state.mBlendMode != blendMode) {
+            state.mBlendMode = blendMode;
+            mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mBitmapState.mTint,
+                    blendMode);
             invalidateSelf();
         }
     }
@@ -706,7 +708,7 @@
      */
     @UnsupportedAppUsage
     public Mode getTintMode() {
-        return mBitmapState.mTintMode;
+        return BlendMode.blendModeToPorterDuffMode(mBitmapState.mBlendMode);
     }
 
     /**
@@ -744,8 +746,9 @@
     @Override
     protected boolean onStateChange(int[] stateSet) {
         final BitmapState state = mBitmapState;
-        if (state.mTint != null && state.mTintMode != null) {
-            mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+        if (state.mTint != null && state.mBlendMode != null) {
+            mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint,
+                    state.mBlendMode);
             return true;
         }
         return false;
@@ -864,7 +867,7 @@
 
         final int tintMode = a.getInt(R.styleable.BitmapDrawable_tintMode, -1);
         if (tintMode != -1) {
-            state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+            state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
         }
 
         final ColorStateList tint = a.getColorStateList(R.styleable.BitmapDrawable_tint);
@@ -979,7 +982,8 @@
         int[] mThemeAttrs = null;
         Bitmap mBitmap = null;
         ColorStateList mTint = null;
-        Mode mTintMode = DEFAULT_TINT_MODE;
+        BlendMode mBlendMode = DEFAULT_BLEND_MODE;
+
         int mGravity = Gravity.FILL;
         float mBaseAlpha = 1.0f;
         Shader.TileMode mTileModeX = null;
@@ -1005,7 +1009,7 @@
         BitmapState(BitmapState bitmapState) {
             mBitmap = bitmapState.mBitmap;
             mTint = bitmapState.mTint;
-            mTintMode = bitmapState.mTintMode;
+            mBlendMode = bitmapState.mBlendMode;
             mThemeAttrs = bitmapState.mThemeAttrs;
             mChangingConfigurations = bitmapState.mChangingConfigurations;
             mGravity = bitmapState.mGravity;
@@ -1065,7 +1069,8 @@
      */
     private void updateLocalState(Resources res) {
         mTargetDensity = resolveDensity(res, mBitmapState.mTargetDensity);
-        mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, mBitmapState.mTintMode);
+        mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mBitmapState.mTint,
+                mBitmapState.mBlendMode);
         computeBitmapSize();
     }
 }
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 3c44916..efa806a 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -26,13 +26,13 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
 import android.graphics.Xfermode;
 import android.util.AttributeSet;
 import android.view.ViewDebug;
@@ -58,7 +58,7 @@
 
     @ViewDebug.ExportedProperty(deepExport = true, prefix = "state_")
     private ColorState mColorState;
-    private PorterDuffColorFilter mTintFilter;
+    private BlendModeColorFilter mBlendModeColorFilter;
 
     private boolean mMutated;
 
@@ -111,9 +111,10 @@
     @Override
     public void draw(Canvas canvas) {
         final ColorFilter colorFilter = mPaint.getColorFilter();
-        if ((mColorState.mUseColor >>> 24) != 0 || colorFilter != null || mTintFilter != null) {
+        if ((mColorState.mUseColor >>> 24) != 0 || colorFilter != null
+                || mBlendModeColorFilter != null) {
             if (colorFilter == null) {
-                mPaint.setColorFilter(mTintFilter);
+                mPaint.setColorFilter(mBlendModeColorFilter);
             }
 
             mPaint.setColor(mColorState.mUseColor);
@@ -208,22 +209,25 @@
     @Override
     public void setTintList(ColorStateList tint) {
         mColorState.mTint = tint;
-        mTintFilter = updateTintFilter(mTintFilter, tint, mColorState.mTintMode);
+        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, tint,
+                mColorState.mBlendMode);
         invalidateSelf();
     }
 
     @Override
-    public void setTintMode(Mode tintMode) {
-        mColorState.mTintMode = tintMode;
-        mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, tintMode);
+    public void setTintMode(@NonNull BlendMode blendMode) {
+        mColorState.mBlendMode = blendMode;
+        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mColorState.mTint,
+                blendMode);
         invalidateSelf();
     }
 
     @Override
     protected boolean onStateChange(int[] stateSet) {
         final ColorState state = mColorState;
-        if (state.mTint != null && state.mTintMode != null) {
-            mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+        if (state.mTint != null && state.mBlendMode != null) {
+            mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
+                    state.mBlendMode);
             return true;
         }
         return false;
@@ -261,7 +265,7 @@
 
     @Override
     public int getOpacity() {
-        if (mTintFilter != null || mPaint.getColorFilter() != null) {
+        if (mBlendModeColorFilter != null || mPaint.getColorFilter() != null) {
             return PixelFormat.TRANSLUCENT;
         }
 
@@ -348,7 +352,7 @@
         int mUseColor;  // basecolor modulated by setAlpha()
         @Config int mChangingConfigurations;
         ColorStateList mTint = null;
-        Mode mTintMode = DEFAULT_TINT_MODE;
+        BlendMode mBlendMode = DEFAULT_BLEND_MODE;
 
         ColorState() {
             // Empty constructor.
@@ -360,7 +364,7 @@
             mUseColor = state.mUseColor;
             mChangingConfigurations = state.mChangingConfigurations;
             mTint = state.mTint;
-            mTintMode = state.mTintMode;
+            mBlendMode = state.mBlendMode;
         }
 
         @Override
@@ -398,6 +402,7 @@
      * after inflating or applying a theme.
      */
     private void updateLocalState(Resources r) {
-        mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, mColorState.mTintMode);
+        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mColorState.mTint,
+                mColorState.mBlendMode);
     }
 }
diff --git a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
index ee4d1e7..b94b114 100644
--- a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
@@ -21,10 +21,10 @@
 import android.content.pm.ActivityInfo;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
+import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
 import android.util.MathUtils;
 
 /**
@@ -114,9 +114,9 @@
     }
 
     @Override
-    public void setTintMode(@NonNull PorterDuff.Mode tintMode) {
-        mState.mTintMode = tintMode;
-        mColorDrawable.setTintMode(tintMode);
+    public void setTintMode(@NonNull BlendMode blendMode) {
+        mState.mBlendMode = blendMode;
+        mColorDrawable.setTintMode(blendMode);
         onStateChange(getState());
     }
 
@@ -236,7 +236,7 @@
         ColorStateList mColor = null;
         ColorStateList mTint = null;
         int mAlpha = -1;
-        PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+        BlendMode mBlendMode = DEFAULT_BLEND_MODE;
         @ActivityInfo.Config int mChangingConfigurations = 0;
 
         ColorStateListDrawableState() {
@@ -246,7 +246,7 @@
             mColor = state.mColor;
             mTint = state.mTint;
             mAlpha = state.mAlpha;
-            mTintMode = state.mTintMode;
+            mBlendMode = state.mBlendMode;
             mChangingConfigurations = state.mChangingConfigurations;
         }
 
@@ -292,8 +292,8 @@
             mColorDrawable.setTintList(mState.mTint);
         }
 
-        if (mState.mTintMode != DEFAULT_TINT_MODE) {
-            mColorDrawable.setTintMode(mState.mTintMode);
+        if (mState.mBlendMode != DEFAULT_BLEND_MODE) {
+            mColorDrawable.setTintMode(mState.mBlendMode);
         }
     }
 }
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 49d3530..adc04fb 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -30,6 +30,8 @@
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
@@ -182,6 +184,7 @@
     private static final Rect ZERO_BOUNDS_RECT = new Rect();
 
     static final PorterDuff.Mode DEFAULT_TINT_MODE = PorterDuff.Mode.SRC_IN;
+    static final BlendMode DEFAULT_BLEND_MODE = BlendMode.SRC_IN;
 
     private int[] mStateSet = StateSet.WILD_CARD;
     private int mLevel = 0;
@@ -210,6 +213,24 @@
     protected int mSrcDensityOverride = 0;
 
     /**
+     * Flag used to break the recursive loop between setTintMode(PorterDuff.Mode) and
+     * setTintMode(BlendMode) as each default implementation invokes the other in order to
+     * support new use cases that utilize the new blending modes as well as support the legacy
+     * use cases. This flag tracks that {@link #setTintMode(BlendMode)} is only invoked once
+     * per invocation.
+     */
+    private boolean mSetBlendModeInvoked = false;
+
+    /**
+     * Flag used to break the recursive loop between setTintMode(PorterDuff.Mode) and
+     * setTintMode(BlendMode) as each default implementation invokes the other in order to
+     * support new use cases that utilize the new blending modes as well as support the legacy
+     * use cases. This flag tracks that {@link #setTintMode(Mode)} is only invoked once
+     * per invocation;
+     */
+    private boolean mSetTintModeInvoked = false;
+
+    /**
      * Draw in its bounds (set via setBounds) respecting optional effects such
      * as alpha (set via setAlpha) and color filter (set via setColorFilter).
      *
@@ -630,6 +651,7 @@
      * @param tintColor Color to use for tinting this drawable
      * @see #setTintList(ColorStateList)
      * @see #setTintMode(PorterDuff.Mode)
+     * @see #setTintMode(BlendMode)
      */
     public void setTint(@ColorInt int tintColor) {
         setTintList(ColorStateList.valueOf(tintColor));
@@ -651,6 +673,7 @@
      *            {@code null} to clear the tint
      * @see #setTint(int)
      * @see #setTintMode(PorterDuff.Mode)
+     * @see #setTintMode(BlendMode)
      */
     public void setTintList(@Nullable ColorStateList tint) {}
 
@@ -665,11 +688,47 @@
      * {@link #setColorFilter(int, PorterDuff.Mode)} overrides tint.
      * </p>
      *
-     * @param tintMode A Porter-Duff blending mode
+     * @param tintMode A Porter-Duff blending mode to apply to the drawable, a value of null sets
+     *                 the default Porter-Diff blending mode value
+     *                 of {@link PorterDuff.Mode#SRC_IN}
+     * @see #setTint(int)
+     * @see #setTintList(ColorStateList)
+     *
+     * @deprecated use {@link #setTintMode(BlendMode)} instead
+     */
+    @Deprecated
+    public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
+        if (!mSetTintModeInvoked) {
+            mSetTintModeInvoked = true;
+            BlendMode mode = tintMode != null ? BlendMode.fromValue(tintMode.nativeInt) : null;
+            setTintMode(mode != null ? mode : Drawable.DEFAULT_BLEND_MODE);
+            mSetTintModeInvoked = false;
+        }
+    }
+
+    /**
+     * Specifies a tint blending mode for this drawable.
+     * <p>
+     * Defines how this drawable's tint color should be blended into the drawable
+     * before it is drawn to screen. Default tint mode is {@link BlendMode#SRC_IN}.
+     * </p>
+     * <p class="note"><strong>Note:</strong> Setting a color filter via
+     * {@link #setColorFilter(ColorFilter)}
+     * </p>
+     *
+     * @param blendMode BlendMode to apply to the drawable, a value of null sets the default
+     *                  blend mode value of {@link BlendMode#SRC_IN}
      * @see #setTint(int)
      * @see #setTintList(ColorStateList)
      */
-    public void setTintMode(@NonNull PorterDuff.Mode tintMode) {}
+    public void setTintMode(@Nullable BlendMode blendMode) {
+        if (!mSetBlendModeInvoked) {
+            mSetBlendModeInvoked = true;
+            PorterDuff.Mode mode = BlendMode.blendModeToPorterDuffMode(blendMode);
+            setTintMode(mode != null ? mode : Drawable.DEFAULT_TINT_MODE);
+            mSetBlendModeInvoked = false;
+        }
+    }
 
     /**
      * Returns the current color filter, or {@code null} if none set.
@@ -1540,6 +1599,20 @@
         return tintFilter;
     }
 
+    @Nullable BlendModeColorFilter updateBlendModeFilter(@Nullable BlendModeColorFilter blendFilter,
+            @Nullable ColorStateList tint, @Nullable BlendMode blendMode) {
+        if (tint == null || blendMode == null) {
+            return null;
+        }
+
+        final int color = tint.getColorForState(getState(), Color.TRANSPARENT);
+        if (blendFilter == null || blendFilter.getColor() != color
+                || blendFilter.getMode() != blendMode) {
+            return new BlendModeColorFilter(color, blendMode);
+        }
+        return blendFilter;
+    }
+
     /**
      * Obtains styled attributes from the theme, if available, or unstyled
      * resources if the theme is null.
@@ -1642,5 +1715,26 @@
             default: return defaultMode;
         }
     }
+
+    /**
+     * Parses a {@link android.graphics.BlendMode} from a tintMode
+     * attribute's enum value.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static BlendMode parseBlendMode(int value, BlendMode defaultMode) {
+        switch (value) {
+            case 3: return BlendMode.SRC_OVER;
+            case 5: return BlendMode.SRC_IN;
+            case 9: return BlendMode.SRC_ATOP;
+            // b/73224934 PorterDuff Multiply maps to Skia Modulate so actually
+            // return BlendMode.MODULATE here
+            case 14: return BlendMode.MODULATE;
+            case 15: return BlendMode.SCREEN;
+            case 16: return BlendMode.PLUS;
+            default: return defaultMode;
+        }
+    }
 }
 
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 77e77c4..3e0881a 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -22,12 +22,12 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
+import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Insets;
 import android.graphics.Outline;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
 import android.graphics.Rect;
 import android.os.Build;
 import android.os.SystemClock;
@@ -196,14 +196,14 @@
     }
 
     @Override
-    public void setTintMode(Mode tintMode) {
+    public void setTintMode(@NonNull BlendMode blendMode) {
         mDrawableContainerState.mHasTintMode = true;
 
-        if (mDrawableContainerState.mTintMode != tintMode) {
-            mDrawableContainerState.mTintMode = tintMode;
+        if (mDrawableContainerState.mBlendMode != blendMode) {
+            mDrawableContainerState.mBlendMode = blendMode;
 
             if (mCurrDrawable != null) {
-                mCurrDrawable.setTintMode(tintMode);
+                mCurrDrawable.setTintMode(blendMode);
             }
         }
     }
@@ -544,7 +544,7 @@
                     d.setTintList(mDrawableContainerState.mTintList);
                 }
                 if (mDrawableContainerState.mHasTintMode) {
-                    d.setTintMode(mDrawableContainerState.mTintMode);
+                    d.setTintMode(mDrawableContainerState.mBlendMode);
                 }
             }
 
@@ -730,7 +730,7 @@
         boolean mHasColorFilter;
 
         ColorStateList mTintList;
-        Mode mTintMode;
+        BlendMode mBlendMode;
         boolean mHasTintList;
         boolean mHasTintMode;
 
@@ -762,7 +762,7 @@
                 mColorFilter = orig.mColorFilter;
                 mHasColorFilter = orig.mHasColorFilter;
                 mTintList = orig.mTintList;
-                mTintMode = orig.mTintMode;
+                mBlendMode = orig.mBlendMode;
                 mHasTintList = orig.mHasTintList;
                 mHasTintMode = orig.mHasTintMode;
 
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 70c90eb..d81401d 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -24,12 +24,12 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Insets;
 import android.graphics.Outline;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.Xfermode;
 import android.util.AttributeSet;
@@ -324,9 +324,9 @@
     }
 
     @Override
-    public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
+    public void setTintMode(@NonNull BlendMode blendMode) {
         if (mDrawable != null) {
-            mDrawable.setTintMode(tintMode);
+            mDrawable.setTintMode(blendMode);
         }
     }
 
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index e58e802..6948bc4 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -28,6 +28,8 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
@@ -38,8 +40,6 @@
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
 import android.graphics.RadialGradient;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -169,7 +169,7 @@
     @UnsupportedAppUsage
     private Paint mStrokePaint;   // optional, set by the caller
     private ColorFilter mColorFilter;   // optional, set by the caller
-    private PorterDuffColorFilter mTintFilter;
+    private BlendModeColorFilter mBlendModeColorFilter;
     private int mAlpha = 0xFF;  // modified by the caller
 
     private final Path mPath = new Path();
@@ -731,7 +731,7 @@
                 mStrokePaint.getStrokeWidth() > 0;
         final boolean haveFill = currFillAlpha > 0;
         final GradientState st = mGradientState;
-        final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter;
+        final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mBlendModeColorFilter;
 
         /*  we need a layer iff we're drawing both a fill and stroke, and the
             stroke is non-opaque, and our shapetype actually supports
@@ -1130,8 +1130,9 @@
             }
         }
 
-        if (s.mTint != null && s.mTintMode != null) {
-            mTintFilter = updateTintFilter(mTintFilter, s.mTint, s.mTintMode);
+        if (s.mTint != null && s.mBlendMode != null) {
+            mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, s.mTint,
+                    s.mBlendMode);
             invalidateSelf = true;
         }
 
@@ -1204,14 +1205,16 @@
     @Override
     public void setTintList(@Nullable ColorStateList tint) {
         mGradientState.mTint = tint;
-        mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode);
+        mBlendModeColorFilter =
+                updateBlendModeFilter(mBlendModeColorFilter, tint, mGradientState.mBlendMode);
         invalidateSelf();
     }
 
     @Override
-    public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
-        mGradientState.mTintMode = tintMode;
-        mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode);
+    public void setTintMode(@NonNull BlendMode blendMode) {
+        mGradientState.mBlendMode = blendMode;
+        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mGradientState.mTint,
+                blendMode);
         invalidateSelf();
     }
 
@@ -1309,6 +1312,10 @@
                     y0 = r.top + (r.bottom - r.top) * st.mCenterY;
 
                     float radius = st.mGradientRadius;
+                    if (Float.compare(radius, 0.0f) == -1 || Float.isNaN(radius)) {
+                        throw new IllegalArgumentException("Gradient radius must be a valid "
+                                + "number greater than or equal to 0");
+                    }
                     if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) {
                         // Fall back to parent width or height if intrinsic
                         // size is not specified.
@@ -1465,7 +1472,7 @@
 
         final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1);
         if (tintMode != -1) {
-            state.mTintMode = Drawable.parseTintMode(tintMode, PorterDuff.Mode.SRC_IN);
+            state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
         }
 
         final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint);
@@ -1756,75 +1763,68 @@
             st.mGradientColors[1] = endColor;
         }
 
-        if (st.mGradient == LINEAR_GRADIENT) {
-            int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);
-            angle %= 360;
+        int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);
+        angle %= 360;
 
-            if (angle % 45 != 0) {
-                throw new XmlPullParserException(a.getPositionDescription()
-                        + "<gradient> tag requires 'angle' attribute to "
-                        + "be a multiple of 45");
-            }
+        if (angle % 45 != 0) {
+            throw new XmlPullParserException(a.getPositionDescription()
+                    + "<gradient> tag requires 'angle' attribute to "
+                    + "be a multiple of 45");
+        }
 
-            st.mAngle = angle;
+        st.mAngle = angle;
 
-            switch (angle) {
-                case 0:
-                    st.mOrientation = Orientation.LEFT_RIGHT;
-                    break;
-                case 45:
-                    st.mOrientation = Orientation.BL_TR;
-                    break;
-                case 90:
-                    st.mOrientation = Orientation.BOTTOM_TOP;
-                    break;
-                case 135:
-                    st.mOrientation = Orientation.BR_TL;
-                    break;
-                case 180:
-                    st.mOrientation = Orientation.RIGHT_LEFT;
-                    break;
-                case 225:
-                    st.mOrientation = Orientation.TR_BL;
-                    break;
-                case 270:
-                    st.mOrientation = Orientation.TOP_BOTTOM;
-                    break;
-                case 315:
-                    st.mOrientation = Orientation.TL_BR;
-                    break;
-            }
-        } else {
-            final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
-            if (tv != null) {
-                final float radius;
-                final @RadiusType int radiusType;
-                if (tv.type == TypedValue.TYPE_FRACTION) {
-                    radius = tv.getFraction(1.0f, 1.0f);
+        switch (angle) {
+            case 0:
+                st.mOrientation = Orientation.LEFT_RIGHT;
+                break;
+            case 45:
+                st.mOrientation = Orientation.BL_TR;
+                break;
+            case 90:
+                st.mOrientation = Orientation.BOTTOM_TOP;
+                break;
+            case 135:
+                st.mOrientation = Orientation.BR_TL;
+                break;
+            case 180:
+                st.mOrientation = Orientation.RIGHT_LEFT;
+                break;
+            case 225:
+                st.mOrientation = Orientation.TR_BL;
+                break;
+            case 270:
+                st.mOrientation = Orientation.TOP_BOTTOM;
+                break;
+            case 315:
+                st.mOrientation = Orientation.TL_BR;
+                break;
+        }
 
-                    final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT)
-                            & TypedValue.COMPLEX_UNIT_MASK;
-                    if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) {
-                        radiusType = RADIUS_TYPE_FRACTION_PARENT;
-                    } else {
-                        radiusType = RADIUS_TYPE_FRACTION;
-                    }
-                } else if (tv.type == TypedValue.TYPE_DIMENSION) {
-                    radius = tv.getDimension(r.getDisplayMetrics());
-                    radiusType = RADIUS_TYPE_PIXELS;
+        final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
+        if (tv != null) {
+            final float radius;
+            final @RadiusType int radiusType;
+            if (tv.type == TypedValue.TYPE_FRACTION) {
+                radius = tv.getFraction(1.0f, 1.0f);
+
+                final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT)
+                        & TypedValue.COMPLEX_UNIT_MASK;
+                if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) {
+                    radiusType = RADIUS_TYPE_FRACTION_PARENT;
                 } else {
-                    radius = tv.getFloat();
-                    radiusType = RADIUS_TYPE_PIXELS;
+                    radiusType = RADIUS_TYPE_FRACTION;
                 }
-
-                st.mGradientRadius = radius;
-                st.mGradientRadiusType = radiusType;
-            } else if (st.mGradient == RADIAL_GRADIENT) {
-                throw new XmlPullParserException(
-                        a.getPositionDescription()
-                        + "<gradient> tag requires 'gradientRadius' "
-                        + "attribute with radial type");
+            } else if (tv.type == TypedValue.TYPE_DIMENSION) {
+                radius = tv.getDimension(r.getDisplayMetrics());
+                radiusType = RADIUS_TYPE_PIXELS;
+            } else {
+                radius = tv.getFloat();
+                radiusType = RADIUS_TYPE_PIXELS;
             }
+
+            st.mGradientRadius = radius;
+            st.mGradientRadiusType = radiusType;
         }
     }
 
@@ -2010,7 +2010,7 @@
         boolean mOpaqueOverShape;
 
         ColorStateList mTint = null;
-        PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+        BlendMode mBlendMode = DEFAULT_BLEND_MODE;
 
         int mDensity = DisplayMetrics.DENSITY_DEFAULT;
 
@@ -2068,7 +2068,7 @@
             mOpaqueOverBounds = orig.mOpaqueOverBounds;
             mOpaqueOverShape = orig.mOpaqueOverShape;
             mTint = orig.mTint;
-            mTintMode = orig.mTintMode;
+            mBlendMode = orig.mBlendMode;
             mThemeAttrs = orig.mThemeAttrs;
             mAttrSize = orig.mAttrSize;
             mAttrGradient = orig.mAttrGradient;
@@ -2355,7 +2355,8 @@
             }
         }
 
-        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
+                state.mBlendMode);
         mGradientIsDirty = true;
 
         state.computeOpacity();
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 71dd7a2..5fd18a1 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -30,6 +30,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.BlendMode;
 import android.graphics.PorterDuff;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -105,8 +106,8 @@
     private final int mType;
 
     private ColorStateList mTintList;
-    static final PorterDuff.Mode DEFAULT_TINT_MODE = Drawable.DEFAULT_TINT_MODE; // SRC_IN
-    private PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+    static final BlendMode DEFAULT_BLEND_MODE = Drawable.DEFAULT_BLEND_MODE; // SRC_IN
+    private BlendMode mBlendMode = Drawable.DEFAULT_BLEND_MODE;
 
     // To avoid adding unnecessary overhead, we have a few basic objects that get repurposed
     // based on the value of mType.
@@ -320,10 +321,10 @@
      */
     public Drawable loadDrawable(Context context) {
         final Drawable result = loadDrawableInner(context);
-        if (result != null && (mTintList != null || mTintMode != DEFAULT_TINT_MODE)) {
+        if (result != null && (mTintList != null || mBlendMode != DEFAULT_BLEND_MODE)) {
             result.mutate();
             result.setTintList(mTintList);
-            result.setTintMode(mTintMode);
+            result.setTintMode(mBlendMode);
         }
         return result;
     }
@@ -695,16 +696,30 @@
      *
      * @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null
      * @return this same object, for use in chained construction
+     *
+     * @deprecated use {@link #setTintMode(BlendMode)} instead
      */
-    public Icon setTintMode(PorterDuff.Mode mode) {
-        mTintMode = mode;
+    @Deprecated
+    public @NonNull Icon setTintMode(@NonNull PorterDuff.Mode mode) {
+        mBlendMode = BlendMode.fromValue(mode.nativeInt);
+        return this;
+    }
+
+    /**
+     * Store a blending mode to use whenever this Icon is drawn.
+     *
+     * @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null
+     * @return this same object, for use in chained construction
+     */
+    public @NonNull Icon setTintMode(@NonNull BlendMode mode) {
+        mBlendMode = mode;
         return this;
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public boolean hasTint() {
-        return (mTintList != null) || (mTintMode != DEFAULT_TINT_MODE);
+        return (mTintList != null) || (mBlendMode != DEFAULT_BLEND_MODE);
     }
 
     /**
@@ -757,7 +772,7 @@
                 sep = "|";
             }
         }
-        if (mTintMode != DEFAULT_TINT_MODE) sb.append(" mode=").append(mTintMode);
+        if (mBlendMode != DEFAULT_BLEND_MODE) sb.append(" mode=").append(mBlendMode);
         sb.append(")");
         return sb.toString();
     }
@@ -807,7 +822,7 @@
         if (in.readInt() == 1) {
             mTintList = ColorStateList.CREATOR.createFromParcel(in);
         }
-        mTintMode = PorterDuff.intToMode(in.readInt());
+        mBlendMode = BlendMode.fromValue(in.readInt());
     }
 
     @Override
@@ -837,7 +852,7 @@
             dest.writeInt(1);
             mTintList.writeToParcel(dest, flags);
         }
-        dest.writeInt(PorterDuff.modeToInt(mTintMode));
+        dest.writeInt(BlendMode.toValue(mBlendMode));
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<Icon> CREATOR
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index b4392c8..e2c8492 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -24,11 +24,11 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Outline;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
@@ -1397,13 +1397,13 @@
     }
 
     @Override
-    public void setTintMode(Mode tintMode) {
+    public void setTintMode(@NonNull BlendMode blendMode) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNumChildren;
         for (int i = 0; i < N; i++) {
             final Drawable dr = array[i].mDrawable;
             if (dr != null) {
-                dr.setTintMode(tintMode);
+                dr.setTintMode(blendMode);
             }
         }
     }
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index b534771..4972e6a 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -25,6 +25,8 @@
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.ImageDecoder;
@@ -33,9 +35,6 @@
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.util.AttributeSet;
@@ -73,7 +72,7 @@
 
     @UnsupportedAppUsage
     private NinePatchState mNinePatchState;
-    private PorterDuffColorFilter mTintFilter;
+    private BlendModeColorFilter mBlendModeFilter;
     private Rect mPadding;
     private Insets mOpticalInsets = Insets.NONE;
     private Rect mOutlineInsets;
@@ -198,8 +197,8 @@
         int restoreToCount = -1;
 
         final boolean clearColorFilter;
-        if (mTintFilter != null && getPaint().getColorFilter() == null) {
-            mPaint.setColorFilter(mTintFilter);
+        if (mBlendModeFilter != null && getPaint().getColorFilter() == null) {
+            mPaint.setColorFilter(mBlendModeFilter);
             clearColorFilter = true;
         } else {
             clearColorFilter = false;
@@ -344,14 +343,16 @@
     @Override
     public void setTintList(@Nullable ColorStateList tint) {
         mNinePatchState.mTint = tint;
-        mTintFilter = updateTintFilter(mTintFilter, tint, mNinePatchState.mTintMode);
+        mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, tint,
+                mNinePatchState.mBlendMode);
         invalidateSelf();
     }
 
     @Override
-    public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
-        mNinePatchState.mTintMode = tintMode;
-        mTintFilter = updateTintFilter(mTintFilter, mNinePatchState.mTint, tintMode);
+    public void setTintMode(@Nullable BlendMode blendMode) {
+        mNinePatchState.mBlendMode = blendMode;
+        mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mNinePatchState.mTint,
+                blendMode);
         invalidateSelf();
     }
 
@@ -467,7 +468,7 @@
 
         final int tintMode = a.getInt(R.styleable.NinePatchDrawable_tintMode, -1);
         if (tintMode != -1) {
-            state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+            state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
         }
 
         final ColorStateList tint = a.getColorStateList(R.styleable.NinePatchDrawable_tint);
@@ -566,8 +567,9 @@
     @Override
     protected boolean onStateChange(int[] stateSet) {
         final NinePatchState state = mNinePatchState;
-        if (state.mTint != null && state.mTintMode != null) {
-            mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+        if (state.mTint != null && state.mBlendMode != null) {
+            mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint,
+                    state.mBlendMode);
             return true;
         }
 
@@ -593,7 +595,7 @@
         @UnsupportedAppUsage
         NinePatch mNinePatch = null;
         ColorStateList mTint = null;
-        Mode mTintMode = DEFAULT_TINT_MODE;
+        BlendMode mBlendMode = DEFAULT_BLEND_MODE;
         Rect mPadding = null;
         Insets mOpticalInsets = Insets.NONE;
         float mBaseAlpha = 1.0f;
@@ -628,7 +630,7 @@
             mChangingConfigurations = orig.mChangingConfigurations;
             mNinePatch = orig.mNinePatch;
             mTint = orig.mTint;
-            mTintMode = orig.mTintMode;
+            mBlendMode = orig.mBlendMode;
             mPadding = orig.mPadding;
             mOpticalInsets = orig.mOpticalInsets;
             mBaseAlpha = orig.mBaseAlpha;
@@ -751,7 +753,7 @@
         } else {
             mTargetDensity = Drawable.resolveDensity(res, mTargetDensity);
         }
-        mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+        mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint, state.mBlendMode);
         computeBitmapSize();
     }
 }
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 7bfb4c3..b5fe7f9 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -24,14 +24,13 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.graphics.Xfermode;
@@ -75,7 +74,7 @@
  */
 public class ShapeDrawable extends Drawable {
     private @NonNull ShapeState mShapeState;
-    private PorterDuffColorFilter mTintFilter;
+    private BlendModeColorFilter mBlendModeColorFilter;
     private boolean mMutated;
 
     /**
@@ -238,8 +237,8 @@
         // only draw shape if it may affect output
         if (paint.getAlpha() != 0 || paint.getXfermode() != null || paint.hasShadowLayer()) {
             final boolean clearColorFilter;
-            if (mTintFilter != null && paint.getColorFilter() == null) {
-                paint.setColorFilter(mTintFilter);
+            if (mBlendModeColorFilter != null && paint.getColorFilter() == null) {
+                paint.setColorFilter(mBlendModeColorFilter);
                 clearColorFilter = true;
             } else {
                 clearColorFilter = false;
@@ -292,14 +291,16 @@
     @Override
     public void setTintList(ColorStateList tint) {
         mShapeState.mTint = tint;
-        mTintFilter = updateTintFilter(mTintFilter, tint, mShapeState.mTintMode);
+        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, tint,
+                mShapeState.mBlendMode);
         invalidateSelf();
     }
 
     @Override
-    public void setTintMode(PorterDuff.Mode tintMode) {
-        mShapeState.mTintMode = tintMode;
-        mTintFilter = updateTintFilter(mTintFilter, mShapeState.mTint, tintMode);
+    public void setTintMode(@NonNull BlendMode blendMode) {
+        mShapeState.mBlendMode = blendMode;
+        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mShapeState.mTint,
+                blendMode);
         invalidateSelf();
     }
 
@@ -352,8 +353,9 @@
     @Override
     protected boolean onStateChange(int[] stateSet) {
         final ShapeState state = mShapeState;
-        if (state.mTint != null && state.mTintMode != null) {
-            mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+        if (state.mTint != null && state.mBlendMode != null) {
+            mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
+                    state.mBlendMode);
             return true;
         }
         return false;
@@ -475,7 +477,7 @@
 
         final int tintMode = a.getInt(R.styleable.ShapeDrawable_tintMode, -1);
         if (tintMode != -1) {
-            state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+            state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
         }
 
         final ColorStateList tint = a.getColorStateList(R.styleable.ShapeDrawable_tint);
@@ -540,7 +542,7 @@
         int[] mThemeAttrs;
         Shape mShape;
         ColorStateList mTint;
-        Mode mTintMode = DEFAULT_TINT_MODE;
+        BlendMode mBlendMode = DEFAULT_BLEND_MODE;
         Rect mPadding;
         int mIntrinsicWidth;
         int mIntrinsicHeight;
@@ -573,7 +575,7 @@
                 }
             }
             mTint = orig.mTint;
-            mTintMode = orig.mTintMode;
+            mBlendMode = orig.mBlendMode;
             if (orig.mPadding != null) {
                 mPadding = new Rect(orig.mPadding);
             }
@@ -625,7 +627,8 @@
      * after inflating or applying a theme.
      */
     private void updateLocalState() {
-        mTintFilter = updateTintFilter(mTintFilter, mShapeState.mTint, mShapeState.mTintMode);
+        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mShapeState.mTint,
+                mShapeState.mBlendMode);
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 7325b85..43772ec 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -24,11 +24,13 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Insets;
 import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.graphics.Shader;
@@ -324,6 +326,8 @@
 
     @UnsupportedAppUsage
     private PorterDuffColorFilter mTintFilter;
+
+    private BlendModeColorFilter mBlendModeColorFilter;
     private ColorFilter mColorFilter;
 
     private boolean mMutated;
@@ -371,7 +375,7 @@
             mDpiScaledDirty = true;
         }
 
-        mTintFilter = updateTintFilter(mTintFilter, mVectorState.mTint, mVectorState.mTintMode);
+        updateColorFilters(mVectorState.mBlendMode, mVectorState.mTint);
     }
 
     @Override
@@ -413,7 +417,8 @@
         }
 
         // Color filters always override tint filters.
-        final ColorFilter colorFilter = (mColorFilter == null ? mTintFilter : mColorFilter);
+        final ColorFilter colorFilter = (mColorFilter == null ? mBlendModeColorFilter :
+                mColorFilter);
         final long colorFilterNativeInstance = colorFilter == null ? 0 :
                 colorFilter.getNativeInstance();
         boolean canReuseCache = mVectorState.canReuseCache();
@@ -475,17 +480,19 @@
         final VectorDrawableState state = mVectorState;
         if (state.mTint != tint) {
             state.mTint = tint;
-            mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode);
+
+            updateColorFilters(mVectorState.mBlendMode, tint);
             invalidateSelf();
         }
     }
 
     @Override
-    public void setTintMode(Mode tintMode) {
+    public void setTintMode(@NonNull BlendMode blendMode) {
         final VectorDrawableState state = mVectorState;
-        if (state.mTintMode != tintMode) {
-            state.mTintMode = tintMode;
-            mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode);
+        if (state.mBlendMode != blendMode) {
+            state.mBlendMode = blendMode;
+
+            updateColorFilters(state.mBlendMode, state.mTint);
             invalidateSelf();
         }
     }
@@ -515,14 +522,22 @@
             changed = true;
             state.mCacheDirty = true;
         }
-        if (state.mTint != null && state.mTintMode != null) {
-            mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+        if (state.mTint != null && state.mBlendMode != null) {
+            BlendMode blendMode = state.mBlendMode;
+            ColorStateList tint = state.mTint;
+            updateColorFilters(blendMode, tint);
             changed = true;
         }
 
         return changed;
     }
 
+    private void updateColorFilters(@Nullable BlendMode blendMode, ColorStateList tint) {
+        PorterDuff.Mode mode = BlendMode.blendModeToPorterDuffMode(blendMode);
+        mTintFilter = updateTintFilter(mTintFilter, tint, mode);
+        mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, tint, blendMode);
+    }
+
     @Override
     public int getOpacity() {
         // We can't tell whether the drawable is fully opaque unless we examine all the pixels,
@@ -737,7 +752,7 @@
 
         final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1);
         if (tintMode != -1) {
-            state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+            state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
         }
 
         final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint);
@@ -911,7 +926,7 @@
         int[] mThemeAttrs;
         @Config int mChangingConfigurations;
         ColorStateList mTint = null;
-        Mode mTintMode = DEFAULT_TINT_MODE;
+        BlendMode mBlendMode = DEFAULT_BLEND_MODE;
         boolean mAutoMirrored;
 
         int mBaseWidth = 0;
@@ -929,7 +944,7 @@
         // Fields for cache
         int[] mCachedThemeAttrs;
         ColorStateList mCachedTint;
-        Mode mCachedTintMode;
+        BlendMode mCachedBlendMode;
         boolean mCachedAutoMirrored;
         boolean mCacheDirty;
 
@@ -970,7 +985,7 @@
                 mThemeAttrs = copy.mThemeAttrs;
                 mChangingConfigurations = copy.mChangingConfigurations;
                 mTint = copy.mTint;
-                mTintMode = copy.mTintMode;
+                mBlendMode = copy.mBlendMode;
                 mAutoMirrored = copy.mAutoMirrored;
                 mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
                 createNativeTreeFromCopy(copy, mRootGroup);
@@ -1026,7 +1041,7 @@
             if (!mCacheDirty
                     && mCachedThemeAttrs == mThemeAttrs
                     && mCachedTint == mTint
-                    && mCachedTintMode == mTintMode
+                    && mCachedBlendMode == mBlendMode
                     && mCachedAutoMirrored == mAutoMirrored) {
                 return true;
             }
@@ -1039,7 +1054,7 @@
             // likely hit cache miss more, but practically not much difference.
             mCachedThemeAttrs = mThemeAttrs;
             mCachedTint = mTint;
-            mCachedTintMode = mTintMode;
+            mCachedBlendMode = mBlendMode;
             mCachedAutoMirrored = mAutoMirrored;
             mCacheDirty = false;
         }
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 1836f00..bd1a492 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -435,8 +435,9 @@
             final long transformPtr = transform.native_instance;
 
             synchronized (sPdfiumLock) {
-                nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft,
-                        contentTop, contentRight, contentBottom, transformPtr, renderMode);
+                nativeRenderPage(mNativeDocument, mNativePage, destination.getNativeInstance(),
+                        contentLeft, contentTop, contentRight, contentBottom, transformPtr,
+                        renderMode);
             }
         }
 
@@ -487,7 +488,7 @@
     private static native void nativeClose(long documentPtr);
     private static native int nativeGetPageCount(long documentPtr);
     private static native boolean nativeScaleForPrinting(long documentPtr);
-    private static native void nativeRenderPage(long documentPtr, long pagePtr, Bitmap dest,
+    private static native void nativeRenderPage(long documentPtr, long pagePtr, long bitmapHandle,
             int clipLeft, int clipTop, int clipRight, int clipBottom, long transformPtr,
             int renderMode);
     private static native long nativeOpenPageAndGetSize(long documentPtr, int pageIndex,
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index bfce17c..f21fa5e 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -17,7 +17,6 @@
 package android.security;
 
 import android.annotation.UnsupportedAppUsage;
-import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.Application;
 import android.app.KeyguardManager;
@@ -45,24 +44,24 @@
 import android.security.keystore.KeyNotYetValidException;
 import android.security.keystore.KeyPermanentlyInvalidatedException;
 import android.security.keystore.KeyProperties;
-import android.security.keystore.KeyProtection;
 import android.security.keystore.KeystoreResponse;
-import android.security.keystore.StrongBoxUnavailableException;
 import android.security.keystore.UserNotAuthenticatedException;
 import android.util.Log;
+
 import com.android.org.bouncycastle.asn1.ASN1InputStream;
 import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
-import java.math.BigInteger;
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.math.BigInteger;
 import java.security.InvalidKeyException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
+
 import sun.security.util.ObjectIdentifier;
 import sun.security.x509.AlgorithmId;
 
@@ -492,8 +491,9 @@
     }
 
     public boolean addRngEntropy(byte[] data, int flags) {
+        KeystoreResultPromise promise = new KeystoreResultPromise();
         try {
-            KeystoreResultPromise promise = new KeystoreResultPromise();
+            mBinder.asBinder().linkToDeath(promise, 0);
             int errorCode = mBinder.addRngEntropy(promise, data, flags);
             if (errorCode == NO_ERROR) {
                 return promise.getFuture().get().getErrorCode() == NO_ERROR;
@@ -506,6 +506,8 @@
         } catch (ExecutionException | InterruptedException e) {
             Log.e(TAG, "AddRngEntropy completed with exception", e);
             return false;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
     }
 
@@ -537,7 +539,8 @@
     }
 
     private class KeyCharacteristicsPromise
-    extends android.security.keystore.IKeystoreKeyCharacteristicsCallback.Stub {
+            extends android.security.keystore.IKeystoreKeyCharacteristicsCallback.Stub
+            implements IBinder.DeathRecipient {
         final private CompletableFuture<KeyCharacteristicsCallbackResult> future =
                 new CompletableFuture<KeyCharacteristicsCallbackResult>();
         @Override
@@ -550,19 +553,30 @@
         public final CompletableFuture<KeyCharacteristicsCallbackResult> getFuture() {
             return future;
         }
+        @Override
+        public void binderDied() {
+            future.completeExceptionally(new RemoteException("Keystore died"));
+        }
     };
 
     private int generateKeyInternal(String alias, KeymasterArguments args, byte[] entropy, int uid,
             int flags, KeyCharacteristics outCharacteristics)
                     throws RemoteException, ExecutionException, InterruptedException {
         KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
-        int error = mBinder.generateKey(promise, alias, args, entropy, uid, flags);
-        if (error != NO_ERROR) {
-            Log.e(TAG, "generateKeyInternal failed on request " + error);
-            return error;
+        int error = NO_ERROR;
+        KeyCharacteristicsCallbackResult result = null;
+        try {
+            mBinder.asBinder().linkToDeath(promise, 0);
+            error = mBinder.generateKey(promise, alias, args, entropy, uid, flags);
+            if (error != NO_ERROR) {
+                Log.e(TAG, "generateKeyInternal failed on request " + error);
+                return error;
+            }
+            result = promise.getFuture().get();
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
 
-        KeyCharacteristicsCallbackResult result = promise.getFuture().get();
         error = result.getKeystoreResponse().getErrorCode();
         if (error != NO_ERROR) {
             Log.e(TAG, "generateKeyInternal failed on response " + error);
@@ -604,10 +618,12 @@
 
     public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId,
             int uid, KeyCharacteristics outCharacteristics) {
+        KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
         try {
+            mBinder.asBinder().linkToDeath(promise, 0);
             clientId = clientId != null ? clientId : new KeymasterBlob(new byte[0]);
             appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
-            KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
+
             int error = mBinder.getKeyCharacteristics(promise, alias, clientId, appId, uid);
             if (error != NO_ERROR) return error;
 
@@ -625,6 +641,8 @@
         } catch (ExecutionException | InterruptedException e) {
             Log.e(TAG, "GetKeyCharacteristics completed with exception", e);
             return SYSTEM_ERROR;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
     }
 
@@ -637,17 +655,23 @@
             int uid, int flags, KeyCharacteristics outCharacteristics)
                     throws RemoteException, ExecutionException, InterruptedException {
         KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
-        int error = mBinder.importKey(promise, alias, args, format, keyData, uid, flags);
-        if (error != NO_ERROR) return error;
+        mBinder.asBinder().linkToDeath(promise, 0);
+        try {
+            int error = mBinder.importKey(promise, alias, args, format, keyData, uid, flags);
+            if (error != NO_ERROR) return error;
 
-        KeyCharacteristicsCallbackResult result = promise.getFuture().get();
-        error = result.getKeystoreResponse().getErrorCode();
-        if (error != NO_ERROR) return error;
+            KeyCharacteristicsCallbackResult result = promise.getFuture().get();
 
-        KeyCharacteristics characteristics = result.getKeyCharacteristics();
-        if (characteristics == null) return SYSTEM_ERROR;
-        outCharacteristics.shallowCopyFrom(characteristics);
-        return NO_ERROR;
+            error = result.getKeystoreResponse().getErrorCode();
+            if (error != NO_ERROR) return error;
+
+            KeyCharacteristics characteristics = result.getKeyCharacteristics();
+            if (characteristics == null) return SYSTEM_ERROR;
+            outCharacteristics.shallowCopyFrom(characteristics);
+            return NO_ERROR;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
+        }
     }
 
     public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData,
@@ -738,18 +762,25 @@
             KeyCharacteristics outCharacteristics)
                     throws RemoteException, ExecutionException, InterruptedException {
         KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
-        int error = mBinder.importWrappedKey(promise, wrappedKeyAlias, wrappedKey, wrappingKeyAlias,
-                maskingKey, args, rootSid, fingerprintSid);
-        if (error != NO_ERROR) return error;
+        mBinder.asBinder().linkToDeath(promise, 0);
+        try {
+            KeyCharacteristicsCallbackResult result = null;
+            int error = mBinder.importWrappedKey(promise, wrappedKeyAlias, wrappedKey,
+                    wrappingKeyAlias, maskingKey, args, rootSid, fingerprintSid);
+            if (error != NO_ERROR) return error;
 
-        KeyCharacteristicsCallbackResult result = promise.getFuture().get();
-        error = result.getKeystoreResponse().getErrorCode();
-        if (error != NO_ERROR) return error;
+            KeyCharacteristicsCallbackResult esult = promise.getFuture().get();
 
-        KeyCharacteristics characteristics = result.getKeyCharacteristics();
-        if (characteristics == null) return SYSTEM_ERROR;
-        outCharacteristics.shallowCopyFrom(characteristics);
-        return NO_ERROR;
+            error = result.getKeystoreResponse().getErrorCode();
+            if (error != NO_ERROR) return error;
+
+            KeyCharacteristics characteristics = result.getKeyCharacteristics();
+            if (characteristics == null) return SYSTEM_ERROR;
+            outCharacteristics.shallowCopyFrom(characteristics);
+            return NO_ERROR;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
+        }
     }
 
     public int importWrappedKey(String wrappedKeyAlias, byte[] wrappedKey,
@@ -776,7 +807,8 @@
     }
 
     private class ExportKeyPromise
-    extends android.security.keystore.IKeystoreExportKeyCallback.Stub {
+            extends android.security.keystore.IKeystoreExportKeyCallback.Stub
+            implements IBinder.DeathRecipient {
         final private CompletableFuture<ExportResult> future = new CompletableFuture<ExportResult>();
         @Override
         public void onFinished(ExportResult exportKeyResult) throws android.os.RemoteException {
@@ -785,14 +817,19 @@
         public final CompletableFuture<ExportResult> getFuture() {
             return future;
         }
+        @Override
+        public void binderDied() {
+            future.completeExceptionally(new RemoteException("Keystore died"));
+        }
     };
 
     public ExportResult exportKey(String alias, int format, KeymasterBlob clientId,
             KeymasterBlob appId, int uid) {
+        ExportKeyPromise promise = new ExportKeyPromise();
         try {
+            mBinder.asBinder().linkToDeath(promise, 0);
             clientId = clientId != null ? clientId : new KeymasterBlob(new byte[0]);
             appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
-            ExportKeyPromise promise = new ExportKeyPromise();
             int error = mBinder.exportKey(promise, alias, format, clientId, appId, uid);
             if (error == NO_ERROR) {
                 return promise.getFuture().get();
@@ -805,6 +842,8 @@
         } catch (ExecutionException | InterruptedException e) {
             Log.e(TAG, "ExportKey completed with exception", e);
             return null;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
     }
     public ExportResult exportKey(String alias, int format, KeymasterBlob clientId,
@@ -813,7 +852,8 @@
     }
 
     private class OperationPromise
-    extends android.security.keystore.IKeystoreOperationResultCallback.Stub {
+            extends android.security.keystore.IKeystoreOperationResultCallback.Stub
+            implements IBinder.DeathRecipient {
         final private CompletableFuture<OperationResult> future = new CompletableFuture<OperationResult>();
         @Override
         public void onFinished(OperationResult operationResult) throws android.os.RemoteException {
@@ -822,14 +862,19 @@
         public final CompletableFuture<OperationResult> getFuture() {
             return future;
         }
+        @Override
+        public void binderDied() {
+            future.completeExceptionally(new RemoteException("Keystore died"));
+        }
     };
 
     public OperationResult begin(String alias, int purpose, boolean pruneable,
             KeymasterArguments args, byte[] entropy, int uid) {
+        OperationPromise promise = new OperationPromise();
         try {
+            mBinder.asBinder().linkToDeath(promise, 0);
             args = args != null ? args : new KeymasterArguments();
             entropy = entropy != null ? entropy : new byte[0];
-            OperationPromise promise = new OperationPromise();
             int errorCode =  mBinder.begin(promise, getToken(), alias, purpose, pruneable, args,
                                            entropy, uid);
             if (errorCode == NO_ERROR) {
@@ -843,6 +888,8 @@
         } catch (ExecutionException | InterruptedException e) {
             Log.e(TAG, "Begin completed with exception", e);
             return null;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
     }
 
@@ -854,10 +901,11 @@
     }
 
     public OperationResult update(IBinder token, KeymasterArguments arguments, byte[] input) {
+        OperationPromise promise = new OperationPromise();
         try {
+            mBinder.asBinder().linkToDeath(promise, 0);
             arguments = arguments != null ? arguments : new KeymasterArguments();
             input = input != null ? input : new byte[0];
-            OperationPromise promise = new OperationPromise();
             int errorCode =  mBinder.update(promise, token, arguments, input);
             if (errorCode == NO_ERROR) {
                 return promise.getFuture().get();
@@ -870,16 +918,19 @@
         } catch (ExecutionException | InterruptedException e) {
             Log.e(TAG, "Update completed with exception", e);
             return null;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
     }
 
     public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature,
             byte[] entropy) {
+        OperationPromise promise = new OperationPromise();
         try {
+            mBinder.asBinder().linkToDeath(promise, 0);
             arguments = arguments != null ? arguments : new KeymasterArguments();
             entropy = entropy != null ? entropy : new byte[0];
             signature = signature != null ? signature : new byte[0];
-            OperationPromise promise = new OperationPromise();
             int errorCode = mBinder.finish(promise, token, arguments, signature, entropy);
             if (errorCode == NO_ERROR) {
                 return promise.getFuture().get();
@@ -892,6 +943,8 @@
         } catch (ExecutionException | InterruptedException e) {
             Log.e(TAG, "Finish completed with exception", e);
             return null;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
     }
 
@@ -900,7 +953,8 @@
     }
 
     private class KeystoreResultPromise
-    extends android.security.keystore.IKeystoreResponseCallback.Stub {
+            extends android.security.keystore.IKeystoreResponseCallback.Stub
+            implements IBinder.DeathRecipient {
         final private CompletableFuture<KeystoreResponse> future = new CompletableFuture<KeystoreResponse>();
         @Override
         public void onFinished(KeystoreResponse keystoreResponse) throws android.os.RemoteException {
@@ -909,11 +963,16 @@
         public final CompletableFuture<KeystoreResponse> getFuture() {
             return future;
         }
+        @Override
+        public void binderDied() {
+            future.completeExceptionally(new RemoteException("Keystore died"));
+        }
     };
 
     public int abort(IBinder token) {
+        KeystoreResultPromise promise = new KeystoreResultPromise();
         try {
-            KeystoreResultPromise promise = new KeystoreResultPromise();
+            mBinder.asBinder().linkToDeath(promise, 0);
             int errorCode = mBinder.abort(promise, token);
             if (errorCode == NO_ERROR) {
                 return promise.getFuture().get().getErrorCode();
@@ -926,6 +985,8 @@
         } catch (ExecutionException | InterruptedException e) {
             Log.e(TAG, "Abort completed with exception", e);
             return SYSTEM_ERROR;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
     }
 
@@ -1035,7 +1096,8 @@
     }
 
     private class CertificateChainPromise
-    extends android.security.keystore.IKeystoreCertificateChainCallback.Stub {
+            extends android.security.keystore.IKeystoreCertificateChainCallback.Stub
+            implements IBinder.DeathRecipient {
         final private CompletableFuture<KeyAttestationCallbackResult> future = new CompletableFuture<KeyAttestationCallbackResult>();
         @Override
         public void onFinished(KeystoreResponse keystoreResponse,
@@ -1045,19 +1107,24 @@
         public final CompletableFuture<KeyAttestationCallbackResult> getFuture() {
             return future;
         }
+        @Override
+        public void binderDied() {
+            future.completeExceptionally(new RemoteException("Keystore died"));
+        }
     };
 
 
     public int attestKey(
             String alias, KeymasterArguments params, KeymasterCertificateChain outChain) {
+        CertificateChainPromise promise = new CertificateChainPromise();
         try {
+            mBinder.asBinder().linkToDeath(promise, 0);
             if (params == null) {
                 params = new KeymasterArguments();
             }
             if (outChain == null) {
                 outChain = new KeymasterCertificateChain();
             }
-            CertificateChainPromise promise = new CertificateChainPromise();
             int error = mBinder.attestKey(promise, alias, params);
             if (error != NO_ERROR) return error;
             KeyAttestationCallbackResult result = promise.getFuture().get();
@@ -1072,18 +1139,21 @@
         } catch (ExecutionException | InterruptedException e) {
             Log.e(TAG, "AttestKey completed with exception", e);
             return SYSTEM_ERROR;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
     }
 
     public int attestDeviceIds(KeymasterArguments params, KeymasterCertificateChain outChain) {
+        CertificateChainPromise promise = new CertificateChainPromise();
         try {
+            mBinder.asBinder().linkToDeath(promise, 0);
             if (params == null) {
                 params = new KeymasterArguments();
             }
             if (outChain == null) {
                 outChain = new KeymasterCertificateChain();
             }
-            CertificateChainPromise promise = new CertificateChainPromise();
             int error = mBinder.attestDeviceIds(promise, params);
             if (error != NO_ERROR) return error;
             KeyAttestationCallbackResult result = promise.getFuture().get();
@@ -1098,6 +1168,8 @@
         } catch (ExecutionException | InterruptedException e) {
             Log.e(TAG, "AttestDevicdeIds completed with exception", e);
             return SYSTEM_ERROR;
+        } finally {
+            mBinder.asBinder().unlinkToDeath(promise, 0);
         }
     }
 
diff --git a/packages/NetworkStackPermissionStub/Android.bp b/keystore/tests/Android.bp
similarity index 60%
copy from packages/NetworkStackPermissionStub/Android.bp
copy to keystore/tests/Android.bp
index 8cee92e..e9b22c1 100644
--- a/packages/NetworkStackPermissionStub/Android.bp
+++ b/keystore/tests/Android.bp
@@ -1,5 +1,4 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2017 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,17 +11,16 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-//
 
-// Stub APK to define permissions for NetworkStack
-android_app {
-    name: "NetworkStackPermissionStub",
-    // TODO: mark app as hasCode=false in manifest once soong stops complaining about apps without
-    // a classes.dex.
+android_test {
+    name: "KeystoreTests",
+    // LOCAL_MODULE := keystore
     srcs: ["src/**/*.java"],
+    static_libs: [
+        "androidx.test.rules",
+        "hamcrest-library",
+    ],
     platform_apis: true,
-    min_sdk_version: "28",
-    certificate: "networkstack",
-    privileged: true,
-    manifest: "AndroidManifest.xml",
+    libs: ["android.test.runner"],
+    certificate: "platform",
 }
diff --git a/keystore/tests/Android.mk b/keystore/tests/Android.mk
deleted file mode 100644
index 99d3197..0000000
--- a/keystore/tests/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# LOCAL_MODULE := keystore
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.test.rules hamcrest-library
-
-LOCAL_PACKAGE_NAME := KeystoreTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
-
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 66a5477..7b7599f 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -29,6 +29,7 @@
 
 #include "androidfw/Asset.h"
 #include "androidfw/Idmap.h"
+#include "androidfw/misc.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/Util.h"
 
@@ -39,8 +40,10 @@
 
 static const std::string kResourcesArsc("resources.arsc");
 
-ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path)
-    : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path) {
+ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle,
+                     const std::string& path,
+                     time_t last_mod_time)
+    : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path), last_mod_time_(last_mod_time) {
 }
 
 std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) {
@@ -116,8 +119,10 @@
     return {};
   }
 
+  time_t last_mod_time = getFileModDate(path.c_str());
+
   // Wrap the handle in a unique_ptr so it gets automatically closed.
-  std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(unmanaged_handle, path));
+  std::unique_ptr<ApkAssets> loaded_apk(new ApkAssets(unmanaged_handle, path, last_mod_time));
 
   // Find the resource table.
   ::ZipString entry_name(kResourcesArsc.c_str());
@@ -248,4 +253,8 @@
   return result == -1;
 }
 
+bool ApkAssets::IsUpToDate() const {
+  return last_mod_time_ == getFileModDate(path_.c_str());
+}
+
 }  // namespace android
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 365be10..21609d3 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -75,6 +75,7 @@
 const char* AssetManager::VENDOR_OVERLAY_DIR = "/vendor/overlay";
 const char* AssetManager::PRODUCT_OVERLAY_DIR = "/product/overlay";
 const char* AssetManager::PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
+const char* AssetManager::ODM_OVERLAY_DIR = "/odm/overlay";
 const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme";
 const char* AssetManager::TARGET_PACKAGE_NAME = "android";
 const char* AssetManager::TARGET_APK_PATH = "/system/framework/framework-res.apk";
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index a99e77f..e1067fc 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -49,15 +49,21 @@
     int ashmemFd = ashmem_create_region(ashmemName.string(), size);
     if (ashmemFd < 0) {
         result = -errno;
+        ALOGE("CursorWindow: ashmem_create_region() failed: errno=%d.", errno);
     } else {
         result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
-        if (result >= 0) {
+        if (result < 0) {
+            ALOGE("CursorWindow: ashmem_set_prot_region() failed: errno=%d",errno);
+        } else {
             void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
             if (data == MAP_FAILED) {
                 result = -errno;
+                ALOGE("CursorWindow: mmap() failed: errno=%d.", errno);
             } else {
                 result = ashmem_set_prot_region(ashmemFd, PROT_READ);
-                if (result >= 0) {
+                if (result < 0) {
+                    ALOGE("CursorWindow: ashmem_set_prot_region() failed: errno=%d.", errno);
+                } else {
                     CursorWindow* window = new CursorWindow(name, ashmemFd,
                             data, size, false /*readOnly*/);
                     result = window->clear();
@@ -86,26 +92,34 @@
     String8 name = parcel->readString8();
 
     status_t result;
+    int actualSize;
     int ashmemFd = parcel->readFileDescriptor();
     if (ashmemFd == int(BAD_TYPE)) {
         result = BAD_TYPE;
+        ALOGE("CursorWindow: readFileDescriptor() failed");
     } else {
         ssize_t size = ashmem_get_size_region(ashmemFd);
         if (size < 0) {
             result = UNKNOWN_ERROR;
+            ALOGE("CursorWindow: ashmem_get_size_region() failed: errno=%d.", errno);
         } else {
             int dupAshmemFd = ::fcntl(ashmemFd, F_DUPFD_CLOEXEC, 0);
             if (dupAshmemFd < 0) {
                 result = -errno;
+                ALOGE("CursorWindow: fcntl() failed: errno=%d.", errno);
             } else {
                 // the size of the ashmem descriptor can be modified between ashmem_get_size_region
                 // call and mmap, so we'll check again immediately after memory is mapped
                 void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0);
                 if (data == MAP_FAILED) {
                     result = -errno;
-                } else if (ashmem_get_size_region(dupAshmemFd) != size) {
+                    ALOGE("CursorWindow: mmap() failed: errno=%d.", errno);
+                } else if ((actualSize = ashmem_get_size_region(dupAshmemFd)) != size) {
                     ::munmap(data, size);
                     result = BAD_VALUE;
+                    ALOGE("CursorWindow: ashmem_get_size_region() returned %d, expected %d"
+                            " errno=%d",
+                            actualSize, (int) size, errno);
                 } else {
                     CursorWindow* window = new CursorWindow(name, dupAshmemFd,
                             data, size, true /*readOnly*/);
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index 35bbb58..49fc82b 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -84,6 +84,8 @@
     return idmap_asset_.get() != nullptr;
   }
 
+  bool IsUpToDate() const;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(ApkAssets);
 
@@ -95,12 +97,13 @@
   // Creates an Asset from any file on the file system.
   static std::unique_ptr<Asset> CreateAssetFromFile(const std::string& path);
 
-  ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path);
+  ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path, time_t last_mod_time);
 
   using ZipArchivePtr = std::unique_ptr<ZipArchive, void(*)(ZipArchiveHandle)>;
 
   ZipArchivePtr zip_handle_;
   const std::string path_;
+  time_t last_mod_time_;
   std::unique_ptr<Asset> resources_asset_;
   std::unique_ptr<Asset> idmap_asset_;
   std::unique_ptr<const LoadedArsc> loaded_arsc_;
diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
index e22e2d2..a015eab 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -62,6 +62,7 @@
     static const char* VENDOR_OVERLAY_DIR;
     static const char* PRODUCT_OVERLAY_DIR;
     static const char* PRODUCT_SERVICES_OVERLAY_DIR;
+    static const char* ODM_OVERLAY_DIR;
     /*
      * If OVERLAY_THEME_DIR_PROPERTY is set, search for runtime resource overlay
      * APKs in VENDOR_OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index 8f7e814..9bb6031 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -349,8 +349,7 @@
     } else {
         SkBitmap bitmap;
         const SkImageInfo& info = source.info();
-        bitmap.allocPixels(
-                SkImageInfo::MakeN32(info.width(), info.height(), info.alphaType(), nullptr));
+        bitmap.allocPixels(info.makeColorType(kN32_SkColorType));
 
         SkCanvas canvas(bitmap);
         canvas.drawColor(0);
@@ -416,7 +415,9 @@
 }
 
 void HardwareBitmapUploader::terminate() {
-    sUploader->destroy();
+    if (sUploader) {
+        sUploader->destroy();
+    }
 }
 
 }  // namespace android::uirenderer
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index fb60a96..89a9b99 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -84,6 +84,7 @@
 }
 
 CopyResult Readback::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap* bitmap) {
+    ATRACE_CALL();
     if (!mRenderThread.getGrContext()) {
         return CopyResult::UnknownError;
     }
@@ -104,6 +105,7 @@
 
 CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTransform,
                                    const Rect& srcRect, SkBitmap* bitmap) {
+    ATRACE_CALL();
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
         mRenderThread.requireGlContext();
     } else {
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index ceab407..1b9e53b 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -19,6 +19,7 @@
 
 #include "renderthread/VulkanManager.h"
 #include "renderthread/RenderThread.h"
+#include <SkAndroidFrameworkUtils.h>
 #include <GrBackendDrawableInfo.h>
 #include <SkImage.h>
 #include <utils/Color.h>
@@ -89,9 +90,29 @@
 VkFunctorDrawable::~VkFunctorDrawable() {
 }
 
-void VkFunctorDrawable::onDraw(SkCanvas* /*canvas*/) {
-    LOG_ALWAYS_FATAL("VkFunctorDrawable::onDraw() should never be called.");
-    // Instead of calling onDraw(), the call should come from onSnapGpuDrawHandler.
+void VkFunctorDrawable::onDraw(SkCanvas* canvas) {
+    // "canvas" is either SkNWayCanvas created by SkiaPipeline::tryCapture (SKP capture use case) or
+    // AlphaFilterCanvas (used by RenderNodeDrawable to apply alpha in certain cases).
+    // "VkFunctorDrawable::onDraw" is not invoked for the most common case, when drawing in a GPU
+    // canvas.
+
+    if (canvas->getGrContext() == nullptr) {
+        // We're dumping a picture, render a light-blue rectangle instead
+        SkPaint paint;
+        paint.setColor(0xFF81D4FA);
+        canvas->drawRect(mBounds, paint);
+    } else {
+        // Handle the case when "canvas" is AlphaFilterCanvas. Find the wrapped GPU canvas.
+        SkCanvas* gpuCanvas = SkAndroidFrameworkUtils::getBaseWrappedCanvas(canvas);
+        // Enforce "canvas" must be an AlphaFilterCanvas. For GPU canvas, the call should come from
+        // onSnapGpuDrawHandler.
+        LOG_ALWAYS_FATAL_IF(
+                gpuCanvas == canvas,
+                "VkFunctorDrawable::onDraw() should not be called with a GPU canvas!");
+
+        // This will invoke onSnapGpuDrawHandler and regular draw flow.
+        gpuCanvas->drawDrawable(this);
+    }
 }
 
 std::unique_ptr<FunctorDrawable::GpuDrawHandler> VkFunctorDrawable::onSnapGpuDrawHandler(
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 1bcb819..16240b4 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -162,6 +162,7 @@
 }
 
 bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
+    ATRACE_NAME("TextureView#getBitmap");
     auto& thread = RenderThread::getInstance();
     return thread.queue().runSync([&]() -> bool {
         return thread.readback().copyLayerInto(layer, &bitmap) == CopyResult::Success;
@@ -347,6 +348,7 @@
 }
 
 int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) {
+    ATRACE_NAME("HardwareBitmap readback");
     RenderThread& thread = RenderThread::getInstance();
     if (gettid() == thread.getTid()) {
         // TODO: fix everything that hits this. We should never be triggering a readback ourselves.
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 6cce319..b76e49c 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -209,8 +209,8 @@
     mVkManager->initialize();
     GrContextOptions options;
     initGrContextOptions(options);
-    // TODO: get a string describing the SPIR-V compiler version and use it here
-    cacheManager().configureContext(&options, nullptr, 0);
+    auto vkDriverVersion = mVkManager->getDriverVersion();
+    cacheManager().configureContext(&options, &vkDriverVersion, sizeof(vkDriverVersion));
     sk_sp<GrContext> grContext = mVkManager->createContext(options);
     LOG_ALWAYS_FATAL_IF(!grContext.get());
     setGrContext(grContext);
@@ -408,12 +408,13 @@
 }
 
 void RenderThread::preload() {
-    std::thread eglInitThread([]() {
-        //TODO: don't load EGL drivers for Vulkan, when HW bitmap uploader is refactored.
-        eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    });
-    eglInitThread.detach();
-    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
+    // EGL driver is always preloaded only if HWUI renders with GL.
+    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
+        std::thread eglInitThread([]() {
+            eglGetDisplay(EGL_DEFAULT_DISPLAY);
+        });
+        eglInitThread.detach();
+    } else {
         requireVkContext();
     }
     HardwareBitmapUploader::initialize();
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index b8ebf3b..4011329 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -170,6 +170,9 @@
     VkPhysicalDeviceProperties physDeviceProperties;
     mGetPhysicalDeviceProperties(mPhysicalDevice, &physDeviceProperties);
     LOG_ALWAYS_FATAL_IF(physDeviceProperties.apiVersion < VK_MAKE_VERSION(1, 1, 0));
+    mDriverVersion = physDeviceProperties.driverVersion;
+
+    mIsQualcomm = physDeviceProperties.vendorID == 20803;
 
     // query to get the initial queue props size
     uint32_t queueCount;
@@ -493,6 +496,12 @@
         mDeviceWaitIdle(mDevice);
     }
 
+    VulkanSurface::NativeBufferInfo* bufferInfo = surface->getCurrentBufferInfo();
+    if (!bufferInfo) {
+        // If VulkanSurface::dequeueNativeBuffer failed earlier, then swapBuffers is a no-op.
+        return;
+    }
+
     VkExportSemaphoreCreateInfo exportInfo;
     exportInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
     exportInfo.pNext = nullptr;
@@ -509,8 +518,6 @@
     GrBackendSemaphore backendSemaphore;
     backendSemaphore.initVulkan(semaphore);
 
-    VulkanSurface::NativeBufferInfo* bufferInfo = surface->getCurrentBufferInfo();
-
     int fenceFd = -1;
     GrSemaphoresSubmitted submitted =
             bufferInfo->skSurface->flush(SkSurface::BackendSurfaceAccess::kPresent,
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index c2d1802..a7a43cc 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -82,6 +82,8 @@
 
     sk_sp<GrContext> createContext(const GrContextOptions& options);
 
+    uint32_t getDriverVersion() const { return mDriverVersion; }
+
 private:
     friend class VulkanSurface;
     // Sets up the VkInstance and VkDevice objects. Also fills out the passed in
@@ -178,6 +180,14 @@
     };
     SwapBehavior mSwapBehavior = SwapBehavior::Discard;
     GrVkExtensions mExtensions;
+    uint32_t mDriverVersion = 0;
+
+    // TODO: Remove once fix has landed. Temporaryly needed for workaround for setting up AHB
+    // surfaces on Qualcomm. Currently if you don't use VkSwapchain Qualcomm is not setting
+    // reporting that we need to use one of their private vendor usage bits which greatly effects
+    // performance if it is not used.
+    bool mIsQualcomm = false;
+    bool isQualcomm() const { return mIsQualcomm; }
 };
 
 } /* namespace renderthread */
diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp
index a98eb32..36f540c 100644
--- a/libs/hwui/renderthread/VulkanSurface.cpp
+++ b/libs/hwui/renderthread/VulkanSurface.cpp
@@ -222,7 +222,17 @@
     const SkISize maxSize = SkISize::Make(caps.maxImageExtent.width, caps.maxImageExtent.height);
     ComputeWindowSizeAndTransform(&windowInfo, minSize, maxSize);
 
-    windowInfo.bufferCount = std::max<uint32_t>(VulkanSurface::sMaxBufferCount, caps.minImageCount);
+    int query_value;
+    int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
+    if (err != 0 || query_value < 0) {
+        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err,
+              query_value);
+        return nullptr;
+    }
+    auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
+
+    windowInfo.bufferCount = min_undequeued_buffers
+            + std::max(VulkanSurface::sTargetBufferCount, caps.minImageCount);
     if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) {
         // Application must settle for fewer images than desired:
         windowInfo.bufferCount = caps.maxImageCount;
@@ -289,6 +299,10 @@
         }
 
         windowInfo.windowUsageFlags = hwbUsage.androidHardwareBufferUsage;
+        if (vkManager.isQualcomm()) {
+            windowInfo.windowUsageFlags =
+                    windowInfo.windowUsageFlags | AHARDWAREBUFFER_USAGE_VENDOR_0;
+        }
 
     } else {
         ALOGE("VulkanSurface::Create() vkmGetPhysicalDeviceImageFormatProperties2 is missing");
@@ -357,10 +371,9 @@
         return false;
     }
 
-    // Lower layer insists that we have at least two buffers.
-    err = native_window_set_buffer_count(window, std::max(2, windowInfo.bufferCount));
+    err = native_window_set_buffer_count(window, windowInfo.bufferCount);
     if (err != 0) {
-        ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%d) failed: %s (%d)",
+        ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s (%d)",
               windowInfo.bufferCount, strerror(-err), err);
         return false;
     }
@@ -392,7 +405,7 @@
 }
 
 void VulkanSurface::releaseBuffers() {
-    for (uint32_t i = 0; i < VulkanSurface::sMaxBufferCount; i++) {
+    for (uint32_t i = 0; i < mWindowInfo.bufferCount; i++) {
         VulkanSurface::NativeBufferInfo& bufferInfo = mNativeBuffers[i];
 
         if (bufferInfo.buffer.get() != nullptr && bufferInfo.dequeued) {
@@ -420,9 +433,10 @@
 }
 
 VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() {
-    // Set the dequeue index to invalid in case of error and only reset it to the correct
+    // Set the mCurrentBufferInfo to invalid in case of error and only reset it to the correct
     // value at the end of the function if everything dequeued correctly.
-    mDequeuedIndex = -1;
+    mCurrentBufferInfo = nullptr;
+
 
     //check if the native window has been resized or rotated and update accordingly
     SkISize newSize = SkISize::MakeEmpty();
@@ -511,7 +525,7 @@
         }
     }
 
-    mDequeuedIndex = idx;
+    mCurrentBufferInfo = bufferInfo;
     return bufferInfo;
 }
 
@@ -535,7 +549,8 @@
         ALOGE_IF(err != 0, "native_window_set_surface_damage failed: %s (%d)", strerror(-err), err);
     }
 
-    VulkanSurface::NativeBufferInfo& currentBuffer = mNativeBuffers[mDequeuedIndex];
+    LOG_ALWAYS_FATAL_IF(!mCurrentBufferInfo);
+    VulkanSurface::NativeBufferInfo& currentBuffer = *mCurrentBufferInfo;
     int queuedFd = (semaphoreFd != -1) ? semaphoreFd : currentBuffer.dequeue_fence;
     int err = mNativeWindow->queueBuffer(mNativeWindow.get(), currentBuffer.buffer.get(), queuedFd);
 
@@ -560,7 +575,8 @@
 }
 
 int VulkanSurface::getCurrentBuffersAge() {
-    VulkanSurface::NativeBufferInfo& currentBuffer = mNativeBuffers[mDequeuedIndex];
+    LOG_ALWAYS_FATAL_IF(!mCurrentBufferInfo);
+    VulkanSurface::NativeBufferInfo& currentBuffer = *mCurrentBufferInfo;
     return currentBuffer.hasValidContents ? (mPresentCount - currentBuffer.lastPresentedCount) : 0;
 }
 
diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h
index 4fd9cd2..305483f 100644
--- a/libs/hwui/renderthread/VulkanSurface.h
+++ b/libs/hwui/renderthread/VulkanSurface.h
@@ -42,7 +42,9 @@
                                   const VulkanManager& vkManager);
     ~VulkanSurface();
 
-    sk_sp<SkSurface> getCurrentSkSurface() { return mNativeBuffers[mDequeuedIndex].skSurface; }
+    sk_sp<SkSurface> getCurrentSkSurface() {
+        return mCurrentBufferInfo ? mCurrentBufferInfo->skSurface : nullptr;
+    }
     const SkMatrix& getCurrentPreTransform() { return mWindowInfo.preTransform; }
 
 private:
@@ -65,7 +67,7 @@
     };
 
     NativeBufferInfo* dequeueNativeBuffer();
-    NativeBufferInfo* getCurrentBufferInfo() { return &mNativeBuffers[mDequeuedIndex]; }
+    NativeBufferInfo* getCurrentBufferInfo() { return mCurrentBufferInfo; }
     bool presentCurrentBuffer(const SkRect& dirtyRect, int semaphoreFd);
 
     // The width and height are are the logical width and height for when submitting draws to the
@@ -81,14 +83,19 @@
      * as private to this class.
      *
      */
-    static constexpr int sMaxBufferCount = 3;
+
+    // How many buffers we want to be able to use ourselves. We want 1 in active rendering with
+    // 1 more queued, so 2. This will be added to NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, which is
+    // how many buffers the consumer needs (eg, 1 for SurfaceFlinger), getting to a typically
+    // triple-buffered queue as a result.
+    static constexpr uint32_t sTargetBufferCount = 2;
 
     struct WindowInfo {
         SkISize size;
         PixelFormat pixelFormat;
         android_dataspace dataspace;
         int transform;
-        int bufferCount;
+        size_t bufferCount;
         uint64_t windowUsageFlags;
 
         // size of the ANativeWindow if the inverse of transform requires us to swap width/height
@@ -109,14 +116,15 @@
                                               const SkISize& maxSize);
     void releaseBuffers();
 
-    NativeBufferInfo mNativeBuffers[VulkanSurface::sMaxBufferCount];
+    // TODO: Just use a vector?
+    NativeBufferInfo mNativeBuffers[android::BufferQueueDefs::NUM_BUFFER_SLOTS];
 
     sp<ANativeWindow> mNativeWindow;
     WindowInfo mWindowInfo;
     GrContext* mGrContext;
 
-    int mDequeuedIndex = -1;
     uint32_t mPresentCount = 0;
+    NativeBufferInfo* mCurrentBufferInfo = nullptr;
 
     const SkISize mMinWindowSize;
     const SkISize mMaxWindowSize;
diff --git a/libs/incident/Android.bp b/libs/incident/Android.bp
index 905e303..150f6dc 100644
--- a/libs/incident/Android.bp
+++ b/libs/incident/Android.bp
@@ -27,23 +27,29 @@
         "libbinder",
         "liblog",
         "libutils",
+        "libprotobuf-cpp-lite",
+    ],
+
+    static_libs: [
+        "libplatformprotos",
+    ],
+
+    whole_static_libs: [
+        "libincidentcompanion",
     ],
 
     aidl: {
-        include_dirs: ["frameworks/base/core/java"],
+        include_dirs: [
+            "frameworks/base/core/java",
+            "frameworks/native/libs/incidentcompanion/binder",
+        ],
         export_aidl_headers: true,
     },
 
     srcs: [
         ":libincident_aidl",
-        "proto/android/os/metadata.proto",
         "src/IncidentReportArgs.cpp",
     ],
 
-    proto: {
-        type: "lite",
-        export_proto_headers: true,
-    },
-
     export_include_dirs: ["include"],
-}
\ No newline at end of file
+}
diff --git a/libs/incident/include/android/os/IncidentReportArgs.h b/libs/incident/include/android/os/IncidentReportArgs.h
index f056d3b..4391a9b 100644
--- a/libs/incident/include/android/os/IncidentReportArgs.h
+++ b/libs/incident/include/android/os/IncidentReportArgs.h
@@ -29,10 +29,11 @@
 
 using namespace std;
 
-// DESTINATION enum value, sync with proto/android/privacy.proto
-const uint8_t DEST_LOCAL = 0;
-const uint8_t DEST_EXPLICIT = 100;
-const uint8_t DEST_AUTOMATIC = 200;
+// DESTINATION enum value, sync with frameworks/base/core/proto/android/privacy.proto
+const uint8_t PRIVACY_POLICY_LOCAL = 0;
+const uint8_t PRIVACY_POLICY_EXPLICIT = 100;
+const uint8_t PRIVACY_POLICY_AUTOMATIC = 200;
+const uint8_t PRIVACY_POLICY_UNSET = 255;
 
 
 class IncidentReportArgs : public Parcelable {
@@ -45,7 +46,7 @@
     virtual status_t readFromParcel(const Parcel* in);
 
     void setAll(bool all);
-    void setDest(int dest);
+    void setPrivacyPolicy(int privacyPolicy);
     void addSection(int section);
     void setReceiverPkg(const string& pkg);
     void setReceiverCls(const string& cls);
@@ -53,10 +54,10 @@
 
     inline bool all() const { return mAll; }
     bool containsSection(int section) const;
-    inline int dest() const { return mDest; }
+    inline int getPrivacyPolicy() const { return mPrivacyPolicy; }
     inline const set<int>& sections() const { return mSections; }
-    inline const String16& receiverPkg() const { return mReceiverPkg; }
-    inline const String16& receiverCls() const { return mReceiverCls; }
+    inline const string& receiverPkg() const { return mReceiverPkg; }
+    inline const string& receiverCls() const { return mReceiverCls; }
     inline const vector<vector<uint8_t>>& headers() const { return mHeaders; }
 
     void merge(const IncidentReportArgs& that);
@@ -65,9 +66,9 @@
     set<int> mSections;
     vector<vector<uint8_t>> mHeaders;
     bool mAll;
-    int mDest;
-    String16 mReceiverPkg;
-    String16 mReceiverCls;
+    int mPrivacyPolicy;
+    string mReceiverPkg;
+    string mReceiverCls;
 };
 
 }
diff --git a/libs/incident/src/IncidentReportArgs.cpp b/libs/incident/src/IncidentReportArgs.cpp
index 46c8dcf9..4268638 100644
--- a/libs/incident/src/IncidentReportArgs.cpp
+++ b/libs/incident/src/IncidentReportArgs.cpp
@@ -26,7 +26,7 @@
 IncidentReportArgs::IncidentReportArgs()
     :mSections(),
      mAll(false),
-     mDest(-1)
+     mPrivacyPolicy(-1)
 {
 }
 
@@ -34,7 +34,9 @@
     :mSections(that.mSections),
      mHeaders(that.mHeaders),
      mAll(that.mAll),
-     mDest(that.mDest)
+     mPrivacyPolicy(that.mPrivacyPolicy),
+     mReceiverPkg(that.mReceiverPkg),
+     mReceiverCls(that.mReceiverCls)
 {
 }
 
@@ -76,17 +78,17 @@
         }
     }
 
-    err = out->writeInt32(mDest);
+    err = out->writeInt32(mPrivacyPolicy);
     if (err != NO_ERROR) {
         return err;
     }
 
-    err = out->writeString16(mReceiverPkg);
+    err = out->writeString16(String16(mReceiverPkg.c_str()));
     if (err != NO_ERROR) {
         return err;
     }
 
-    err = out->writeString16(mReceiverCls);
+    err = out->writeString16(String16(mReceiverCls.c_str()));
     if (err != NO_ERROR) {
         return err;
     }
@@ -137,15 +139,15 @@
         }
     }
 
-    int32_t dest;
-    err = in->readInt32(&dest);
+    int32_t privacyPolicy;
+    err = in->readInt32(&privacyPolicy);
     if (err != NO_ERROR) {
         return err;
     }
-    mDest = dest;
+    mPrivacyPolicy = privacyPolicy;
 
-    mReceiverPkg = in->readString16();
-    mReceiverCls = in->readString16();
+    mReceiverPkg = String8(in->readString16()).string();
+    mReceiverCls = String8(in->readString16()).string();
 
     return OK;
 }
@@ -160,9 +162,9 @@
 }
 
 void
-IncidentReportArgs::setDest(int dest)
+IncidentReportArgs::setPrivacyPolicy(int privacyPolicy)
 {
-    mDest = dest;
+    mPrivacyPolicy = privacyPolicy;
 }
 
 void
@@ -176,13 +178,13 @@
 void
 IncidentReportArgs::setReceiverPkg(const string& pkg)
 {
-    mReceiverPkg = String16(pkg.c_str());
+    mReceiverPkg = pkg;
 }
 
 void
 IncidentReportArgs::setReceiverCls(const string& cls)
 {
-    mReceiverCls = String16(cls.c_str());
+    mReceiverCls = cls;
 }
 
 void
@@ -200,15 +202,18 @@
 void
 IncidentReportArgs::merge(const IncidentReportArgs& that)
 {
-    if (mAll) {
-        return;
-    } else if (that.mAll) {
-        mAll = true;
-        mSections.clear();
-    } else {
-        for (set<int>::const_iterator it=that.mSections.begin();
-                it!=that.mSections.end(); it++) {
-            mSections.insert(*it);
+    for (const vector<uint8_t>& header: that.mHeaders) {
+        mHeaders.push_back(header);
+    }
+    if (!mAll) {
+        if (that.mAll) {
+            mAll = true;
+            mSections.clear();
+        } else {
+            for (set<int>::const_iterator it=that.mSections.begin();
+                    it!=that.mSections.end(); it++) {
+                mSections.insert(*it);
+            }
         }
     }
 }
diff --git a/libs/protoutil/Android.bp b/libs/protoutil/Android.bp
index 44bc97a..b0af997 100644
--- a/libs/protoutil/Android.bp
+++ b/libs/protoutil/Android.bp
@@ -25,12 +25,15 @@
 
     srcs: [
         "src/EncodedBuffer.cpp",
+        "src/ProtoFileReader.cpp",
         "src/ProtoOutputStream.cpp",
+        "src/ProtoReader.cpp",
         "src/protobuf.cpp",
     ],
 
     shared_libs: [
         "libbase",
+        "libutils",
         "libcutils",
         "liblog",
     ],
diff --git a/libs/protoutil/include/android/util/EncodedBuffer.h b/libs/protoutil/include/android/util/EncodedBuffer.h
index 0b7f6e46..f9590ee 100644
--- a/libs/protoutil/include/android/util/EncodedBuffer.h
+++ b/libs/protoutil/include/android/util/EncodedBuffer.h
@@ -17,6 +17,11 @@
 #ifndef ANDROID_UTIL_ENCODED_BUFFER_H
 #define ANDROID_UTIL_ENCODED_BUFFER_H
 
+#include <android/util/ProtoReader.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
 #include <stdint.h>
 #include <vector>
 
@@ -34,12 +39,12 @@
  *      *Index:     Index of a buffer within the mBuffers list.
  *      *Offset:    Position within a buffer.
  */
-class EncodedBuffer
+class EncodedBuffer : public virtual RefBase
 {
 public:
     EncodedBuffer();
     explicit EncodedBuffer(size_t chunkSize);
-    ~EncodedBuffer();
+    virtual ~EncodedBuffer();
 
     class Pointer {
     public:
@@ -80,8 +85,9 @@
     Pointer* wp();
 
     /**
-     * Returns the current position of write pointer, if the write buffer is full, it will automatically
-     * rotate to a new buffer with given chunkSize. If NULL is returned, it means NO_MEMORY
+     * Returns the current position of write pointer, if the write buffer is full, it will
+     * automatically rotate to a new buffer with given chunkSize. If NULL is returned, it
+     * means NO_MEMORY.
      */
     uint8_t* writeBuffer();
 
@@ -120,6 +126,21 @@
      */
     size_t writeHeader(uint32_t fieldId, uint8_t wireType);
 
+    /**
+     * Copy the contents of the parameter into the write buffer.
+     */
+    status_t writeRaw(uint8_t const* buf, size_t size);
+
+    /**
+     * Copy the entire contents of the ProtoReader into the write buffer.
+     */
+    status_t writeRaw(const sp<ProtoReader>& that);
+
+    /**
+     * Copy the size bytes of contents of the ProtoReader into the write buffer.
+     */
+    status_t writeRaw(const sp<ProtoReader>& that, size_t size);
+
     /********************************* Edit APIs ************************************************/
     /**
      * Returns the edit pointer.
@@ -157,63 +178,35 @@
     void copy(size_t srcPos, size_t size);
 
     /********************************* Read APIs ************************************************/
-    class iterator;
-    friend class iterator;
-    class iterator {
-    public:
-        explicit iterator(const EncodedBuffer& buffer);
-
-        /**
-         * Returns the number of bytes written in the buffer
-         */
-        size_t size() const;
-
-        /**
-         * Returns the size of total bytes read.
-         */
-        size_t bytesRead() const;
-
-        /**
-         * Returns the read pointer.
-         */
-        Pointer* rp();
-
-        /**
-         * Returns the current position of read pointer, if NULL is returned, it reaches end of buffer.
-         */
-        uint8_t const* readBuffer();
-
-        /**
-         * Returns the readable size in the current read buffer.
-         */
-        size_t currentToRead();
-
-        /**
-         * Returns true if next bytes is available for read.
-         */
-        bool hasNext();
-
-        /**
-         * Reads the current byte and moves pointer 1 bit.
-         */
-        uint8_t next();
-
-        /**
-         * Read varint from iterator, the iterator will point to next available byte.
-         */
-        uint64_t readRawVarint();
-
-    private:
-        const EncodedBuffer& mData;
-        Pointer mRp;
-    };
-
     /**
-     * Returns the iterator of EncodedBuffer so it guarantees consumers won't be able to modified the buffer.
+     * Returns the Reader of EncodedBuffer so it guarantees consumers won't be able to
+     * modify the buffer.
      */
-    iterator begin() const;
+    sp<ProtoReader> read();
 
 private:
+    class Reader;
+    friend class Reader;
+    class Reader : public ProtoReader {
+    public:
+        explicit Reader(const sp<EncodedBuffer>& buffer);
+        virtual ~Reader();
+
+        virtual ssize_t size() const;
+        virtual size_t bytesRead() const;
+        virtual uint8_t const* readBuffer();
+        virtual size_t currentToRead();
+        virtual bool hasNext();
+        virtual uint8_t next();
+        virtual uint64_t readRawVarint();
+        virtual void move(size_t amt);
+
+    private:
+        const sp<EncodedBuffer> mData;
+        Pointer mRp;
+        friend class EncodedBuffer;
+    };
+
     size_t mChunkSize;
     std::vector<uint8_t*> mBuffers;
 
diff --git a/libs/protoutil/include/android/util/ProtoFileReader.h b/libs/protoutil/include/android/util/ProtoFileReader.h
new file mode 100644
index 0000000..cb3d012
--- /dev/null
+++ b/libs/protoutil/include/android/util/ProtoFileReader.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <string>
+
+#include <android/util/EncodedBuffer.h>
+
+namespace android {
+namespace util {
+
+/**
+ * A ProtoReader on top of a file descriptor.
+ */
+class ProtoFileReader : public ProtoReader
+{
+public:
+    /**
+     * Read from this file descriptor.
+     */
+    ProtoFileReader(int fd);
+
+    /**
+     * Does NOT close the file.
+     */
+    virtual ~ProtoFileReader();
+
+    // From ProtoReader.
+    virtual ssize_t size() const;
+    virtual size_t bytesRead() const;
+    virtual uint8_t const* readBuffer();
+    virtual size_t currentToRead();
+    virtual bool hasNext();
+    virtual uint8_t next();
+    virtual uint64_t readRawVarint();
+    virtual void move(size_t amt);
+
+    status_t getError() const;
+private:
+    int mFd;                // File descriptor for input.
+    status_t mStatus;       // Any errors encountered during read.
+    ssize_t mSize;          // How much total data there is, or -1 if we can't tell.
+    size_t mPos;            // How much data has been read so far.
+    size_t mOffset;         // Offset in current buffer.
+    size_t mMaxOffset;      // How much data is left to read in mBuffer.
+    const int mChunkSize;   // Size of mBuffer.
+    uint8_t mBuffer[32*1024];
+
+    /**
+     * If there is currently more data to read in the buffer, returns true.
+     * If there is not more, then tries to read.  If more data can be read,
+     * it does so and returns true.  If there is no more data, returns false.
+     * Resets mOffset and mMaxOffset as necessary.  Does not advance mOffset.
+     */
+    bool ensure_data();
+};
+
+}
+}
+
diff --git a/libs/protoutil/include/android/util/ProtoOutputStream.h b/libs/protoutil/include/android/util/ProtoOutputStream.h
index ad76559..360e8d3 100644
--- a/libs/protoutil/include/android/util/ProtoOutputStream.h
+++ b/libs/protoutil/include/android/util/ProtoOutputStream.h
@@ -121,7 +121,7 @@
      * it is not able to write to ProtoOutputStream any more since the data is compact.
      */
     size_t size(); // Get the size of the serialized protobuf.
-    EncodedBuffer::iterator data(); // Get the reader apis of the data.
+    sp<ProtoReader> data(); // Get the reader apis of the data.
     bool flush(int fd); // Flush data directly to a file descriptor.
 
     /**
@@ -135,7 +135,7 @@
     void writeRawByte(uint8_t byte);
 
 private:
-    EncodedBuffer mBuffer;
+    sp<EncodedBuffer> mBuffer;
     size_t mCopyBegin;
     bool mCompact;
     uint32_t mDepth;
diff --git a/libs/protoutil/include/android/util/ProtoReader.h b/libs/protoutil/include/android/util/ProtoReader.h
new file mode 100644
index 0000000..204eb7d
--- /dev/null
+++ b/libs/protoutil/include/android/util/ProtoReader.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <stdint.h>
+#include <vector>
+
+namespace android {
+namespace util {
+
+class ProtoReader : public virtual RefBase {
+public:
+    ProtoReader();
+    ~ProtoReader();
+
+    /**
+     * Returns the number of bytes written in the buffer
+     */
+    virtual ssize_t size() const = 0;
+
+    /**
+     * Returns the size of total bytes read.
+     */
+    virtual size_t bytesRead() const = 0;
+
+    /**
+     * Returns the current position of read pointer, if NULL is returned, it reaches
+     * end of buffer.
+     */
+    virtual uint8_t const* readBuffer() = 0;
+
+    /**
+     * Returns the readable size in the current read buffer.
+     */
+    virtual size_t currentToRead() = 0;
+
+    /**
+     * Returns true if next bytes is available for read.
+     */
+    virtual bool hasNext() = 0;
+
+    /**
+     * Reads the current byte and moves pointer 1 bit.
+     */
+    virtual uint8_t next() = 0;
+
+    /**
+     * Read varint from the reader, the reader will point to next available byte.
+     */
+    virtual uint64_t readRawVarint() = 0;
+
+    /**
+     * Advance the read pointer.
+     */
+    virtual void move(size_t amt) = 0;
+};
+
+} // util
+} // android
+
diff --git a/libs/protoutil/src/EncodedBuffer.cpp b/libs/protoutil/src/EncodedBuffer.cpp
index c017851..7ffd887 100644
--- a/libs/protoutil/src/EncodedBuffer.cpp
+++ b/libs/protoutil/src/EncodedBuffer.cpp
@@ -208,6 +208,63 @@
     return writeRawVarint32((fieldId << FIELD_ID_SHIFT) | wireType);
 }
 
+status_t
+EncodedBuffer::writeRaw(uint8_t const* buf, size_t size)
+{
+    while (size > 0) {
+        uint8_t* target = writeBuffer();
+        if (target == NULL) {
+            return -ENOMEM;
+        }
+        size_t chunk = currentToWrite();
+        if (chunk > size) {
+            chunk = size;
+        }
+        memcpy(target, buf, chunk);
+        size -= chunk;
+        buf += chunk;
+        mWp.move(chunk);
+    }
+    return NO_ERROR;
+}
+
+status_t
+EncodedBuffer::writeRaw(const sp<ProtoReader>& reader)
+{
+    status_t err;
+    uint8_t const* buf;
+    while ((buf = reader->readBuffer()) != nullptr) {
+        size_t amt = reader->currentToRead();
+        err = writeRaw(buf, amt);
+        reader->move(amt);
+        if (err != NO_ERROR) {
+            return err;
+        }
+    }
+    return NO_ERROR;
+}
+
+status_t
+EncodedBuffer::writeRaw(const sp<ProtoReader>& reader, size_t size)
+{
+    status_t err;
+    uint8_t const* buf;
+    while (size > 0 && (buf = reader->readBuffer()) != nullptr) {
+        size_t amt = reader->currentToRead();
+        if (size < amt) {
+            amt = size;
+        }
+        err = writeRaw(buf, amt);
+        reader->move(amt);
+        size -= amt;
+        if (err != NO_ERROR) {
+            return err;
+        }
+    }
+    return size == 0 ? NO_ERROR : NOT_ENOUGH_DATA;
+}
+
+
 /******************************** Edit APIs ************************************************/
 EncodedBuffer::Pointer*
 EncodedBuffer::ep()
@@ -283,66 +340,63 @@
 }
 
 /********************************* Read APIs ************************************************/
-EncodedBuffer::iterator
-EncodedBuffer::begin() const
+sp<ProtoReader>
+EncodedBuffer::read()
 {
-    return EncodedBuffer::iterator(*this);
+    return new EncodedBuffer::Reader(this);
 }
 
-EncodedBuffer::iterator::iterator(const EncodedBuffer& buffer)
+EncodedBuffer::Reader::Reader(const sp<EncodedBuffer>& buffer)
         :mData(buffer),
-         mRp(buffer.mChunkSize)
+         mRp(buffer->mChunkSize)
 {
 }
 
-size_t
-EncodedBuffer::iterator::size() const
+EncodedBuffer::Reader::~Reader() {
+}
+
+ssize_t
+EncodedBuffer::Reader::size() const
 {
-    return mData.size();
+    return (ssize_t)mData->size();
 }
 
 size_t
-EncodedBuffer::iterator::bytesRead() const
+EncodedBuffer::Reader::bytesRead() const
 {
     return mRp.pos();
 }
 
-EncodedBuffer::Pointer*
-EncodedBuffer::iterator::rp()
-{
-    return &mRp;
-}
-
 uint8_t const*
-EncodedBuffer::iterator::readBuffer()
+EncodedBuffer::Reader::readBuffer()
 {
-    return hasNext() ? const_cast<uint8_t const*>(mData.at(mRp)) : NULL;
+    return hasNext() ? const_cast<uint8_t const*>(mData->at(mRp)) : NULL;
 }
 
 size_t
-EncodedBuffer::iterator::currentToRead()
+EncodedBuffer::Reader::currentToRead()
 {
-    return (mData.mWp.index() > mRp.index()) ?
-            mData.mChunkSize - mRp.offset() :
-            mData.mWp.offset() - mRp.offset();
+    return (mData->mWp.index() > mRp.index()) ?
+            mData->mChunkSize - mRp.offset() :
+            mData->mWp.offset() - mRp.offset();
 }
 
 bool
-EncodedBuffer::iterator::hasNext()
+EncodedBuffer::Reader::hasNext()
 {
-    return mRp.pos() < mData.mWp.pos();
+    return mRp.pos() < mData->mWp.pos();
 }
 
 uint8_t
-EncodedBuffer::iterator::next()
+EncodedBuffer::Reader::next()
 {
-    uint8_t res = *(mData.at(mRp));
+    uint8_t res = *(mData->at(mRp));
     mRp.move();
     return res;
 }
 
 uint64_t
-EncodedBuffer::iterator::readRawVarint()
+EncodedBuffer::Reader::readRawVarint()
 {
     uint64_t val = 0, shift = 0;
     while (true) {
@@ -354,5 +408,11 @@
     return val;
 }
 
+void
+EncodedBuffer::Reader::move(size_t amt)
+{
+    mRp.move(amt);
+}
+
 } // util
 } // android
diff --git a/libs/protoutil/src/ProtoFileReader.cpp b/libs/protoutil/src/ProtoFileReader.cpp
new file mode 100644
index 0000000..074170a
--- /dev/null
+++ b/libs/protoutil/src/ProtoFileReader.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "libprotoutil"
+
+#include <android/util/ProtoFileReader.h>
+#include <cutils/log.h>
+
+#include <cinttypes>
+#include <type_traits>
+
+#include <unistd.h>
+
+namespace android {
+namespace util {
+
+/**
+ * Get the amount of data remaining in the file in fd, or -1 if the file size can't be measured.
+ * It's not the whole file, but this allows us to skip any preamble that might have already
+ * been passed over.
+ */
+ssize_t get_file_size(int fd) {
+    off_t current = lseek(fd, 0, SEEK_CUR);
+    if (current < 0) {
+        return -1;
+    }
+    off_t end = lseek(fd, 0, SEEK_END);
+    if (end < 0) {
+        return -1;
+    }
+    off_t err = lseek(fd, current, SEEK_SET);
+    if (err < 0) {
+        ALOGW("get_file_size could do SEEK_END but not SEEK_SET. We might have skipped data.");
+        return -1;
+    }
+    return (ssize_t)(end-current);
+}
+
+// =========================================================================
+ProtoFileReader::ProtoFileReader(int fd)
+        :mFd(fd),
+         mStatus(NO_ERROR),
+         mSize(get_file_size(fd)),
+         mPos(0),
+         mOffset(0),
+         mChunkSize(sizeof(mBuffer)) {
+}
+
+ProtoFileReader::~ProtoFileReader() {
+}
+
+ssize_t
+ProtoFileReader::size() const
+{
+    return (ssize_t)mSize;
+}
+
+size_t
+ProtoFileReader::bytesRead() const
+{
+    return mPos;
+}
+
+uint8_t const*
+ProtoFileReader::readBuffer()
+{
+    return hasNext() ? mBuffer + mOffset : NULL;
+}
+
+size_t
+ProtoFileReader::currentToRead()
+{
+    return mMaxOffset - mOffset;
+}
+
+bool
+ProtoFileReader::hasNext()
+{
+    return ensure_data();
+}
+
+uint8_t
+ProtoFileReader::next()
+{
+    if (!ensure_data()) {
+        // Shouldn't get to here.  Always call hasNext() before calling next().
+        return 0;
+    }
+    return mBuffer[mOffset++];
+}
+
+uint64_t
+ProtoFileReader::readRawVarint()
+{
+    uint64_t val = 0, shift = 0;
+    while (true) {
+        if (!hasNext()) {
+            ALOGW("readRawVarint() called without hasNext() called first.");
+            mStatus = NOT_ENOUGH_DATA;
+            return 0;
+        }
+        uint8_t byte = next();
+        val |= (INT64_C(0x7F) & byte) << shift;
+        if ((byte & 0x80) == 0) break;
+        shift += 7;
+    }
+    return val;
+}
+
+void
+ProtoFileReader::move(size_t amt)
+{
+    while (mStatus == NO_ERROR && amt > 0) {
+        if (!ensure_data()) {
+            return;
+        }
+        const size_t chunk = mMaxOffset - mOffset < amt ? amt : mMaxOffset - mOffset;
+        mOffset += chunk;
+        amt -= chunk;
+    }
+}
+
+status_t
+ProtoFileReader::getError() const {
+    return mStatus;
+}
+
+bool
+ProtoFileReader::ensure_data() {
+    if (mStatus != NO_ERROR) {
+        return false;
+    }
+    if (mOffset < mMaxOffset) {
+        return true;
+    }
+    ssize_t amt = TEMP_FAILURE_RETRY(read(mFd, mBuffer, mChunkSize));
+    if (amt == 0) {
+        return false;
+    } else if (amt < 0) {
+        mStatus = -errno;
+        return false;
+    } else {
+        mOffset = 0;
+        mMaxOffset = amt;
+        return true;
+    }
+}
+
+
+} // util
+} // android
+
diff --git a/libs/protoutil/src/ProtoOutputStream.cpp b/libs/protoutil/src/ProtoOutputStream.cpp
index ff3fad6..ccbb83b 100644
--- a/libs/protoutil/src/ProtoOutputStream.cpp
+++ b/libs/protoutil/src/ProtoOutputStream.cpp
@@ -27,7 +27,7 @@
 namespace util {
 
 ProtoOutputStream::ProtoOutputStream()
-        :mBuffer(),
+        :mBuffer(new EncodedBuffer()),
          mCopyBegin(0),
          mCompact(false),
          mDepth(0),
@@ -44,7 +44,7 @@
 void
 ProtoOutputStream::clear()
 {
-    mBuffer.clear();
+    mBuffer->clear();
     mCopyBegin = 0;
     mCompact = false;
     mDepth = 0;
@@ -226,13 +226,13 @@
     }
 
     uint32_t id = (uint32_t)fieldId;
-    size_t prevPos = mBuffer.wp()->pos();
-    mBuffer.writeHeader(id, WIRE_TYPE_LENGTH_DELIMITED);
-    size_t sizePos = mBuffer.wp()->pos();
+    size_t prevPos = mBuffer->wp()->pos();
+    mBuffer->writeHeader(id, WIRE_TYPE_LENGTH_DELIMITED);
+    size_t sizePos = mBuffer->wp()->pos();
 
     mDepth++;
     mObjectId++;
-    mBuffer.writeRawFixed64(mExpectedObjectToken); // push previous token into stack.
+    mBuffer->writeRawFixed64(mExpectedObjectToken); // push previous token into stack.
 
     mExpectedObjectToken = makeToken(sizePos - prevPos,
         (bool)(fieldId & FIELD_COUNT_REPEATED), mDepth, mObjectId, sizePos);
@@ -258,26 +258,26 @@
 
     uint32_t sizePos = getSizePosFromToken(token);
     // number of bytes written in this start-end session.
-    int childRawSize = mBuffer.wp()->pos() - sizePos - 8;
+    int childRawSize = mBuffer->wp()->pos() - sizePos - 8;
 
     // retrieve the old token from stack.
-    mBuffer.ep()->rewind()->move(sizePos);
-    mExpectedObjectToken = mBuffer.readRawFixed64();
+    mBuffer->ep()->rewind()->move(sizePos);
+    mExpectedObjectToken = mBuffer->readRawFixed64();
 
     // If raw size is larger than 0, write the negative value here to indicate a compact is needed.
     if (childRawSize > 0) {
-        mBuffer.editRawFixed32(sizePos, -childRawSize);
-        mBuffer.editRawFixed32(sizePos+4, -1);
+        mBuffer->editRawFixed32(sizePos, -childRawSize);
+        mBuffer->editRawFixed32(sizePos+4, -1);
     } else {
         // reset wp which erase the header tag of the message when its size is 0.
-        mBuffer.wp()->rewind()->move(sizePos - getTagSizeFromToken(token));
+        mBuffer->wp()->rewind()->move(sizePos - getTagSizeFromToken(token));
     }
 }
 
 size_t
 ProtoOutputStream::bytesWritten()
 {
-    return mBuffer.size();
+    return mBuffer->size();
 }
 
 bool
@@ -288,26 +288,26 @@
         return false;
     }
     // record the size of the original buffer.
-    size_t rawBufferSize = mBuffer.size();
+    size_t rawBufferSize = mBuffer->size();
     if (rawBufferSize == 0) return true; // nothing to do if the buffer is empty;
 
     // reset edit pointer and recursively compute encoded size of messages.
-    mBuffer.ep()->rewind();
+    mBuffer->ep()->rewind();
     if (editEncodedSize(rawBufferSize) == 0) {
         ALOGE("Failed to editEncodedSize.");
         return false;
     }
 
     // reset both edit pointer and write pointer, and compact recursively.
-    mBuffer.ep()->rewind();
-    mBuffer.wp()->rewind();
+    mBuffer->ep()->rewind();
+    mBuffer->wp()->rewind();
     if (!compactSize(rawBufferSize)) {
         ALOGE("Failed to compactSize.");
         return false;
     }
     // copy the reset to the buffer.
     if (mCopyBegin < rawBufferSize) {
-        mBuffer.copy(mCopyBegin, rawBufferSize - mCopyBegin);
+        mBuffer->copy(mCopyBegin, rawBufferSize - mCopyBegin);
     }
 
     // mark true means it is not legal to write to this ProtoOutputStream anymore
@@ -322,34 +322,34 @@
 size_t
 ProtoOutputStream::editEncodedSize(size_t rawSize)
 {
-    size_t objectStart = mBuffer.ep()->pos();
+    size_t objectStart = mBuffer->ep()->pos();
     size_t objectEnd = objectStart + rawSize;
     size_t encodedSize = 0;
     int childRawSize, childEncodedSize;
     size_t childEncodedSizePos;
 
-    while (mBuffer.ep()->pos() < objectEnd) {
-        uint32_t tag = (uint32_t)mBuffer.readRawVarint();
+    while (mBuffer->ep()->pos() < objectEnd) {
+        uint32_t tag = (uint32_t)mBuffer->readRawVarint();
         encodedSize += get_varint_size(tag);
         switch (read_wire_type(tag)) {
             case WIRE_TYPE_VARINT:
                 do {
                     encodedSize++;
-                } while ((mBuffer.readRawByte() & 0x80) != 0);
+                } while ((mBuffer->readRawByte() & 0x80) != 0);
                 break;
             case WIRE_TYPE_FIXED64:
                 encodedSize += 8;
-                mBuffer.ep()->move(8);
+                mBuffer->ep()->move(8);
                 break;
             case WIRE_TYPE_LENGTH_DELIMITED:
-                childRawSize = (int)mBuffer.readRawFixed32();
-                childEncodedSizePos = mBuffer.ep()->pos();
-                childEncodedSize = (int)mBuffer.readRawFixed32();
+                childRawSize = (int)mBuffer->readRawFixed32();
+                childEncodedSizePos = mBuffer->ep()->pos();
+                childEncodedSize = (int)mBuffer->readRawFixed32();
                 if (childRawSize >= 0 && childRawSize == childEncodedSize) {
-                    mBuffer.ep()->move(childRawSize);
+                    mBuffer->ep()->move(childRawSize);
                 } else if (childRawSize < 0 && childEncodedSize == -1){
                     childEncodedSize = editEncodedSize(-childRawSize);
-                    mBuffer.editRawFixed32(childEncodedSizePos, childEncodedSize);
+                    mBuffer->editRawFixed32(childEncodedSizePos, childEncodedSize);
                 } else {
                     ALOGE("Bad raw or encoded values: raw=%d, encoded=%d at %zu",
                             childRawSize, childEncodedSize, childEncodedSizePos);
@@ -359,7 +359,7 @@
                 break;
             case WIRE_TYPE_FIXED32:
                 encodedSize += 4;
-                mBuffer.ep()->move(4);
+                mBuffer->ep()->move(4);
                 break;
             default:
                 ALOGE("Unexpected wire type %d in editEncodedSize at [%zu, %zu]",
@@ -378,30 +378,30 @@
 bool
 ProtoOutputStream::compactSize(size_t rawSize)
 {
-    size_t objectStart = mBuffer.ep()->pos();
+    size_t objectStart = mBuffer->ep()->pos();
     size_t objectEnd = objectStart + rawSize;
     int childRawSize, childEncodedSize;
 
-    while (mBuffer.ep()->pos() < objectEnd) {
-        uint32_t tag = (uint32_t)mBuffer.readRawVarint();
+    while (mBuffer->ep()->pos() < objectEnd) {
+        uint32_t tag = (uint32_t)mBuffer->readRawVarint();
         switch (read_wire_type(tag)) {
             case WIRE_TYPE_VARINT:
-                while ((mBuffer.readRawByte() & 0x80) != 0) {}
+                while ((mBuffer->readRawByte() & 0x80) != 0) {}
                 break;
             case WIRE_TYPE_FIXED64:
-                mBuffer.ep()->move(8);
+                mBuffer->ep()->move(8);
                 break;
             case WIRE_TYPE_LENGTH_DELIMITED:
-                mBuffer.copy(mCopyBegin, mBuffer.ep()->pos() - mCopyBegin);
+                mBuffer->copy(mCopyBegin, mBuffer->ep()->pos() - mCopyBegin);
 
-                childRawSize = (int)mBuffer.readRawFixed32();
-                childEncodedSize = (int)mBuffer.readRawFixed32();
-                mCopyBegin = mBuffer.ep()->pos();
+                childRawSize = (int)mBuffer->readRawFixed32();
+                childEncodedSize = (int)mBuffer->readRawFixed32();
+                mCopyBegin = mBuffer->ep()->pos();
 
                 // write encoded size to buffer.
-                mBuffer.writeRawVarint32(childEncodedSize);
+                mBuffer->writeRawVarint32(childEncodedSize);
                 if (childRawSize >= 0 && childRawSize == childEncodedSize) {
-                    mBuffer.ep()->move(childEncodedSize);
+                    mBuffer->ep()->move(childEncodedSize);
                 } else if (childRawSize < 0){
                     if (!compactSize(-childRawSize)) return false;
                 } else {
@@ -411,7 +411,7 @@
                 }
                 break;
             case WIRE_TYPE_FIXED32:
-                mBuffer.ep()->move(4);
+                mBuffer->ep()->move(4);
                 break;
             default:
                 ALOGE("Unexpected wire type %d in compactSize at [%zu, %zu]",
@@ -429,7 +429,7 @@
         ALOGE("compact failed, the ProtoOutputStream data is corrupted!");
         return 0;
     }
-    return mBuffer.size();
+    return mBuffer->size();
 }
 
 bool
@@ -438,43 +438,45 @@
     if (fd < 0) return false;
     if (!compact()) return false;
 
-    EncodedBuffer::iterator it = mBuffer.begin();
-    while (it.readBuffer() != NULL) {
-        if (!android::base::WriteFully(fd, it.readBuffer(), it.currentToRead())) return false;
-        it.rp()->move(it.currentToRead());
+    sp<ProtoReader> reader = mBuffer->read();
+    while (reader->readBuffer() != NULL) {
+        if (!android::base::WriteFully(fd, reader->readBuffer(), reader->currentToRead())) {
+            return false;
+        }
+        reader->move(reader->currentToRead());
     }
     return true;
 }
 
-EncodedBuffer::iterator
+sp<ProtoReader>
 ProtoOutputStream::data()
 {
     if (!compact()) {
         ALOGE("compact failed, the ProtoOutputStream data is corrupted!");
-        mBuffer.clear();
+        mBuffer->clear();
     }
-    return mBuffer.begin();
+    return mBuffer->read();
 }
 
 void
 ProtoOutputStream::writeRawVarint(uint64_t varint)
 {
-    mBuffer.writeRawVarint64(varint);
+    mBuffer->writeRawVarint64(varint);
 }
 
 void
 ProtoOutputStream::writeLengthDelimitedHeader(uint32_t id, size_t size)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_LENGTH_DELIMITED);
+    mBuffer->writeHeader(id, WIRE_TYPE_LENGTH_DELIMITED);
     // reserves 64 bits for length delimited fields, if first field is negative, compact it.
-    mBuffer.writeRawFixed32(size);
-    mBuffer.writeRawFixed32(size);
+    mBuffer->writeRawFixed32(size);
+    mBuffer->writeRawFixed32(size);
 }
 
 void
 ProtoOutputStream::writeRawByte(uint8_t byte)
 {
-    mBuffer.writeRawByte(byte);
+    mBuffer->writeRawByte(byte);
 }
 
 
@@ -494,99 +496,99 @@
 inline void
 ProtoOutputStream::writeDoubleImpl(uint32_t id, double val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
-    mBuffer.writeRawFixed64(bit_cast<double, uint64_t>(val));
+    mBuffer->writeHeader(id, WIRE_TYPE_FIXED64);
+    mBuffer->writeRawFixed64(bit_cast<double, uint64_t>(val));
 }
 
 inline void
 ProtoOutputStream::writeFloatImpl(uint32_t id, float val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
-    mBuffer.writeRawFixed32(bit_cast<float, uint32_t>(val));
+    mBuffer->writeHeader(id, WIRE_TYPE_FIXED32);
+    mBuffer->writeRawFixed32(bit_cast<float, uint32_t>(val));
 }
 
 inline void
 ProtoOutputStream::writeInt64Impl(uint32_t id, int64_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint64(val);
+    mBuffer->writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer->writeRawVarint64(val);
 }
 
 inline void
 ProtoOutputStream::writeInt32Impl(uint32_t id, int32_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint32(val);
+    mBuffer->writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer->writeRawVarint32(val);
 }
 
 inline void
 ProtoOutputStream::writeUint64Impl(uint32_t id, uint64_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint64(val);
+    mBuffer->writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer->writeRawVarint64(val);
 }
 
 inline void
 ProtoOutputStream::writeUint32Impl(uint32_t id, uint32_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint32(val);
+    mBuffer->writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer->writeRawVarint32(val);
 }
 
 inline void
 ProtoOutputStream::writeFixed64Impl(uint32_t id, uint64_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
-    mBuffer.writeRawFixed64(val);
+    mBuffer->writeHeader(id, WIRE_TYPE_FIXED64);
+    mBuffer->writeRawFixed64(val);
 }
 
 inline void
 ProtoOutputStream::writeFixed32Impl(uint32_t id, uint32_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
-    mBuffer.writeRawFixed32(val);
+    mBuffer->writeHeader(id, WIRE_TYPE_FIXED32);
+    mBuffer->writeRawFixed32(val);
 }
 
 inline void
 ProtoOutputStream::writeSFixed64Impl(uint32_t id, int64_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
-    mBuffer.writeRawFixed64(val);
+    mBuffer->writeHeader(id, WIRE_TYPE_FIXED64);
+    mBuffer->writeRawFixed64(val);
 }
 
 inline void
 ProtoOutputStream::writeSFixed32Impl(uint32_t id, int32_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
-    mBuffer.writeRawFixed32(val);
+    mBuffer->writeHeader(id, WIRE_TYPE_FIXED32);
+    mBuffer->writeRawFixed32(val);
 }
 
 inline void
 ProtoOutputStream::writeZigzagInt64Impl(uint32_t id, int64_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint64((val << 1) ^ (val >> 63));
+    mBuffer->writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer->writeRawVarint64((val << 1) ^ (val >> 63));
 }
 
 inline void
 ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int32_t val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint32((val << 1) ^ (val >> 31));
+    mBuffer->writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer->writeRawVarint32((val << 1) ^ (val >> 31));
 }
 
 inline void
 ProtoOutputStream::writeEnumImpl(uint32_t id, int val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint32((uint32_t) val);
+    mBuffer->writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer->writeRawVarint32((uint32_t) val);
 }
 
 inline void
 ProtoOutputStream::writeBoolImpl(uint32_t id, bool val)
 {
-    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
-    mBuffer.writeRawVarint32(val ? 1 : 0);
+    mBuffer->writeHeader(id, WIRE_TYPE_VARINT);
+    mBuffer->writeRawVarint32(val ? 1 : 0);
 }
 
 inline void
@@ -595,7 +597,7 @@
     if (val == NULL) return;
     writeLengthDelimitedHeader(id, size);
     for (size_t i=0; i<size; i++) {
-        mBuffer.writeRawByte((uint8_t)val[i]);
+        mBuffer->writeRawByte((uint8_t)val[i]);
     }
 }
 
@@ -605,7 +607,7 @@
     if (val == NULL) return;
     writeLengthDelimitedHeader(id, size);
     for (size_t i=0; i<size; i++) {
-        mBuffer.writeRawByte(val[i]);
+        mBuffer->writeRawByte(val[i]);
     }
 }
 
diff --git a/cmds/statsd/src/logd/LogListener.cpp b/libs/protoutil/src/ProtoReader.cpp
similarity index 76%
rename from cmds/statsd/src/logd/LogListener.cpp
rename to libs/protoutil/src/ProtoReader.cpp
index ddb26f9..4f2a9f1 100644
--- a/cmds/statsd/src/logd/LogListener.cpp
+++ b/libs/protoutil/src/ProtoReader.cpp
@@ -13,19 +13,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define LOG_TAG "libprotoutil"
 
-#include "logd/LogListener.h"
+#include <android/util/ProtoReader.h>
 
 namespace android {
-namespace os {
-namespace statsd {
+namespace util {
 
-LogListener::LogListener() {
+ProtoReader::ProtoReader() {
 }
 
-LogListener::~LogListener() {
+ProtoReader::~ProtoReader() {
 }
 
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
+} // util
+} // android
diff --git a/libs/protoutil/tests/EncodedBuffer_test.cpp b/libs/protoutil/tests/EncodedBuffer_test.cpp
index 964fc8e..398af60 100644
--- a/libs/protoutil/tests/EncodedBuffer_test.cpp
+++ b/libs/protoutil/tests/EncodedBuffer_test.cpp
@@ -16,6 +16,7 @@
 #include <gtest/gtest.h>
 
 using namespace android::util;
+using android::sp;
 
 constexpr size_t TEST_CHUNK_SIZE = 16UL;
 constexpr size_t TEST_CHUNK_HALF_SIZE = TEST_CHUNK_SIZE / 2;
@@ -122,33 +123,30 @@
     for (size_t i = 0; i < TEST_CHUNK_3X_SIZE; i++) {
         buffer.writeRawByte(i);
     }
-    auto iter = buffer.begin();
-    EXPECT_EQ(iter.size(), TEST_CHUNK_3X_SIZE);
-    EXPECT_EQ(iter.bytesRead(), 0);
+    sp<ProtoReader> reader1 = buffer.read();
+    EXPECT_EQ(reader1->size(), TEST_CHUNK_3X_SIZE);
+    EXPECT_EQ(reader1->bytesRead(), 0);
 
-    expectPointer(iter.rp(), 0);
-    while (iter.readBuffer() != NULL) {
-        iter.rp()->move(iter.currentToRead());
+    while (reader1->readBuffer() != NULL) {
+        reader1->move(reader1->currentToRead());
     }
-    EXPECT_EQ(iter.bytesRead(), TEST_CHUNK_3X_SIZE);
-    expectPointer(iter.rp(), TEST_CHUNK_3X_SIZE);
+    EXPECT_EQ(reader1->bytesRead(), TEST_CHUNK_3X_SIZE);
 
-    iter.rp()->rewind();
-    expectPointer(iter.rp(), 0);
+    sp<ProtoReader> reader2 = buffer.read();
     uint8_t val = 0;
-    while (iter.hasNext()) {
-        EXPECT_EQ(iter.next(), val);
+    while (reader2->hasNext()) {
+        EXPECT_EQ(reader2->next(), val);
         val++;
     }
-    EXPECT_EQ(iter.bytesRead(), TEST_CHUNK_3X_SIZE);
-    expectPointer(iter.rp(), TEST_CHUNK_3X_SIZE);
+    EXPECT_EQ(reader2->bytesRead(), TEST_CHUNK_3X_SIZE);
+    EXPECT_EQ(reader1->bytesRead(), TEST_CHUNK_3X_SIZE);
 }
 
 TEST(EncodedBufferTest, ReadVarint) {
     EncodedBuffer buffer;
     uint64_t val = UINT64_C(1522865904593);
     size_t len = buffer.writeRawVarint64(val);
-    auto iter = buffer.begin();
-    EXPECT_EQ(iter.size(), len);
-    EXPECT_EQ(iter.readRawVarint(), val);
+    sp<ProtoReader> reader = buffer.read();
+    EXPECT_EQ(reader->size(), len);
+    EXPECT_EQ(reader->readRawVarint(), val);
 }
diff --git a/libs/protoutil/tests/ProtoOutputStream_test.cpp b/libs/protoutil/tests/ProtoOutputStream_test.cpp
index 27ee13d..9d357f3 100644
--- a/libs/protoutil/tests/ProtoOutputStream_test.cpp
+++ b/libs/protoutil/tests/ProtoOutputStream_test.cpp
@@ -21,6 +21,7 @@
 
 #include "frameworks/base/libs/protoutil/tests/test.pb.h"
 
+using android::sp;
 using namespace android::base;
 using namespace android::util;
 using ::testing::StrEq;
@@ -38,9 +39,9 @@
 static std::string iterateToString(ProtoOutputStream* proto) {
     std::string content;
     content.reserve(proto->size());
-    auto iter = proto->data();
-    while (iter.hasNext()) {
-        content.push_back(iter.next());
+    sp<ProtoReader> reader = proto->data();
+    while (reader->hasNext()) {
+        content.push_back(reader->next());
     }
     return content;
 }
@@ -198,7 +199,6 @@
     // no proto.end called
     EXPECT_NE(proto.bytesWritten(), 0);
     EXPECT_EQ(proto.size(), 0);
-    EXPECT_EQ(proto.data().size(), 0);
     EXPECT_FALSE(proto.flush(STDOUT_FILENO));
 }
 
@@ -211,7 +211,6 @@
     proto.end(token);
     EXPECT_NE(proto.bytesWritten(), 0);
     EXPECT_EQ(proto.size(), 0);
-    EXPECT_EQ(proto.data().size(), 0);
     EXPECT_FALSE(proto.flush(STDOUT_FILENO));
 }
 
@@ -223,6 +222,5 @@
     proto.end(wrongToken);
     EXPECT_NE(proto.bytesWritten(), 0);
     EXPECT_EQ(proto.size(), 0);
-    EXPECT_EQ(proto.data().size(), 0);
     EXPECT_FALSE(proto.flush(STDOUT_FILENO));
 }
diff --git a/libs/services/Android.bp b/libs/services/Android.bp
index 3d57fbd..1b9939d 100644
--- a/libs/services/Android.bp
+++ b/libs/services/Android.bp
@@ -18,6 +18,7 @@
     name: "libservices",
     srcs: [
         ":IDropBoxManagerService.aidl",
+        "src/content/ComponentName.cpp",
         "src/os/DropBoxManager.cpp",
         "src/os/StatsDimensionsValue.cpp",
         "src/os/StatsLogEventWrapper.cpp",
diff --git a/libs/services/include/android/content/ComponentName.h b/libs/services/include/android/content/ComponentName.h
new file mode 100644
index 0000000..6bf46b4
--- /dev/null
+++ b/libs/services/include/android/content/ComponentName.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+#include <binder/Status.h>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace content {
+
+using namespace std;
+
+class ComponentName: public android::Parcelable {
+    public:
+    ComponentName();
+    ComponentName(const ComponentName& that);
+    ComponentName(const string& pkg, const string& cls);
+    virtual ~ComponentName();
+
+    bool operator<(const ComponentName& that) const;
+
+    const string& getPackageName() const { return mPackage; }
+    const string& getClassName() const { return mClass; }
+
+    virtual android::status_t writeToParcel(android::Parcel* out) const override;
+    virtual android::status_t readFromParcel(const android::Parcel* in) override;
+    
+private:
+    string mPackage;
+    string mClass;
+};
+
+
+
+}  // namespace os
+}  // namespace android
+
+        
+
diff --git a/libs/services/src/content/ComponentName.cpp b/libs/services/src/content/ComponentName.cpp
new file mode 100644
index 0000000..adb67ee
--- /dev/null
+++ b/libs/services/src/content/ComponentName.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/content/ComponentName.h>
+
+namespace android {
+namespace content {
+
+ComponentName::ComponentName()
+        :mPackage(),
+         mClass() {
+}
+
+ComponentName::ComponentName(const ComponentName& that)
+        :mPackage(that.mPackage),
+         mClass(that.mClass) {
+}
+
+ComponentName::ComponentName(const string& pkg, const string& cls)
+        :mPackage(pkg),
+         mClass(cls) {
+}
+
+ComponentName::~ComponentName() {
+}
+
+bool ComponentName::operator<(const ComponentName& that) const {
+    if (mPackage < that.mPackage) {
+       return true;
+    } else if (mPackage > that.mPackage) {
+       return false;
+    }
+    return mClass < that.mClass;
+}
+
+status_t ComponentName::readFromParcel(const Parcel* in) {
+    status_t err;
+
+    // Note: This is a subtle variation from the java version, which
+    // requires non-null strings, but does not require non-empty strings.
+    // This code implicitly requires non-null strings, because it's impossible,
+    // but reading null strings that were somehow written by the java
+    // code would turn them into empty strings.
+
+    err = in->readUtf8FromUtf16(&mPackage);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    err = in->readUtf8FromUtf16(&mClass);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    return NO_ERROR;
+}
+
+status_t ComponentName::writeToParcel(android::Parcel* out) const {
+    status_t err;
+
+    err = out->writeUtf8AsUtf16(mPackage);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    err = out->writeUtf8AsUtf16(mClass);
+    if (err != NO_ERROR) {
+        return err;
+    }
+
+    return NO_ERROR;
+}
+
+}} // namespace android::content
+
diff --git a/libs/services/src/os/DropBoxManager.cpp b/libs/services/src/os/DropBoxManager.cpp
index 681d5f7..429f996 100644
--- a/libs/services/src/os/DropBoxManager.cpp
+++ b/libs/services/src/os/DropBoxManager.cpp
@@ -225,7 +225,10 @@
     if (service == NULL) {
         return Status::fromExceptionCode(Status::EX_NULL_POINTER, "can't find dropbox service");
     }
-    return service->add(entry);
+    ALOGD("About to call service->add()");
+    Status status = service->add(entry);
+    ALOGD("service->add returned %s", status.toString8().string());
+    return status;
 }
 
 }} // namespace android::os
diff --git a/location/Android.mk b/location/Android.mk
deleted file mode 100644
index 50509c6..0000000
--- a/location/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(call all-subdir-makefiles, $(LOCAL_PATH))
\ No newline at end of file
diff --git a/location/java/android/location/GnssCapabilities.java b/location/java/android/location/GnssCapabilities.java
index 6a35920..badffd1 100644
--- a/location/java/android/location/GnssCapabilities.java
+++ b/location/java/android/location/GnssCapabilities.java
@@ -77,15 +77,14 @@
     })
     public @interface Capability {}
 
-    /**
-     * @hide
-     */
+    /** @hide */
     public static final long INVALID_CAPABILITIES = -1;
 
     /** A bitmask of supported GNSS capabilities. */
     private final long mGnssCapabilities;
 
-    static GnssCapabilities of(long gnssCapabilities) {
+    /** @hide */
+    public static GnssCapabilities of(long gnssCapabilities) {
         return new GnssCapabilities(gnssCapabilities);
     }
 
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 93dc6fa..97bc404 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -93,10 +93,10 @@
     ProviderProperties getProviderProperties(String provider);
     boolean isProviderPackage(String packageName);
 
-    void setLocationControllerExtraPackage(String packageName);
-    String getLocationControllerExtraPackage();
-    void setLocationControllerExtraPackageEnabled(boolean enabled);
-    boolean isLocationControllerExtraPackageEnabled();
+    void setExtraLocationControllerPackage(String packageName);
+    String getExtraLocationControllerPackage();
+    void setExtraLocationControllerPackageEnabled(boolean enabled);
+    boolean isExtraLocationControllerPackageEnabled();
 
     boolean isProviderEnabledForUser(String provider, int userId);
     boolean isLocationEnabledForUser(int userId);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index edf304c..af60e3c 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -2328,9 +2328,27 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
-    public void setLocationControllerExtraPackage(@NonNull String packageName) {
+    public void setExtraLocationControllerPackage(@Nullable String packageName) {
         try {
-            mService.setLocationControllerExtraPackage(packageName);
+            mService.setExtraLocationControllerPackage(packageName);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set the extra location controller package for location services on the device.
+     *
+     * @removed
+     * @deprecated Use {@link #setExtraLocationControllerPackage} instead.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public void setLocationControllerExtraPackage(String packageName) {
+        try {
+            mService.setExtraLocationControllerPackage(packageName);
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
@@ -2342,9 +2360,9 @@
      * @hide
      */
     @SystemApi
-    public @Nullable String getLocationControllerExtraPackage() {
+    public @Nullable String getExtraLocationControllerPackage() {
         try {
-            return mService.getLocationControllerExtraPackage();
+            return mService.getExtraLocationControllerPackage();
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
             return null;
@@ -2354,13 +2372,31 @@
     /**
      * Set whether the extra location controller package is currently enabled on the device.
      *
+     * @removed
+     * @deprecated Use {@link #setExtraLocationControllerPackageEnabled} instead.
+     * @hide
+     */
+    @SystemApi
+    @Deprecated
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public void setLocationControllerExtraPackageEnabled(boolean enabled) {
+        try {
+            mService.setExtraLocationControllerPackageEnabled(enabled);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set whether the extra location controller package is currently enabled on the device.
+     *
      * @hide
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
-    public void setLocationControllerExtraPackageEnabled(boolean enabled) {
+    public void setExtraLocationControllerPackageEnabled(boolean enabled) {
         try {
-            mService.setLocationControllerExtraPackageEnabled(enabled);
+            mService.setExtraLocationControllerPackageEnabled(enabled);
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
@@ -2372,9 +2408,9 @@
      * @hide
      */
     @SystemApi
-    public boolean isLocationControllerExtraPackageEnabled() {
+    public boolean isExtraLocationControllerPackageEnabled() {
         try {
-            return mService.isLocationControllerExtraPackageEnabled();
+            return mService.isExtraLocationControllerPackageEnabled();
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
             return false;
diff --git a/location/tests/Android.bp b/location/tests/Android.bp
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/location/tests/Android.bp
@@ -0,0 +1 @@
+
diff --git a/location/tests/Android.mk b/location/tests/Android.mk
deleted file mode 100644
index 57848f3..0000000
--- a/location/tests/Android.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
\ No newline at end of file
diff --git a/location/tests/locationtests/Android.bp b/location/tests/locationtests/Android.bp
new file mode 100644
index 0000000..1a4e2c7
--- /dev/null
+++ b/location/tests/locationtests/Android.bp
@@ -0,0 +1,19 @@
+android_test {
+    name: "FrameworksLocationTests",
+    // Include all test java files.
+    srcs: ["src/**/*.java"],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+    platform_apis: true,
+    static_libs: [
+        "androidx.test.rules",
+        "core-test-rules",
+        "guava",
+        "mockito-target-minus-junit4",
+        "frameworks-base-testutils",
+        "truth-prebuilt",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/location/tests/locationtests/Android.mk b/location/tests/locationtests/Android.mk
deleted file mode 100644
index 3dcf694..0000000
--- a/location/tests/locationtests/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
-LOCAL_PACKAGE_NAME := FrameworksLocationTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.test.rules \
-    core-test-rules \
-    guava \
-    mockito-target-minus-junit4 \
-    frameworks-base-testutils \
-    truth-prebuilt \
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-include $(BUILD_PACKAGE)
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
index 19bb258..87035da 100644
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ b/media/apex/java/android/media/MediaPlayer2.java
@@ -1546,7 +1546,7 @@
      * Returns the size of the video.
      *
      * @return the size of the video. The width and height of size could be 0 if there is no video,
-     * no display surface was set, or the size has not been determined yet.
+     * or the size has not been determined yet.
      * The {@code EventCallback} can be registered via
      * {@link #registerEventCallback(Executor, EventCallback)} to provide a
      * notification {@code EventCallback.onVideoSizeChanged} when the size
@@ -2870,7 +2870,7 @@
          * Called to indicate the video size
          *
          * The video size (width and height) could be 0 if there was no video,
-         * no display surface was set, or the value was not determined yet.
+         * or the value was not determined yet.
          *
          * @param mp the MediaPlayer2 associated with this callback
          * @param dsd the DataSourceDesc of this data source
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index c2f29bc..55f1911 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
+import android.media.audiopolicy.AudioProductStrategies;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -370,9 +371,10 @@
 
     /**
      * @hide
-     * Flag specifying that the audio shall not be captured by other apps.
+     * Flag specifying that the audio shall not be captured by third-party apps
+     * with a MediaProjection.
      */
-    public static final int FLAG_NO_CAPTURE = 0x1 << 10;
+    public static final int FLAG_NO_MEDIA_PROJECTION = 0x1 << 10;
 
     /**
      * @hide
@@ -380,12 +382,64 @@
      */
     public static final int FLAG_MUTE_HAPTIC = 0x1 << 11;
 
-    private final static int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO |
-            FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY |
-            FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER | FLAG_MUTE_HAPTIC;
+    /**
+     * @hide
+     * Flag specifying that the audio shall not be captured by any apps, not even system apps.
+     */
+    public static final int FLAG_NO_SYSTEM_CAPTURE = 0x1 << 12;
+
+    private static final int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO
+            | FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY
+            | FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER | FLAG_NO_MEDIA_PROJECTION
+            | FLAG_MUTE_HAPTIC | FLAG_NO_SYSTEM_CAPTURE;
     private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED |
             FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY;
 
+    /**
+     * Indicates that the audio may be captured by any app.
+     *
+     * For privacy, the following usages can not be recorded: VOICE_COMMUNICATION*,
+     * USAGE_NOTIFICATION*, USAGE_ASSISTANCE* and USAGE_ASSISTANT.
+     *
+     * On {@link android.os.Build.VERSION_CODES#Q}, this means only {@link #USAGE_UNKNOWN},
+     * {@link #USAGE_MEDIA} and {@link #USAGE_GAME} may be captured.
+     *
+     * See {@link android.media.projection.MediaProjection} and
+     * {@link Builder#setAllowedCapturePolicy}.
+     */
+    public static final int ALLOW_CAPTURE_BY_ALL = 1;
+    /**
+     * Indicates that the audio may only be captured by system apps.
+     *
+     * System apps can capture for many purposes like accessibility, user guidance...
+     * but abide to the following restrictions:
+     *  - the audio can not leave the device
+     *  - the audio can not be passed to a third party app
+     *  - the audio can not be recorded at a higher quality then 16kHz 16bit mono
+     *
+     * See {@link Builder#setAllowedCapturePolicy}.
+     */
+    public static final int ALLOW_CAPTURE_BY_SYSTEM = 2;
+    /**
+     * Indicates that the audio is not to be recorded by any app, even if it is a system app.
+     *
+     * It is encouraged to use {@link #ALLOW_CAPTURE_BY_SYSTEM} instead of this value as system apps
+     * provide significant and useful features for the user (such as live captioning
+     * and accessibility).
+     *
+     * See {@link Builder#setAllowedCapturePolicy}.
+     */
+    public static final int ALLOW_CAPTURE_BY_NONE = 3;
+
+    /** @hide */
+    @IntDef({
+        ALLOW_CAPTURE_BY_ALL,
+        ALLOW_CAPTURE_BY_SYSTEM,
+        ALLOW_CAPTURE_BY_NONE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CapturePolicy {}
+
     @UnsupportedAppUsage
     private int mUsage = USAGE_UNKNOWN;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -593,10 +647,10 @@
                 case USAGE_GAME:
                 case USAGE_VIRTUAL_SOURCE:
                 case USAGE_ASSISTANT:
-                     mUsage = usage;
-                     break;
+                    mUsage = usage;
+                    break;
                 default:
-                     mUsage = USAGE_UNKNOWN;
+                    mUsage = USAGE_UNKNOWN;
             }
             return this;
         }
@@ -642,18 +696,22 @@
         }
 
         /**
-         * Specifying if audio shall or shall not be captured by other apps.
-         * By default, capture is allowed.
-         * @param allowCapture false to forbid capture of the audio by any apps,
-         *                     true to allow apps to capture the audio
+         * Specifying if audio may or may not be captured by other apps or the system.
+         *
+         * The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
+         *
+         * Note that an application can also set its global policy, in which case the most
+         * restrictive policy is always applied.
+         *
+         * @param capturePolicy one of
+         *     {@link #ALLOW_CAPTURE_BY_ALL},
+         *     {@link #ALLOW_CAPTURE_BY_SYSTEM},
+         *     {@link #ALLOW_CAPTURE_BY_NONE}.
          * @return the same Builder instance
+         * @throws IllegalArgumentException if the argument is not a valid value.
          */
-        public @NonNull Builder setAllowCapture(boolean allowCapture) {
-            if (allowCapture) {
-                mFlags &= ~FLAG_NO_CAPTURE;
-            } else {
-                mFlags |= FLAG_NO_CAPTURE;
-            }
+        public @NonNull Builder setAllowedCapturePolicy(@CapturePolicy int capturePolicy) {
+            mFlags = capturePolicyToFlags(capturePolicy, mFlags);
             return this;
         }
 
@@ -725,6 +783,13 @@
          */
         @UnsupportedAppUsage
         public Builder setInternalLegacyStreamType(int streamType) {
+            final AudioProductStrategies ps = new AudioProductStrategies();
+            if (ps.size() > 0) {
+                AudioAttributes attributes = ps.getAudioAttributesForLegacyStreamType(streamType);
+                if (attributes != null) {
+                    return new Builder(attributes);
+                }
+            }
             switch(streamType) {
                 case AudioSystem.STREAM_VOICE_CALL:
                     mContentType = CONTENT_TYPE_SPEECH;
@@ -1100,6 +1165,10 @@
                     AudioSystem.STREAM_MUSIC : AudioSystem.STREAM_TTS;
         }
 
+        final AudioProductStrategies ps = new AudioProductStrategies();
+        if (ps.size() > 0) {
+            return ps.getLegacyStreamTypeForAudioAttributes(aa);
+        }
         // usage to stream type mapping
         switch (aa.getUsage()) {
             case USAGE_MEDIA:
@@ -1138,6 +1207,24 @@
         }
     }
 
+    static int capturePolicyToFlags(@CapturePolicy int capturePolicy, int flags) {
+        switch (capturePolicy) {
+            case ALLOW_CAPTURE_BY_NONE:
+                flags |= FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE;
+                break;
+            case ALLOW_CAPTURE_BY_SYSTEM:
+                flags |= FLAG_NO_MEDIA_PROJECTION;
+                flags &= ~FLAG_NO_SYSTEM_CAPTURE;
+                break;
+            case ALLOW_CAPTURE_BY_ALL:
+                flags &= ~FLAG_NO_SYSTEM_CAPTURE & ~FLAG_NO_MEDIA_PROJECTION;
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown allow playback capture policy");
+        }
+        return flags;
+    }
+
     /** @hide */
     @IntDef({
         USAGE_UNKNOWN,
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 7cb5e00..dc5c663 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1478,6 +1478,30 @@
         }
      }
 
+    /**
+     * Specifying if this audio may or may not be captured by other apps or the system.
+     *
+     * The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
+     *
+     * Note that each audio track can also set its policy, in which case the most
+     * restrictive policy is always applied.
+     *
+     * @param capturePolicy one of
+     *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
+     *     {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
+     *     {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
+     * @throws IllegalArgumentException if the argument is not a valid value.
+     */
+    public void setAllowedCapturePolicy(@AudioAttributes.CapturePolicy int capturePolicy) {
+        int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
+        // TODO: got trough AudioService and save a cache to restore in case of AP crash
+        // TODO: also pass the package in case multiple packages have the same UID
+        int result = AudioSystem.setAllowedCapturePolicy(Process.myUid(), flags);
+        if (result != AudioSystem.AUDIO_STATUS_OK) {
+            Log.e(TAG, "Could not setAllowedCapturePolicy: " + result);
+        }
+    }
+
     //====================================================================
     // Offload query
     /**
diff --git a/media/java/android/media/AudioPlaybackCaptureConfiguration.java b/media/java/android/media/AudioPlaybackCaptureConfiguration.java
index 4aa0b90..bcaef03 100644
--- a/media/java/android/media/AudioPlaybackCaptureConfiguration.java
+++ b/media/java/android/media/AudioPlaybackCaptureConfiguration.java
@@ -28,14 +28,18 @@
 /**
  * Configuration for capturing audio played by other apps.
  *
- * For privacy and copyright reason, only the following audio can be captured:
- *  - usage MUST be UNKNOWN or GAME or MEDIA. All other usages CAN NOT be capturable.
- *  - audio attributes MUST NOT have the FLAG_NO_CAPTURE
+ * Only the following audio can be captured:
+ *  - usage MUST be {@link AudioAttributes#USAGE_UNKNOWN} or {@link AudioAttributes#USAGE_GAME}
+ *    or {@link AudioAttributes#USAGE_MEDIA}. All other usages CAN NOT be captured.
+ *  - audio attributes MUST have its ${@link AudioAttributes.Builder#setAllowedCapturePolicy}
+ *    to {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
  *  - played by apps that MUST be in the same user profile as the capturing app
  *    (eg work profile can not capture user profile apps and vice-versa).
- *  - played by apps that MUST NOT have in their manifest.xml the application
- *    attribute android:allowAudioPlaybackCapture="false"
- *  - played by apps that MUST have a targetSdkVersion higher or equal to 29 (Q).
+ *  - played by apps for which the attribute allowAudioPlaybackCapture in their manifest
+ *    MUST either be:
+ *      * set to "true"
+ *      * not set, and their targetSdkVersion MUST be equal or higher to
+ *        {@link android.os.Build.VERSION_CODES#Q}.
  *
  * <p>An example for creating a capture configuration for capturing all media playback:
  *
diff --git a/media/java/android/media/AudioPlaybackConfiguration.java b/media/java/android/media/AudioPlaybackConfiguration.java
index 5d12c3c..b2ebfa9 100644
--- a/media/java/android/media/AudioPlaybackConfiguration.java
+++ b/media/java/android/media/AudioPlaybackConfiguration.java
@@ -43,8 +43,6 @@
     /** @hide */
     public static final int PLAYER_PIID_INVALID = -1;
     /** @hide */
-    public static final int PLAYER_PIID_UNASSIGNED = 0;
-    /** @hide */
     public static final int PLAYER_UPID_INVALID = -1;
 
     // information about the implementation
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index a7760a80..2dd7f0f 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -25,6 +25,7 @@
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
+import android.media.MediaRecorder.Source;
 import android.media.audiopolicy.AudioMix;
 import android.media.audiopolicy.AudioPolicy;
 import android.media.projection.MediaProjection;
@@ -539,7 +540,7 @@
          * @return the same Builder instance.
          * @throws IllegalArgumentException
          */
-        public Builder setAudioSource(int source) throws IllegalArgumentException {
+        public Builder setAudioSource(@Source int source) throws IllegalArgumentException {
             Preconditions.checkState(
                     mAudioPlaybackCaptureConfiguration == null,
                     ERROR_MESSAGE_SOURCE_MISMATCH);
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index ad255fe..d105fa3 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1022,6 +1022,11 @@
 
     public static native float getStreamVolumeDB(int stream, int index, int device);
 
+    /**
+     * @see AudioManager#setAllowedCapturePolicy()
+     */
+    public static native int setAllowedCapturePolicy(int uid, int flags);
+
     static boolean isOffloadSupported(@NonNull AudioFormat format, @NonNull AudioAttributes attr) {
         return native_is_offload_supported(format.getEncoding(), format.getSampleRate(),
                 format.getChannelMask(), format.getChannelIndexMask(),
diff --git a/media/java/android/media/HwAudioSource.java b/media/java/android/media/HwAudioSource.java
index e53b7e8..01a02f1 100644
--- a/media/java/android/media/HwAudioSource.java
+++ b/media/java/android/media/HwAudioSource.java
@@ -224,14 +224,4 @@
             return new HwAudioSource(mAudioDeviceInfo, mAudioAttributes);
         }
     }
-
-    /**
-     * Eliminate {@link #deprecateStreamTypeForPlayback(int, String, String)} in API list.
-     * TODO: remove this pseudo-override function
-     * @hide
-     */
-    public static void deprecateStreamTypeForPlayback(int streamType, String className,
-            String opName) throws IllegalArgumentException {
-        // Do nothing.
-    }
 }
diff --git a/media/java/android/media/session/ControllerCallbackLink.aidl b/media/java/android/media/IMediaRoute2Callback.aidl
similarity index 81%
copy from media/java/android/media/session/ControllerCallbackLink.aidl
copy to media/java/android/media/IMediaRoute2Callback.aidl
index 8ee8c7d..f03c8ab 100644
--- a/media/java/android/media/session/ControllerCallbackLink.aidl
+++ b/media/java/android/media/IMediaRoute2Callback.aidl
@@ -13,6 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.media.session;
 
-parcelable ControllerCallbackLink;
+package android.media;
+
+/**
+ * @hide
+ */
+oneway interface IMediaRoute2Callback {
+    void onRouteSelected(int uid, String routeId);
+}
diff --git a/media/java/android/media/session/ControllerCallbackLink.aidl b/media/java/android/media/IMediaRoute2Provider.aidl
similarity index 72%
copy from media/java/android/media/session/ControllerCallbackLink.aidl
copy to media/java/android/media/IMediaRoute2Provider.aidl
index 8ee8c7d..b97dcc5 100644
--- a/media/java/android/media/session/ControllerCallbackLink.aidl
+++ b/media/java/android/media/IMediaRoute2Provider.aidl
@@ -13,6 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.media.session;
 
-parcelable ControllerCallbackLink;
+package android.media;
+
+import android.media.IMediaRoute2Callback;
+
+/**
+ * {@hide}
+ */
+oneway interface IMediaRoute2Provider {
+    void setCallback(IMediaRoute2Callback callback);
+    void selectRoute(int uid, String id);
+}
diff --git a/media/java/android/media/session/ControllerCallbackLink.aidl b/media/java/android/media/IMediaRouter2ManagerClient.aidl
similarity index 73%
copy from media/java/android/media/session/ControllerCallbackLink.aidl
copy to media/java/android/media/IMediaRouter2ManagerClient.aidl
index 8ee8c7d..234551b 100644
--- a/media/java/android/media/session/ControllerCallbackLink.aidl
+++ b/media/java/android/media/IMediaRouter2ManagerClient.aidl
@@ -13,6 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.media.session;
 
-parcelable ControllerCallbackLink;
+package android.media;
+
+/**
+ * {@hide}
+ */
+oneway interface IMediaRouter2ManagerClient {
+    void onRouteSelected(int uid, String routeId);
+    void onControlCategoriesChanged(int uid, in List<String> categories);
+}
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 3308fc9..59f1d0d 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -17,6 +17,7 @@
 package android.media;
 
 import android.media.IMediaRouterClient;
+import android.media.IMediaRouter2ManagerClient;
 import android.media.MediaRouterClientState;
 
 /**
@@ -29,8 +30,15 @@
     MediaRouterClientState getState(IMediaRouterClient client);
     boolean isPlaybackActive(IMediaRouterClient client);
 
+    void setControlCategories(IMediaRouterClient client, in List<String> categories);
     void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan);
     void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
     void requestSetVolume(IMediaRouterClient client, String routeId, int volume);
     void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction);
+
+    void registerManagerAsUser(IMediaRouter2ManagerClient callback,
+            String packageName, int userId);
+    void unregisterManager(IMediaRouter2ManagerClient callback);
+    void setRemoteRoute(IMediaRouter2ManagerClient callback,
+            int uid, String routeId, boolean explicit);
 }
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index a22c8d0..4d63cc8 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -1060,7 +1060,7 @@
      * that no B frames are allowed. Note that non-zero value does not guarantee
      * B frames; it's up to the encoder to decide.
      */
-    public static final String KEY_MAX_BFRAMES = "max-bframes";
+    public static final String KEY_MAX_B_FRAMES = "max-bframes";
 
     /* package private */ MediaFormat(@NonNull Map<String, Object> map) {
         mMap = map;
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 040152a..1937edd 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1103,7 +1103,7 @@
             setDataSource(afd);
             return true;
         } catch (NullPointerException | SecurityException | IOException ex) {
-            Log.w(TAG, "Couldn't open " + uri == null ? "null uri" : uri.toSafeString(), ex);
+            Log.w(TAG, "Couldn't open " + (uri == null ? "null uri" : uri.toSafeString()), ex);
             return false;
         }
     }
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 575a0bb..63b22df 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -18,6 +18,7 @@
 
 import android.annotation.CallbackExecutor;
 import android.annotation.FloatRange;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -42,6 +43,8 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.RandomAccessFile;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.List;
@@ -355,6 +358,22 @@
         public static final int HOTWORD = 1999;
     }
 
+    /** @hide */
+    @IntDef({
+        AudioSource.DEFAULT,
+        AudioSource.MIC,
+        AudioSource.VOICE_UPLINK,
+        AudioSource.VOICE_DOWNLINK,
+        AudioSource.VOICE_CALL,
+        AudioSource.CAMCORDER,
+        AudioSource.VOICE_RECOGNITION,
+        AudioSource.VOICE_COMMUNICATION,
+        AudioSource.UNPROCESSED,
+        AudioSource.VOICE_PERFORMANCE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Source {}
+
     // TODO make AudioSource static (API change) and move this method inside the AudioSource class
     /**
      * @hide
@@ -547,11 +566,11 @@
      * to be specified before setting recording-parameters or encoders. Call
      * this only before setOutputFormat().
      *
-     * @param audio_source the audio source to use
+     * @param audioSource the audio source to use
      * @throws IllegalStateException if it is called after setOutputFormat()
      * @see android.media.MediaRecorder.AudioSource
      */
-    public native void setAudioSource(int audio_source)
+    public native void setAudioSource(@Source int audioSource)
             throws IllegalStateException;
 
     /**
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
new file mode 100644
index 0000000..04ddc30
--- /dev/null
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class MediaRoute2ProviderService extends Service {
+    private static final String TAG = "MediaRouteProviderSrv";
+
+    public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
+
+    private final Handler mHandler;
+    private ProviderStub mStub;
+    private IMediaRoute2Callback mCallback;
+
+    public MediaRoute2ProviderService() {
+        mHandler = new Handler(Looper.getMainLooper());
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (SERVICE_INTERFACE.equals(intent.getAction())) {
+            if (mStub == null) {
+                mStub = new ProviderStub();
+            }
+            return mStub;
+        }
+        return null;
+    }
+
+    /**
+     * Called when selectRoute is called on a route of the provider.
+     *
+     * @param uid The target application uid
+     * @param routeId The id of the target route
+     */
+    public abstract void onSelect(int uid, String routeId);
+
+    /**
+     * Updates provider info from selected route and appliation.
+     *
+     * TODO: When provider descriptor is defined, this should update the descriptor correctly.
+     *
+     * @param uid
+     * @param routeId
+     */
+    public void updateProvider(int uid, String routeId) {
+        if (mCallback != null) {
+            try {
+                //TODO: After publishState() is fully implemented, delete this.
+                mCallback.onRouteSelected(uid, routeId);
+            } catch (RemoteException ex) {
+                Log.d(TAG, "Failed to update provider");
+            }
+        }
+        publishState();
+    }
+
+    void setCallback(IMediaRoute2Callback callback) {
+        mCallback = callback;
+        publishState();
+    }
+
+    void publishState() {
+        //TODO: Send provider descriptor to the MediaRouterService
+    }
+
+    final class ProviderStub extends IMediaRoute2Provider.Stub {
+        ProviderStub() { }
+
+        @Override
+        public void setCallback(IMediaRoute2Callback callback) {
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setCallback,
+                    MediaRoute2ProviderService.this, callback));
+        }
+
+        @Override
+        public void selectRoute(int uid, String id) {
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelect,
+                    MediaRoute2ProviderService.this, uid, id));
+        }
+    }
+}
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 3444e92..5a89d8c 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -347,6 +347,17 @@
             return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
         }
 
+        void setControlCategories(List<String> categories) {
+            if (mClient != null) {
+                try {
+                    mMediaRouterService.setControlCategories(mClient,
+                            categories);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to set control categories.", ex);
+                }
+            }
+        }
+
         private void updatePresentationDisplays(int changedDisplayId) {
             final int count = mRoutes.size();
             for (int i = 0; i < count; i++) {
@@ -919,6 +930,25 @@
         return -1;
     }
 
+    //TODO: Remove @hide when it is ready.
+    //TODO: Provide pre-defined categories for app developers.
+    /**
+     * Sets control categories of the client application.
+     * Control categories can be used to filter out media routes
+     * that don't correspond with the client application.
+     * The only routes that match any of the categories will be shown on other applications.
+     *
+     * @hide
+     * @param categories Categories to set
+     */
+    public void setControlCategories(@NonNull List<String> categories) {
+        if (categories == null) {
+            throw new IllegalArgumentException("Categories must not be null");
+        }
+        sStatic.setControlCategories(categories);
+    }
+
+
     /**
      * Select the specified route to use for output of the given media types.
      * <p class="note">
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
new file mode 100644
index 0000000..ac5958e
--- /dev/null
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * @hide
+ */
+public class MediaRouter2Manager {
+    private static final String TAG = "MediaRouter2Manager";
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static MediaRouter2Manager sInstance;
+
+    final String mPackageName;
+
+    private Context mContext;
+    private Client mClient;
+    private final IMediaRouterService mMediaRouterService;
+    final Handler mHandler;
+
+    @GuardedBy("sLock")
+    final ArrayList<CallbackRecord> mCallbacks = new ArrayList<>();
+
+    /**
+     * Gets an instance of media router manager that controls media route of other apps.
+     * @param context
+     * @return
+     */
+    public static MediaRouter2Manager getInstance(@NonNull Context context) {
+        if (context == null) {
+            throw new IllegalArgumentException("context must not be null");
+        }
+        synchronized (sLock) {
+            if (sInstance == null) {
+                sInstance = new MediaRouter2Manager(context);
+            }
+            return sInstance;
+        }
+    }
+
+    private MediaRouter2Manager(Context context) {
+        mContext = context.getApplicationContext();
+        mMediaRouterService = IMediaRouterService.Stub.asInterface(
+                ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+        mPackageName = mContext.getPackageName();
+        mHandler = new Handler(context.getMainLooper());
+    }
+
+    /**
+     * Registers a callback to listen route info.
+     *
+     * @param executor The executor that runs the callback.
+     * @param callback The callback to add.
+     */
+    public void addCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull Callback callback) {
+
+        if (executor == null) {
+            throw new IllegalArgumentException("executor must not be null");
+        }
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null");
+        }
+
+        synchronized (sLock) {
+            final int index = findCallbackRecord(callback);
+            if (index >= 0) {
+                Log.w(TAG, "Ignore adding the same callback twice.");
+                return;
+            }
+            if (mCallbacks.size() == 0) {
+                Client client = new Client();
+                try {
+                    mMediaRouterService.registerManagerAsUser(client, mPackageName,
+                            UserHandle.myUserId());
+                    mClient = client;
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to register media router manager.", ex);
+                }
+            }
+            mCallbacks.add(new CallbackRecord(executor, callback));
+        }
+    }
+
+    /**
+     * Removes the specified callback.
+     *
+     * @param callback The callback to remove.
+     */
+    public void removeCallback(@NonNull Callback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null");
+        }
+
+        synchronized (sLock) {
+            final int index = findCallbackRecord(callback);
+            if (index < 0) {
+                Log.w(TAG, "Ignore removing unknown callback. " + callback);
+                return;
+            }
+            mCallbacks.remove(index);
+            if (mCallbacks.size() == 0 && mClient != null) {
+                try {
+                    mMediaRouterService.unregisterManager(mClient);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to unregister media router manager", ex);
+                }
+                mClient = null;
+            }
+        }
+    }
+
+    private int findCallbackRecord(Callback callback) {
+        final int count = mCallbacks.size();
+        for (int i = 0; i < count; i++) {
+            if (mCallbacks.get(i).mCallback == callback) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Selects media route for the specified application uid.
+     *
+     * @param uid The uid of the application that should change it's media route.
+     * @param routeId The id of the route to select
+     */
+    public void selectRoute(int uid, String routeId) {
+        if (mClient != null) {
+            try {
+                mMediaRouterService.setRemoteRoute(mClient, uid, routeId, /* explicit= */true);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to select media route", ex);
+            }
+        }
+    }
+
+    /**
+     * Unselects media route for the specified application uid.
+     *
+     * @param uid The uid of the application that should stop routing.
+     */
+    public void unselectRoute(int uid) {
+        if (mClient != null) {
+            try {
+                mMediaRouterService.setRemoteRoute(mClient, uid, null, /* explicit= */ true);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to select media route", ex);
+            }
+        }
+    }
+
+    void notifyRouteSelected(int uid, String routeId) {
+        for (CallbackRecord record : mCallbacks) {
+            record.mExecutor.execute(() -> record.mCallback.onRouteSelected(uid, routeId));
+        }
+    }
+
+    void notifyControlCategoriesChanged(int uid, List<String> categories) {
+        for (CallbackRecord record : mCallbacks) {
+            record.mExecutor.execute(
+                    () -> record.mCallback.onControlCategoriesChanged(uid, categories));
+        }
+    }
+
+    /**
+     * Interface for receiving events about media routing changes.
+     */
+    public abstract static class Callback {
+        /**
+         * Called when a route is selected for some application uid.
+         * @param uid
+         * @param routeId
+         */
+        public abstract void onRouteSelected(int uid, String routeId);
+
+        /**
+         * Called when the control categories of an application is changed.
+         * @param uid the uid of the app that changed control categories
+         * @param categories the changed categories
+         */
+        public abstract void onControlCategoriesChanged(int uid, List<String> categories);
+    }
+
+    final class CallbackRecord {
+        public final Executor mExecutor;
+        public final Callback mCallback;
+
+        CallbackRecord(Executor executor, Callback callback) {
+            mExecutor = executor;
+            mCallback = callback;
+        }
+    }
+
+    class Client extends IMediaRouter2ManagerClient.Stub {
+        @Override
+        public void onRouteSelected(int uid, String routeId) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyRouteSelected,
+                    MediaRouter2Manager.this, uid, routeId));
+        }
+
+        @Override
+        public void onControlCategoriesChanged(int uid, List<String> categories) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyControlCategoriesChanged,
+                    MediaRouter2Manager.this, uid, categories));
+        }
+    }
+}
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java
index 50caf733..ee8f1b3 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -50,6 +50,10 @@
     private static final boolean DEBUG = DEBUG_APP_OPS || false;
     private static IAudioService sService; //lazy initialization, use getService()
 
+    /** if true, only use OP_PLAY_AUDIO monitoring for logging, and rely on muting to happen
+     *  in AudioFlinger */
+    private static final boolean USE_AUDIOFLINGER_MUTING_FOR_OP = true;
+
     // parameters of the player that affect AppOps
     protected AudioAttributes mAttributes;
 
@@ -67,13 +71,13 @@
 
     // for AppOps
     private @Nullable IAppOpsService mAppOps;
-    private IAppOpsCallback mAppOpsCallback;
+    private @Nullable IAppOpsCallback mAppOpsCallback;
     @GuardedBy("mLock")
     private boolean mHasAppOpsPlayAudio = true;
 
     private final int mImplType;
     // uniquely identifies the Player Interface throughout the system (P I Id)
-    private int mPlayerIId = AudioPlaybackConfiguration.PLAYER_PIID_UNASSIGNED;
+    private int mPlayerIId = AudioPlaybackConfiguration.PLAYER_PIID_INVALID;
 
     @GuardedBy("mLock")
     private int mState;
@@ -104,27 +108,27 @@
      * Call from derived class when instantiation / initialization is successful
      */
     protected void baseRegisterPlayer() {
-        int newPiid = AudioPlaybackConfiguration.PLAYER_PIID_INVALID;
-        IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
-        mAppOps = IAppOpsService.Stub.asInterface(b);
-        // initialize mHasAppOpsPlayAudio
-        updateAppOpsPlayAudio();
-        // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed
-        mAppOpsCallback = new IAppOpsCallbackWrapper(this);
-        try {
-            mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO,
-                    ActivityThread.currentPackageName(), mAppOpsCallback);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error registering appOps callback", e);
-            mHasAppOpsPlayAudio = false;
+        if (!USE_AUDIOFLINGER_MUTING_FOR_OP) {
+            IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
+            mAppOps = IAppOpsService.Stub.asInterface(b);
+            // initialize mHasAppOpsPlayAudio
+            updateAppOpsPlayAudio();
+            // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed
+            mAppOpsCallback = new IAppOpsCallbackWrapper(this);
+            try {
+                mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO,
+                        ActivityThread.currentPackageName(), mAppOpsCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error registering appOps callback", e);
+                mHasAppOpsPlayAudio = false;
+            }
         }
         try {
-            newPiid = getService().trackPlayer(
+            mPlayerIId = getService().trackPlayer(
                     new PlayerIdCard(mImplType, mAttributes, new IPlayerWrapper(this)));
         } catch (RemoteException e) {
             Log.e(TAG, "Error talking to audio service, player will not be tracked", e);
         }
-        mPlayerIId = newPiid;
     }
 
     /**
@@ -284,6 +288,9 @@
      * Must be called synchronized on mLock.
      */
     void updateAppOpsPlayAudio_sync(boolean attributesChanged) {
+        if (USE_AUDIOFLINGER_MUTING_FOR_OP) {
+            return;
+        }
         boolean oldHasAppOpsPlayAudio = mHasAppOpsPlayAudio;
         try {
             int mode = AppOpsManager.MODE_IGNORED;
@@ -333,6 +340,9 @@
      * @return
      */
     boolean isRestricted_sync() {
+        if (USE_AUDIOFLINGER_MUTING_FOR_OP) {
+            return false;
+        }
         // check app ops
         if (mHasAppOpsPlayAudio) {
             return false;
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index e0e657b..fefb0d7 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -29,7 +29,6 @@
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
 import android.content.res.AssetFileDescriptor;
@@ -40,7 +39,6 @@
 import android.os.FileUtils;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -597,24 +595,14 @@
 
     @UnsupportedAppUsage
     private Cursor getMediaRingtones(Context context) {
-        if (PackageManager.PERMISSION_GRANTED != context.checkPermission(
-                android.Manifest.permission.READ_EXTERNAL_STORAGE,
-                Process.myPid(), Process.myUid())) {
-            Log.w(TAG, "No READ_EXTERNAL_STORAGE permission, ignoring ringtones on ext storage");
-            return null;
-        }
-         // Get the external media cursor. First check to see if it is mounted.
-        final String status = Environment.getExternalStorageState();
-        
-        return (status.equals(Environment.MEDIA_MOUNTED) ||
-                    status.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
-                ? query(
-                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS,
-                    constructBooleanTrueWhereClause(mFilterColumns), null,
-                    MediaStore.Audio.Media.DEFAULT_SORT_ORDER, context)
-                : null;
+        // MediaStore now returns ringtones on other storage devices, even when
+        // we don't have storage or audio permissions
+        return query(
+                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS,
+                constructBooleanTrueWhereClause(mFilterColumns), null,
+                MediaStore.Audio.Media.DEFAULT_SORT_ORDER, context);
     }
-    
+
     private void setFilterColumnsList(int type) {
         List<String> columns = mFilterColumns;
         columns.clear();
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 6fd6298..09f17c0 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -142,7 +142,8 @@
         return mFormat;
     }
 
-    AudioMixingRule getRule() {
+    /** @hide */
+    public AudioMixingRule getRule() {
         return mRule;
     }
 
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index d41f416..947b06c 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -16,6 +16,7 @@
 
 package android.media.audiopolicy;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.media.AudioAttributes;
@@ -43,9 +44,11 @@
 @SystemApi
 public class AudioMixingRule {
 
-    private AudioMixingRule(int mixType, ArrayList<AudioMixMatchCriterion> criteria) {
+    private AudioMixingRule(int mixType, ArrayList<AudioMixMatchCriterion> criteria,
+                            boolean allowPrivilegedPlaybackCapture) {
         mCriteria = criteria;
         mTargetMixType = mixType;
+        mAllowPrivilegedPlaybackCapture = allowPrivilegedPlaybackCapture;
     }
 
     /**
@@ -161,6 +164,13 @@
     @UnsupportedAppUsage
     private final ArrayList<AudioMixMatchCriterion> mCriteria;
     ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; }
+    @UnsupportedAppUsage
+    private boolean mAllowPrivilegedPlaybackCapture = false;
+
+    /** @hide */
+    public boolean allowPrivilegedPlaybackCapture() {
+        return mAllowPrivilegedPlaybackCapture;
+    }
 
     /** @hide */
     @Override
@@ -170,12 +180,13 @@
 
         final AudioMixingRule that = (AudioMixingRule) o;
         return (this.mTargetMixType == that.mTargetMixType)
-                && (areCriteriaEquivalent(this.mCriteria, that.mCriteria));
+                && (areCriteriaEquivalent(this.mCriteria, that.mCriteria)
+                && this.mAllowPrivilegedPlaybackCapture == that.mAllowPrivilegedPlaybackCapture);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mTargetMixType, mCriteria);
+        return Objects.hash(mTargetMixType, mCriteria, mAllowPrivilegedPlaybackCapture);
     }
 
     private static boolean isValidSystemApiRule(int rule) {
@@ -239,6 +250,7 @@
     public static class Builder {
         private ArrayList<AudioMixMatchCriterion> mCriteria;
         private int mTargetMixType = AudioMix.MIX_TYPE_INVALID;
+        private boolean mAllowPrivilegedPlaybackCapture = false;
 
         /**
          * Constructs a new Builder with no rules.
@@ -343,6 +355,21 @@
         }
 
         /**
+         * Set if the audio of app that opted out of audio playback capture should be captured.
+         *
+         * The permission {@link CAPTURE_AUDIO_OUTPUT} or {@link CAPTURE_MEDIA_OUTPUT} is needed
+         * to ignore the opt-out.
+         *
+         * Only affects LOOPBACK|RENDER mix.
+         *
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder allowPrivilegedPlaybackCapture(boolean allow) {
+            mAllowPrivilegedPlaybackCapture = allow;
+            return this;
+        }
+
+        /**
          * Add or exclude a rule for the selection of which streams are mixed together.
          * Does error checking on the parameters.
          * @param rule
@@ -507,7 +534,7 @@
          * @return a new {@link AudioMixingRule} object
          */
         public AudioMixingRule build() {
-            return new AudioMixingRule(mTargetMixType, mCriteria);
+            return new AudioMixingRule(mTargetMixType, mCriteria, mAllowPrivilegedPlaybackCapture);
         }
     }
 }
diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
index a6e63c7..c4ba0c1 100644
--- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java
+++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
@@ -96,6 +96,8 @@
             dest.writeInt(mix.getFormat().getSampleRate());
             dest.writeInt(mix.getFormat().getEncoding());
             dest.writeInt(mix.getFormat().getChannelMask());
+            // write opt-out respect
+            dest.writeBoolean(mix.getRule().allowPrivilegedPlaybackCapture());
             // write mix rules
             final ArrayList<AudioMixMatchCriterion> criteria = mix.getRule().getCriteria();
             dest.writeInt(criteria.size());
@@ -124,9 +126,12 @@
             final AudioFormat format = new AudioFormat.Builder().setSampleRate(sampleRate)
                     .setChannelMask(channelMask).setEncoding(encoding).build();
             mixBuilder.setFormat(format);
+
+            AudioMixingRule.Builder ruleBuilder = new AudioMixingRule.Builder();
+            // write opt-out respect
+            ruleBuilder.allowPrivilegedPlaybackCapture(in.readBoolean());
             // read mix rules
             int nbRules = in.readInt();
-            AudioMixingRule.Builder ruleBuilder = new AudioMixingRule.Builder();
             for (int j = 0 ; j < nbRules ; j++) {
                 // read the matching rules
                 ruleBuilder.addRuleFromParcel(in);
@@ -161,7 +166,9 @@
             textDump += "  rate=" + mix.getFormat().getSampleRate() + "Hz\n";
             textDump += "  encoding=" + mix.getFormat().getEncoding() + "\n";
             textDump += "  channels=0x";
-            textDump += Integer.toHexString(mix.getFormat().getChannelMask()).toUpperCase() +"\n";
+            textDump += Integer.toHexString(mix.getFormat().getChannelMask()).toUpperCase() + "\n";
+            textDump += "  ignore playback capture opt out="
+                    + mix.getRule().allowPrivilegedPlaybackCapture() + "\n";
             // write mix rules
             final ArrayList<AudioMixMatchCriterion> criteria = mix.getRule().getCriteria();
             for (AudioMixMatchCriterion criterion : criteria) {
diff --git a/media/java/android/media/session/ControllerCallbackLink.java b/media/java/android/media/session/ControllerCallbackLink.java
deleted file mode 100644
index 67d849a..0000000
--- a/media/java/android/media/session/ControllerCallbackLink.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.session;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.media.MediaMetadata;
-import android.media.MediaParceledListSlice;
-import android.media.session.MediaController.PlaybackInfo;
-import android.media.session.MediaSession.QueueItem;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.RemoteException;
-
-import java.util.List;
-
-/**
- * Handles incoming commands to {@link MediaController.Callback}.
- * @hide
- */
-public final class ControllerCallbackLink implements Parcelable {
-    final Context mContext;
-    final CallbackStub mCallbackStub;
-    final ISessionControllerCallback mIControllerCallback;
-
-    /**
-     * Constructor for stub (Callee)
-     */
-    public ControllerCallbackLink(@NonNull Context context, @NonNull CallbackStub callbackStub) {
-        mContext = context;
-        mCallbackStub = callbackStub;
-        mIControllerCallback = new CallbackStubProxy();
-    }
-
-    /**
-     * Constructor for interface (Caller)
-     */
-    public ControllerCallbackLink(IBinder binder) {
-        mContext = null;
-        mCallbackStub = null;
-        mIControllerCallback = ISessionControllerCallback.Stub.asInterface(binder);
-    }
-
-    /**
-     * Notify controller that the connected session is destroyed.
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifySessionDestroyed() {
-        try {
-            mIControllerCallback.notifySessionDestroyed();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the connected session sends an event.
-     *
-     * @param event the name of the event
-     * @param extras the extras included with the event
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyEvent(@NonNull String event, @Nullable Bundle extras) {
-        try {
-            mIControllerCallback.notifyEvent(event, extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the current playback state is changed.
-     *
-     * @param state the new playback state
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyPlaybackStateChanged(@Nullable PlaybackState state) {
-        try {
-            mIControllerCallback.notifyPlaybackStateChanged(state);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the current metadata is changed.
-     *
-     * @param metadata the new metadata
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyMetadataChanged(@Nullable MediaMetadata metadata) {
-        try {
-            mIControllerCallback.notifyMetadataChanged(metadata);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the current queue is changed.
-     *
-     * @param queue the new queue
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyQueueChanged(@Nullable List<QueueItem> queue) {
-        try {
-            mIControllerCallback.notifyQueueChanged(queue == null ? null :
-                    new MediaParceledListSlice(queue));
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the current queue title is changed.
-     *
-     * @param title the new queue title
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyQueueTitleChanged(@Nullable CharSequence title) {
-        try {
-            mIControllerCallback.notifyQueueTitleChanged(title);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the extras are changed.
-     *
-     * @param extras the new extras
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyExtrasChanged(@Nullable Bundle extras) {
-        try {
-            mIControllerCallback.notifyExtrasChanged(extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the playback info is changed.
-     *
-     * @param info the new playback info
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyVolumeInfoChanged(@NonNull PlaybackInfo info) {
-        try {
-            mIControllerCallback.notifyVolumeInfoChanged(info);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /** Gets the binder */
-    @NonNull
-    public IBinder getBinder() {
-        return mIControllerCallback.asBinder();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStrongBinder(mIControllerCallback.asBinder());
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ControllerCallbackLink> CREATOR =
-            new Parcelable.Creator<ControllerCallbackLink>() {
-        @Override
-        public ControllerCallbackLink createFromParcel(Parcel in) {
-            return new ControllerCallbackLink(in.readStrongBinder());
-        }
-
-        @Override
-        public ControllerCallbackLink[] newArray(int size) {
-            return new ControllerCallbackLink[size];
-        }
-    };
-
-    /**
-     * Class for Stub implementation
-     */
-    public abstract static class CallbackStub {
-        /** Stub method for ISessionControllerCallback.notifySessionDestroyed */
-        public void onSessionDestroyed() {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyEvent */
-        public void onEvent(@NonNull String event, @Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyPlaybackStateChanged */
-        public void onPlaybackStateChanged(@Nullable PlaybackState state) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyMetadataChanged */
-        public void onMetadataChanged(@Nullable MediaMetadata metadata) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyQueueChanged */
-        public void onQueueChanged(@Nullable List<QueueItem> queue) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyQueueTitleChanged */
-        public void onQueueTitleChanged(@Nullable CharSequence title) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyExtrasChanged */
-        public void onExtrasChanged(@Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyVolumeInfoChanged */
-        public void onVolumeInfoChanged(@NonNull PlaybackInfo info) {
-        }
-    }
-
-    private class CallbackStubProxy extends ISessionControllerCallback.Stub {
-        @Override
-        public void notifyEvent(String event, Bundle extras) {
-            mCallbackStub.onEvent(event, extras);
-        }
-
-        @Override
-        public void notifySessionDestroyed() {
-            mCallbackStub.onSessionDestroyed();
-        }
-
-        @Override
-        public void notifyPlaybackStateChanged(PlaybackState state) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onPlaybackStateChanged(state);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void notifyMetadataChanged(MediaMetadata metadata) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onMetadataChanged(metadata);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void notifyQueueChanged(MediaParceledListSlice queue) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onQueueChanged(queue == null ? null : queue.getList());
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void notifyQueueTitleChanged(CharSequence title) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onQueueTitleChanged(title);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void notifyExtrasChanged(Bundle extras) {
-            mCallbackStub.onExtrasChanged(extras);
-        }
-
-        @Override
-        public void notifyVolumeInfoChanged(PlaybackInfo info) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onVolumeInfoChanged(info);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        private void ensureMediaControlPermission() {
-            // Check if it's system server or has MEDIA_CONTENT_CONTROL.
-            // Note that system server doesn't have MEDIA_CONTENT_CONTROL, so we need extra
-            // check here.
-            if (getCallingUid() == Process.SYSTEM_UID || mContext.checkCallingPermission(
-                    android.Manifest.permission.MEDIA_CONTENT_CONTROL)
-                    == PackageManager.PERMISSION_GRANTED) {
-                return;
-            }
-            throw new SecurityException("Must hold the MEDIA_CONTENT_CONTROL permission.");
-        }
-    }
-}
diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl
index 0add1b4..a294088d 100644
--- a/media/java/android/media/session/ISessionCallback.aidl
+++ b/media/java/android/media/session/ISessionCallback.aidl
@@ -17,7 +17,7 @@
 
 import android.content.Intent;
 import android.media.Rating;
-import android.media.session.ControllerCallbackLink;
+import android.media.session.ISessionControllerCallback;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.ResultReceiver;
@@ -26,48 +26,48 @@
  * @hide
  */
 oneway interface ISessionCallback {
-    void onCommand(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onCommand(String packageName, int pid, int uid, ISessionControllerCallback caller,
             String command, in Bundle args, in ResultReceiver cb);
     void onMediaButton(String packageName, int pid, int uid, in Intent mediaButtonIntent,
             int sequenceNumber, in ResultReceiver cb);
     void onMediaButtonFromController(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, in Intent mediaButtonIntent);
+            ISessionControllerCallback caller, in Intent mediaButtonIntent);
 
     // These callbacks are for the TransportControls
-    void onPrepare(String packageName, int pid, int uid, in ControllerCallbackLink caller);
+    void onPrepare(String packageName, int pid, int uid, ISessionControllerCallback caller);
     void onPrepareFromMediaId(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, String mediaId, in Bundle extras);
+            ISessionControllerCallback caller, String mediaId, in Bundle extras);
     void onPrepareFromSearch(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, String query, in Bundle extras);
+            ISessionControllerCallback caller, String query, in Bundle extras);
     void onPrepareFromUri(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, in Uri uri, in Bundle extras);
-    void onPlay(String packageName, int pid, int uid, in ControllerCallbackLink caller);
+            ISessionControllerCallback caller, in Uri uri, in Bundle extras);
+    void onPlay(String packageName, int pid, int uid, ISessionControllerCallback caller);
     void onPlayFromMediaId(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, String mediaId, in Bundle extras);
+            ISessionControllerCallback caller, String mediaId, in Bundle extras);
     void onPlayFromSearch(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, String query, in Bundle extras);
-    void onPlayFromUri(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+            ISessionControllerCallback caller, String query, in Bundle extras);
+    void onPlayFromUri(String packageName, int pid, int uid, ISessionControllerCallback caller,
             in Uri uri, in Bundle extras);
-    void onSkipToTrack(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onSkipToTrack(String packageName, int pid, int uid, ISessionControllerCallback caller,
             long id);
-    void onPause(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onStop(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onNext(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onPrevious(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onFastForward(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onRewind(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onSeekTo(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onPause(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onStop(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onNext(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onPrevious(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onFastForward(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onRewind(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onSeekTo(String packageName, int pid, int uid, ISessionControllerCallback caller,
             long pos);
-    void onRate(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onRate(String packageName, int pid, int uid, ISessionControllerCallback caller,
             in Rating rating);
     void onSetPlaybackSpeed(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, float speed);
-    void onCustomAction(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+            ISessionControllerCallback caller, float speed);
+    void onCustomAction(String packageName, int pid, int uid, ISessionControllerCallback caller,
             String action, in Bundle args);
 
     // These callbacks are for volume handling
-    void onAdjustVolume(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onAdjustVolume(String packageName, int pid, int uid, ISessionControllerCallback caller,
             int direction);
     void onSetVolumeTo(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, int value);
+            ISessionControllerCallback caller, int value);
 }
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 298085f..9b1223c 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -20,7 +20,7 @@
 import android.media.MediaMetadata;
 import android.media.MediaParceledListSlice;
 import android.media.Rating;
-import android.media.session.ControllerCallbackLink;
+import android.media.session.ISessionControllerCallback;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.PlaybackState;
@@ -36,12 +36,12 @@
  * @hide
  */
 interface ISessionController {
-    void sendCommand(String packageName, in ControllerCallbackLink caller,
+    void sendCommand(String packageName, in ISessionControllerCallback caller,
             String command, in Bundle args, in ResultReceiver cb);
-    boolean sendMediaButton(String packageName, in ControllerCallbackLink caller,
+    boolean sendMediaButton(String packageName, in ISessionControllerCallback caller,
             in KeyEvent mediaButton);
-    void registerCallback(String packageName, in ControllerCallbackLink cb);
-    void unregisterCallback(in ControllerCallbackLink cb);
+    void registerCallback(String packageName, in ISessionControllerCallback cb);
+    void unregisterCallback(in ISessionControllerCallback cb);
     String getPackageName();
     String getTag();
     Bundle getSessionInfo();
@@ -49,36 +49,36 @@
     long getFlags();
     MediaController.PlaybackInfo getVolumeAttributes();
     void adjustVolume(String packageName, String opPackageName,
-            in ControllerCallbackLink caller, int direction, int flags);
-    void setVolumeTo(String packageName, String opPackageName, in ControllerCallbackLink caller,
+            in ISessionControllerCallback caller, int direction, int flags);
+    void setVolumeTo(String packageName, String opPackageName, in ISessionControllerCallback caller,
             int value, int flags);
 
     // These commands are for the TransportControls
-    void prepare(String packageName, in ControllerCallbackLink caller);
-    void prepareFromMediaId(String packageName, in ControllerCallbackLink caller,
+    void prepare(String packageName, in ISessionControllerCallback caller);
+    void prepareFromMediaId(String packageName, in ISessionControllerCallback caller,
             String mediaId, in Bundle extras);
-    void prepareFromSearch(String packageName, in ControllerCallbackLink caller,
+    void prepareFromSearch(String packageName, in ISessionControllerCallback caller,
             String string, in Bundle extras);
-    void prepareFromUri(String packageName, in ControllerCallbackLink caller,
+    void prepareFromUri(String packageName, in ISessionControllerCallback caller,
             in Uri uri, in Bundle extras);
-    void play(String packageName, in ControllerCallbackLink caller);
-    void playFromMediaId(String packageName, in ControllerCallbackLink caller,
+    void play(String packageName, in ISessionControllerCallback caller);
+    void playFromMediaId(String packageName, in ISessionControllerCallback caller,
             String mediaId, in Bundle extras);
-    void playFromSearch(String packageName, in ControllerCallbackLink caller,
+    void playFromSearch(String packageName, in ISessionControllerCallback caller,
             String string, in Bundle extras);
-    void playFromUri(String packageName, in ControllerCallbackLink caller,
+    void playFromUri(String packageName, in ISessionControllerCallback caller,
             in Uri uri, in Bundle extras);
-    void skipToQueueItem(String packageName, in ControllerCallbackLink caller, long id);
-    void pause(String packageName, in ControllerCallbackLink caller);
-    void stop(String packageName, in ControllerCallbackLink caller);
-    void next(String packageName, in ControllerCallbackLink caller);
-    void previous(String packageName, in ControllerCallbackLink caller);
-    void fastForward(String packageName, in ControllerCallbackLink caller);
-    void rewind(String packageName, in ControllerCallbackLink caller);
-    void seekTo(String packageName, in ControllerCallbackLink caller, long pos);
-    void rate(String packageName, in ControllerCallbackLink caller, in Rating rating);
-    void setPlaybackSpeed(String packageName, in ControllerCallbackLink caller, float speed);
-    void sendCustomAction(String packageName, in ControllerCallbackLink caller,
+    void skipToQueueItem(String packageName, in ISessionControllerCallback caller, long id);
+    void pause(String packageName, in ISessionControllerCallback caller);
+    void stop(String packageName, in ISessionControllerCallback caller);
+    void next(String packageName, in ISessionControllerCallback caller);
+    void previous(String packageName, in ISessionControllerCallback caller);
+    void fastForward(String packageName, in ISessionControllerCallback caller);
+    void rewind(String packageName, in ISessionControllerCallback caller);
+    void seekTo(String packageName, in ISessionControllerCallback caller, long pos);
+    void rate(String packageName, in ISessionControllerCallback caller, in Rating rating);
+    void setPlaybackSpeed(String packageName, in ISessionControllerCallback caller, float speed);
+    void sendCustomAction(String packageName, in ISessionControllerCallback caller,
             String action, in Bundle args);
     MediaMetadata getMetadata();
     PlaybackState getPlaybackState();
diff --git a/media/java/android/media/session/ISessionControllerCallback.aidl b/media/java/android/media/session/ISessionControllerCallback.aidl
index 56ae852..f284133 100644
--- a/media/java/android/media/session/ISessionControllerCallback.aidl
+++ b/media/java/android/media/session/ISessionControllerCallback.aidl
@@ -25,14 +25,14 @@
  * @hide
  */
 oneway interface ISessionControllerCallback {
-    void notifyEvent(String event, in Bundle extras);
-    void notifySessionDestroyed();
+    void onEvent(String event, in Bundle extras);
+    void onSessionDestroyed();
 
     // These callbacks are for the TransportController
-    void notifyPlaybackStateChanged(in PlaybackState state);
-    void notifyMetadataChanged(in MediaMetadata metadata);
-    void notifyQueueChanged(in MediaParceledListSlice queue);
-    void notifyQueueTitleChanged(CharSequence title);
-    void notifyExtrasChanged(in Bundle extras);
-    void notifyVolumeInfoChanged(in MediaController.PlaybackInfo info);
+    void onPlaybackStateChanged(in PlaybackState state);
+    void onMetadataChanged(in MediaMetadata metadata);
+    void onQueueChanged(in MediaParceledListSlice queue);
+    void onQueueTitleChanged(CharSequence title);
+    void onExtrasChanged(in Bundle extras);
+    void onVolumeInfoChanged(in MediaController.PlaybackInfo info);
 }
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 036cd78..79d8be1 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -73,7 +73,7 @@
 
     private final MediaSession.Token mToken;
     private final Context mContext;
-    private final ControllerCallbackLink mCbStub;
+    private final CallbackStub mCbStub = new CallbackStub(this);
     private final ArrayList<MessageHandler> mCallbacks = new ArrayList<MessageHandler>();
     private final Object mLock = new Object();
 
@@ -104,7 +104,6 @@
         mTransportControls = new TransportControls();
         mToken = token;
         mContext = context;
-        mCbStub = new ControllerCallbackLink(context, new CallbackStub(this));
     }
 
     /**
@@ -1065,7 +1064,7 @@
         };
     }
 
-    private static final class CallbackStub extends ControllerCallbackLink.CallbackStub {
+    private static final class CallbackStub extends ISessionControllerCallback.Stub {
         private final WeakReference<MediaController> mController;
 
         CallbackStub(MediaController controller) {
@@ -1105,7 +1104,7 @@
         }
 
         @Override
-        public void onQueueChanged(List<QueueItem> queue) {
+        public void onQueueChanged(MediaParceledListSlice queue) {
             MediaController controller = mController.get();
             if (controller != null) {
                 controller.postMessage(MSG_UPDATE_QUEUE, queue, null);
@@ -1162,7 +1161,8 @@
                     mCallback.onMetadataChanged((MediaMetadata) msg.obj);
                     break;
                 case MSG_UPDATE_QUEUE:
-                    mCallback.onQueueChanged((List<MediaSession.QueueItem>) msg.obj);
+                    mCallback.onQueueChanged(msg.obj == null ? null :
+                            (List<QueueItem>) ((MediaParceledListSlice) msg.obj).getList());
                     break;
                 case MSG_UPDATE_QUEUE_TITLE:
                     mCallback.onQueueTitleChanged((CharSequence) msg.obj);
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index aa61a01..c577469 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -1120,7 +1120,7 @@
 
         @Override
         public void onCommand(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
+                ISessionControllerCallback caller, String command, Bundle args, ResultReceiver cb) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchCommand(createRemoteUserInfo(packageName, pid, uid),
@@ -1146,7 +1146,7 @@
 
         @Override
         public void onMediaButtonFromController(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Intent mediaButtonIntent) {
+                ISessionControllerCallback caller, Intent mediaButtonIntent) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid),
@@ -1156,7 +1156,7 @@
 
         @Override
         public void onPrepare(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid));
@@ -1165,7 +1165,7 @@
 
         @Override
         public void onPrepareFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId,
+                ISessionControllerCallback caller, String mediaId,
                 Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1176,7 +1176,7 @@
 
         @Override
         public void onPrepareFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query,
+                ISessionControllerCallback caller, String query,
                 Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1187,7 +1187,7 @@
 
         @Override
         public void onPrepareFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+                ISessionControllerCallback caller, Uri uri, Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPrepareFromUri(createRemoteUserInfo(packageName, pid, uid),
@@ -1197,7 +1197,7 @@
 
         @Override
         public void onPlay(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPlay(createRemoteUserInfo(packageName, pid, uid));
@@ -1206,7 +1206,7 @@
 
         @Override
         public void onPlayFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId,
+                ISessionControllerCallback caller, String mediaId,
                 Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1217,7 +1217,7 @@
 
         @Override
         public void onPlayFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query,
+                ISessionControllerCallback caller, String query,
                 Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1228,7 +1228,7 @@
 
         @Override
         public void onPlayFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+                ISessionControllerCallback caller, Uri uri, Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPlayFromUri(createRemoteUserInfo(packageName, pid, uid),
@@ -1238,7 +1238,7 @@
 
         @Override
         public void onSkipToTrack(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, long id) {
+                ISessionControllerCallback caller, long id) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchSkipToItem(createRemoteUserInfo(packageName, pid, uid), id);
@@ -1247,7 +1247,7 @@
 
         @Override
         public void onPause(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPause(createRemoteUserInfo(packageName, pid, uid));
@@ -1256,7 +1256,7 @@
 
         @Override
         public void onStop(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchStop(createRemoteUserInfo(packageName, pid, uid));
@@ -1265,7 +1265,7 @@
 
         @Override
         public void onNext(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchNext(createRemoteUserInfo(packageName, pid, uid));
@@ -1274,7 +1274,7 @@
 
         @Override
         public void onPrevious(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid));
@@ -1283,7 +1283,7 @@
 
         @Override
         public void onFastForward(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchFastForward(createRemoteUserInfo(packageName, pid, uid));
@@ -1292,7 +1292,7 @@
 
         @Override
         public void onRewind(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchRewind(createRemoteUserInfo(packageName, pid, uid));
@@ -1301,7 +1301,7 @@
 
         @Override
         public void onSeekTo(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, long pos) {
+                ISessionControllerCallback caller, long pos) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchSeekTo(createRemoteUserInfo(packageName, pid, uid), pos);
@@ -1309,7 +1309,7 @@
         }
 
         @Override
-        public void onRate(String packageName, int pid, int uid, ControllerCallbackLink caller,
+        public void onRate(String packageName, int pid, int uid, ISessionControllerCallback caller,
                 Rating rating) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1319,7 +1319,7 @@
 
         @Override
         public void onSetPlaybackSpeed(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, float speed) {
+                ISessionControllerCallback caller, float speed) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchSetPlaybackSpeed(
@@ -1329,7 +1329,7 @@
 
         @Override
         public void onCustomAction(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String action, Bundle args) {
+                ISessionControllerCallback caller, String action, Bundle args) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchCustomAction(createRemoteUserInfo(packageName, pid, uid),
@@ -1339,7 +1339,7 @@
 
         @Override
         public void onAdjustVolume(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, int direction) {
+                ISessionControllerCallback caller, int direction) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchAdjustVolume(createRemoteUserInfo(packageName, pid, uid),
@@ -1349,7 +1349,7 @@
 
         @Override
         public void onSetVolumeTo(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, int value) {
+                ISessionControllerCallback caller, int value) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchSetVolumeTo(createRemoteUserInfo(packageName, pid, uid),
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 65b58ab..5c3d780 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -129,6 +129,7 @@
         // NDK or LLNDK or NDK-compliant
         "libandroid",
         "libbinder_ndk",
+        "libcgrouprc",
         "libmediandk",
         "libmediametrics",
         "libnativehelper_compat_libc++",
diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp
new file mode 100644
index 0000000..f0fbc50
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/Android.bp
@@ -0,0 +1,14 @@
+android_test {
+    name: "mediaframeworktest",
+    srcs: ["**/*.java"],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+    static_libs: [
+        "mockito-target-minus-junit4",
+        "androidx.test.rules",
+        "android-ex-camera2",
+    ],
+    platform_apis: true,
+}
diff --git a/media/tests/MediaFrameworkTest/Android.mk b/media/tests/MediaFrameworkTest/Android.mk
deleted file mode 100644
index 167d255..0000000
--- a/media/tests/MediaFrameworkTest/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    mockito-target-minus-junit4 \
-    androidx.test.rules \
-    android-ex-camera2
-
-LOCAL_PACKAGE_NAME := mediaframeworktest
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-include $(BUILD_PACKAGE)
diff --git a/media/tests/MediaRouteProvider/Android.bp b/media/tests/MediaRouteProvider/Android.bp
new file mode 100644
index 0000000..da42824
--- /dev/null
+++ b/media/tests/MediaRouteProvider/Android.bp
@@ -0,0 +1,18 @@
+android_test {
+    name: "mediarouteprovider",
+
+    srcs: ["**/*.java"],
+
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+
+    static_libs: [
+        "android-support-test",
+        "mockito-target-minus-junit4",
+    ],
+
+    platform_apis: true,
+    certificate: "platform",
+}
\ No newline at end of file
diff --git a/media/tests/MediaRouteProvider/AndroidManifest.xml b/media/tests/MediaRouteProvider/AndroidManifest.xml
new file mode 100644
index 0000000..489a621
--- /dev/null
+++ b/media/tests/MediaRouteProvider/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.mediarouteprovider.example">
+
+    <application android:label="@string/app_name">
+        <uses-library android:name="android.test.runner" />
+        <service android:name=".SampleMediaRoute2ProviderService"
+            android:label="@string/app_name"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.media.MediaRoute2ProviderService" />
+            </intent-filter>
+       </service>
+    </application>
+</manifest>
diff --git a/media/tests/MediaRouteProvider/res/values/strings.xml b/media/tests/MediaRouteProvider/res/values/strings.xml
new file mode 100644
index 0000000..bb97064
--- /dev/null
+++ b/media/tests/MediaRouteProvider/res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- name of the app [CHAR LIMIT=25]-->
+    <string name="app_name">SampleMediaRouteProvider</string>
+</resources>
\ No newline at end of file
diff --git a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
new file mode 100644
index 0000000..22fbd85
--- /dev/null
+++ b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mediarouteprovider.example;
+
+import android.content.Intent;
+import android.media.MediaRoute2ProviderService;
+import android.os.IBinder;
+
+public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService {
+    @Override
+    public IBinder onBind(Intent intent) {
+        return super.onBind(intent);
+    }
+
+    @Override
+    public void onSelect(int uid, String routeId) {
+        updateProvider(uid, routeId);
+    }
+}
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
new file mode 100644
index 0000000..611b25a
--- /dev/null
+++ b/media/tests/MediaRouter/Android.bp
@@ -0,0 +1,18 @@
+android_test {
+    name: "mediaroutertest",
+
+    srcs: ["**/*.java"],
+
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+
+    static_libs: [
+        "android-support-test",
+        "mockito-target-minus-junit4",
+    ],
+
+    platform_apis: true,
+    certificate: "platform",
+}
\ No newline at end of file
diff --git a/media/tests/MediaRouter/AndroidManifest.xml b/media/tests/MediaRouter/AndroidManifest.xml
new file mode 100644
index 0000000..a34a264
--- /dev/null
+++ b/media/tests/MediaRouter/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.mediaroutertest">
+
+    <uses-permission android:name="android.permission.CONTROL_MEDIA_ROUTE" />
+
+    <application android:label="@string/app_name">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.mediaroutertest"
+                     android:label="MediaRouter Tests"/>
+</manifest>
diff --git a/media/tests/MediaRouter/AndroidTest.xml b/media/tests/MediaRouter/AndroidTest.xml
new file mode 100644
index 0000000..1301062
--- /dev/null
+++ b/media/tests/MediaRouter/AndroidTest.xml
@@ -0,0 +1,16 @@
+<configuration description="Runs sample instrumentation test.">
+    <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="mediaroutertest.apk"/>
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-tag" value="MediaRouterTest"/>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+        <option name="package" value="com.android.mediaroutertest"/>
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/media/tests/MediaRouter/res/values/strings.xml b/media/tests/MediaRouter/res/values/strings.xml
new file mode 100644
index 0000000..0737020
--- /dev/null
+++ b/media/tests/MediaRouter/res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- name of the app [CHAR LIMIT=25]-->
+    <string name="app_name">mediaRouterTest</string>
+</resources>
\ No newline at end of file
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
new file mode 100644
index 0000000..a4bde65
--- /dev/null
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mediaroutertest;
+
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.media.MediaRouter;
+import android.media.MediaRouter2Manager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MediaRouterManagerTest {
+    private static final String TAG = "MediaRouterManagerTest";
+
+    private static final int TARGET_UID = 109992;
+    private static final String ROUTE_1 = "MediaRoute1";
+
+    private static final int AWAIT_MS = 1000;
+    private static final int TIMEOUT_MS = 1000;
+
+    private Context mContext;
+    private MediaRouter2Manager mManager;
+    private MediaRouter mRouter;
+    private Executor mExecutor;
+
+    private static final List<String> TEST_CONTROL_CATEGORIES = new ArrayList();
+    private static final String CONTROL_CATEGORY_1 = "android.media.mediarouter.MEDIA1";
+    private static final String CONTROL_CATEGORY_2 = "android.media.mediarouter.MEDIA2";
+    static {
+        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_1);
+        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_2);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mManager = MediaRouter2Manager.getInstance(mContext);
+        mRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+        mExecutor = new ThreadPoolExecutor(
+            1, 20, 3, TimeUnit.SECONDS,
+            new SynchronousQueue<Runnable>());
+    }
+
+    @Test
+    public void transferTest() throws Exception {
+        MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
+
+        mManager.addCallback(mExecutor, mockCallback);
+
+        verify(mockCallback, after(AWAIT_MS).never())
+            .onRouteSelected(eq(TARGET_UID), any(String.class));
+
+        mManager.selectRoute(TARGET_UID, ROUTE_1);
+        verify(mockCallback, timeout(TIMEOUT_MS)).onRouteSelected(TARGET_UID, ROUTE_1);
+
+        mManager.removeCallback(mockCallback);
+    }
+
+    @Test
+    public void controlCategoryTest() throws Exception {
+        final int uid = android.os.Process.myUid();
+
+        MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
+        mManager.addCallback(mExecutor, mockCallback);
+
+        verify(mockCallback, after(AWAIT_MS).never()).onControlCategoriesChanged(eq(uid),
+                any(List.class));
+
+        mRouter.setControlCategories(TEST_CONTROL_CATEGORIES);
+        verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
+            .onControlCategoriesChanged(uid, TEST_CONTROL_CATEGORIES);
+
+        mManager.removeCallback(mockCallback);
+    }
+
+}
diff --git a/media/tests/MtpTests/Android.bp b/media/tests/MtpTests/Android.bp
new file mode 100644
index 0000000..7d2c7c6
--- /dev/null
+++ b/media/tests/MtpTests/Android.bp
@@ -0,0 +1,6 @@
+android_test {
+    name: "MtpTests",
+    srcs: ["**/*.java"],
+    static_libs: ["androidx.test.rules"],
+    platform_apis: true,
+}
diff --git a/media/tests/MtpTests/Android.mk b/media/tests/MtpTests/Android.mk
deleted file mode 100644
index 4cee62e..0000000
--- a/media/tests/MtpTests/Android.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.rules
-
-LOCAL_PACKAGE_NAME := MtpTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-include $(BUILD_PACKAGE)
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 1f2480b..177f2b8 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -248,16 +248,21 @@
     ASystemFontIterator_open; # introduced=29
     ASystemFontIterator_close; # introduced=29
     ASystemFontIterator_next; # introduced=29
-    ASystemFont_close; # introduced=29
-    ASystemFont_getFontFilePath; # introduced=29
-    ASystemFont_getWeight; # introduced=29
-    ASystemFont_isItalic; # introduced=29
-    ASystemFont_getLocale; # introduced=29
-    ASystemFont_getCollectionIndex; # introduced=29
-    ASystemFont_getAxisCount; # introduced=29
-    ASystemFont_getAxisTag; # introduced=29
-    ASystemFont_getAxisValue; # introduced=29
-    ASystemFont_matchFamilyStyleCharacter; # introduced=29
+    AFont_close; # introduced=29
+    AFont_getFontFilePath; # introduced=29
+    AFont_getWeight; # introduced=29
+    AFont_isItalic; # introduced=29
+    AFont_getLocale; # introduced=29
+    AFont_getCollectionIndex; # introduced=29
+    AFont_getAxisCount; # introduced=29
+    AFont_getAxisTag; # introduced=29
+    AFont_getAxisValue; # introduced=29
+    AFontMatcher_create; # introduced=29
+    AFontMatcher_destroy; # introduced=29
+    AFontMatcher_setStyle; # introduced=29
+    AFontMatcher_setLocales; # introduced=29
+    AFontMatcher_setFamilyVariant; # introduced=29
+    AFontMatcher_match; # introduced=29
     ATrace_beginSection; # introduced=23
     ATrace_endSection; # introduced=23
     ATrace_isEnabled; # introduced=23
diff --git a/native/android/system_fonts.cpp b/native/android/system_fonts.cpp
index 4d3d1d6..302cbd1 100644
--- a/native/android/system_fonts.cpp
+++ b/native/android/system_fonts.cpp
@@ -16,6 +16,8 @@
 
 #include <jni.h>
 
+#include <android/font.h>
+#include <android/font_matcher.h>
 #include <android/system_fonts.h>
 
 #include <memory>
@@ -53,7 +55,7 @@
     XmlDocUniquePtr mCustomizationXmlDoc;
 };
 
-struct ASystemFont {
+struct AFont {
     std::string mFilePath;
     std::unique_ptr<std::string> mLocale;
     uint16_t mWeight;
@@ -62,6 +64,19 @@
     std::vector<std::pair<uint32_t, float>> mAxes;
 };
 
+struct AFontMatcher {
+    minikin::FontStyle mFontStyle;
+    uint32_t mLocaleListId = 0;  // 0 is reserved for empty locale ID.
+    bool mFamilyVariant = AFAMILY_VARIANT_DEFAULT;
+};
+
+static_assert(static_cast<uint32_t>(AFAMILY_VARIANT_DEFAULT) ==
+              static_cast<uint32_t>(minikin::FamilyVariant::DEFAULT));
+static_assert(static_cast<uint32_t>(AFAMILY_VARIANT_COMPACT) ==
+              static_cast<uint32_t>(minikin::FamilyVariant::COMPACT));
+static_assert(static_cast<uint32_t>(AFAMILY_VARIANT_ELEGANT) ==
+              static_cast<uint32_t>(minikin::FamilyVariant::ELEGANT));
+
 namespace {
 
 std::string xmlTrim(const std::string& in) {
@@ -101,7 +116,7 @@
     return nullptr;
 }
 
-void copyFont(const XmlDocUniquePtr& xmlDoc, xmlNode* fontNode, ASystemFont* out,
+void copyFont(const XmlDocUniquePtr& xmlDoc, xmlNode* fontNode, AFont* out,
               const std::string& pathPrefix) {
     const xmlChar* LOCALE_ATTR_NAME = BAD_CAST("lang");
     XmlCharUniquePtr filePathStr(
@@ -197,24 +212,48 @@
     delete ite;
 }
 
-ASystemFont* ASystemFont_matchFamilyStyleCharacter(
-        const char* _Nonnull familyName,
+AFontMatcher* _Nonnull AFontMatcher_create() {
+    return new AFontMatcher();
+}
+
+void AFontMatcher_destroy(AFontMatcher* matcher) {
+    delete matcher;
+}
+
+void AFontMatcher_setStyle(
+        AFontMatcher* _Nonnull matcher,
         uint16_t weight,
-        bool italic,
-        const char* _Nonnull languageTags,
+        bool italic) {
+    matcher->mFontStyle = minikin::FontStyle(
+            weight, static_cast<minikin::FontStyle::Slant>(italic));
+}
+
+void AFontMatcher_setLocales(
+        AFontMatcher* _Nonnull matcher,
+        const char* _Nonnull languageTags) {
+    matcher->mLocaleListId = minikin::registerLocaleList(languageTags);
+}
+
+void AFontMatcher_setFamilyVariant(AFontMatcher* _Nonnull matcher, uint32_t familyVariant) {
+    matcher->mFamilyVariant = familyVariant;
+}
+
+AFont* _Nonnull AFontMatcher_match(
+        const AFontMatcher* _Nonnull matcher,
+        const char* _Nonnull familyName,
         const uint16_t* _Nonnull text,
-        uint32_t textLength,
+        const uint32_t textLength,
         uint32_t* _Nullable runLength) {
     std::shared_ptr<minikin::FontCollection> fc =
             minikin::SystemFonts::findFontCollection(familyName);
-    std::vector<minikin::FontCollection::Run> runs =
-            fc->itemize(minikin::U16StringPiece(text, textLength),
-                        minikin::FontStyle(weight, static_cast<minikin::FontStyle::Slant>(italic)),
-                        minikin::registerLocaleList(languageTags),
-                        minikin::FamilyVariant::DEFAULT);
+    std::vector<minikin::FontCollection::Run> runs = fc->itemize(
+                minikin::U16StringPiece(text, textLength),
+                matcher->mFontStyle,
+                matcher->mLocaleListId,
+                static_cast<minikin::FamilyVariant>(matcher->mFamilyVariant));
 
     const minikin::Font* font = runs[0].fakedFont.font;
-    std::unique_ptr<ASystemFont> result = std::make_unique<ASystemFont>();
+    std::unique_ptr<AFont> result = std::make_unique<AFont>();
     const android::MinikinFontSkia* minikinFontSkia =
             reinterpret_cast<android::MinikinFontSkia*>(font->typeface().get());
     result->mFilePath = minikinFontSkia->getFilePath();
@@ -253,7 +292,7 @@
     }
 }
 
-ASystemFont* ASystemFontIterator_next(ASystemFontIterator* ite) {
+AFont* ASystemFontIterator_next(ASystemFontIterator* ite) {
     LOG_ALWAYS_FATAL_IF(ite == nullptr, "nullptr has passed as iterator argument");
     if (ite->mXmlDoc) {
         ite->mFontNode = findNextFontNode(ite->mXmlDoc, ite->mFontNode);
@@ -262,7 +301,7 @@
             ite->mXmlDoc.reset();
             ite->mFontNode = nullptr;
         } else {
-            std::unique_ptr<ASystemFont> font = std::make_unique<ASystemFont>();
+            std::unique_ptr<AFont> font = std::make_unique<AFont>();
             copyFont(ite->mXmlDoc, ite->mFontNode, font.get(), "/system/fonts/");
             if (!isFontFileAvailable(font->mFilePath)) {
                 return ASystemFontIterator_next(ite);
@@ -279,7 +318,7 @@
             ite->mFontNode = nullptr;
             return nullptr;
         } else {
-            std::unique_ptr<ASystemFont> font = std::make_unique<ASystemFont>();
+            std::unique_ptr<AFont> font = std::make_unique<AFont>();
             copyFont(ite->mCustomizationXmlDoc, ite->mFontNode, font.get(), "/product/fonts/");
             if (!isFontFileAvailable(font->mFilePath)) {
                 return ASystemFontIterator_next(ite);
@@ -290,48 +329,48 @@
     return nullptr;
 }
 
-void ASystemFont_close(ASystemFont* font) {
+void AFont_close(AFont* font) {
     delete font;
 }
 
-const char* ASystemFont_getFontFilePath(const ASystemFont* font) {
+const char* AFont_getFontFilePath(const AFont* font) {
     LOG_ALWAYS_FATAL_IF(font == nullptr, "nullptr has passed as font argument");
     return font->mFilePath.c_str();
 }
 
-uint16_t ASystemFont_getWeight(const ASystemFont* font) {
+uint16_t AFont_getWeight(const AFont* font) {
     LOG_ALWAYS_FATAL_IF(font == nullptr, "nullptr has passed as font argument");
     return font->mWeight;
 }
 
-bool ASystemFont_isItalic(const ASystemFont* font) {
+bool AFont_isItalic(const AFont* font) {
     LOG_ALWAYS_FATAL_IF(font == nullptr, "nullptr has passed as font argument");
     return font->mItalic;
 }
 
-const char* ASystemFont_getLocale(const ASystemFont* font) {
+const char* AFont_getLocale(const AFont* font) {
     LOG_ALWAYS_FATAL_IF(font == nullptr, "nullptr has passed to font argument");
     return font->mLocale ? nullptr : font->mLocale->c_str();
 }
 
-size_t ASystemFont_getCollectionIndex(const ASystemFont* font) {
+size_t AFont_getCollectionIndex(const AFont* font) {
     LOG_ALWAYS_FATAL_IF(font == nullptr, "nullptr has passed to font argument");
     return font->mCollectionIndex;
 }
 
-size_t ASystemFont_getAxisCount(const ASystemFont* font) {
+size_t AFont_getAxisCount(const AFont* font) {
     LOG_ALWAYS_FATAL_IF(font == nullptr, "nullptr has passed to font argument");
     return font->mAxes.size();
 }
 
-uint32_t ASystemFont_getAxisTag(const ASystemFont* font, uint32_t axisIndex) {
+uint32_t AFont_getAxisTag(const AFont* font, uint32_t axisIndex) {
     LOG_ALWAYS_FATAL_IF(font == nullptr, "nullptr has passed to font argument");
     LOG_ALWAYS_FATAL_IF(axisIndex >= font->mAxes.size(),
                         "given axis index is out of bounds. (< %zd", font->mAxes.size());
     return font->mAxes[axisIndex].first;
 }
 
-float ASystemFont_getAxisValue(const ASystemFont* font, uint32_t axisIndex) {
+float AFont_getAxisValue(const AFont* font, uint32_t axisIndex) {
     LOG_ALWAYS_FATAL_IF(font == nullptr, "nullptr has passed to font argument");
     LOG_ALWAYS_FATAL_IF(axisIndex >= font->mAxes.size(),
                         "given axis index is out of bounds. (< %zd", font->mAxes.size());
diff --git a/opengl/java/android/opengl/GLUtils.java b/opengl/java/android/opengl/GLUtils.java
index d097335..ca8d5ac 100644
--- a/opengl/java/android/opengl/GLUtils.java
+++ b/opengl/java/android/opengl/GLUtils.java
@@ -44,7 +44,7 @@
         if (bitmap.isRecycled()) {
             throw new IllegalArgumentException("bitmap is recycled");
         }
-        int result = native_getInternalFormat(bitmap);
+        int result = native_getInternalFormat(bitmap.getNativeInstance());
         if (result < 0) {
             throw new IllegalArgumentException("Unknown internalformat");
         }
@@ -66,7 +66,7 @@
         if (bitmap.isRecycled()) {
             throw new IllegalArgumentException("bitmap is recycled");
         }
-        int result = native_getType(bitmap);
+        int result = native_getType(bitmap.getNativeInstance());
         if (result < 0) {
             throw new IllegalArgumentException("Unknown type");
         }
@@ -103,7 +103,8 @@
         if (bitmap.isRecycled()) {
             throw new IllegalArgumentException("bitmap is recycled");
         }
-        if (native_texImage2D(target, level, internalformat, bitmap, -1, border)!=0) {
+        if (native_texImage2D(target, level, internalformat, bitmap.getNativeInstance(), -1,
+                border) != 0) {
             throw new IllegalArgumentException("invalid Bitmap format");
         }
     }
@@ -129,7 +130,8 @@
         if (bitmap.isRecycled()) {
             throw new IllegalArgumentException("bitmap is recycled");
         }
-        if (native_texImage2D(target, level, internalformat, bitmap, type, border)!=0) {
+        if (native_texImage2D(target, level, internalformat, bitmap.getNativeInstance(), type,
+              border) != 0) {
             throw new IllegalArgumentException("invalid Bitmap format");
         }
     }
@@ -151,7 +153,7 @@
         if (bitmap.isRecycled()) {
             throw new IllegalArgumentException("bitmap is recycled");
         }
-        if (native_texImage2D(target, level, -1, bitmap, -1, border)!=0) {
+        if (native_texImage2D(target, level, -1, bitmap.getNativeInstance(), -1, border) != 0) {
             throw new IllegalArgumentException("invalid Bitmap format");
         }
     }
@@ -187,7 +189,8 @@
             throw new IllegalArgumentException("bitmap is recycled");
         }
         int type = getType(bitmap);
-        if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap, -1, type)!=0) {
+        if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap.getNativeInstance(), -1,
+                type) != 0) {
             throw new IllegalArgumentException("invalid Bitmap format");
         }
     }
@@ -211,7 +214,8 @@
         if (bitmap.isRecycled()) {
             throw new IllegalArgumentException("bitmap is recycled");
         }
-        if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap, format, type)!=0) {
+        if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap.getNativeInstance(),
+                format, type) != 0) {
             throw new IllegalArgumentException("invalid Bitmap format");
         }
     }
@@ -261,10 +265,10 @@
         }
     }
 
-    native private static int native_getInternalFormat(Bitmap bitmap);
-    native private static int native_getType(Bitmap bitmap);
+    native private static int native_getInternalFormat(long bitmapHandle);
+    native private static int native_getType(long bitmapHandle);
     native private static int native_texImage2D(int target, int level, int internalformat,
-            Bitmap bitmap, int type, int border);
+            long bitmapHandle, int type, int border);
     native private static int native_texSubImage2D(int target, int level, int xoffset, int yoffset,
-            Bitmap bitmap, int format, int type);
+            long bitmapHandle, int format, int type);
 }
diff --git a/packages/CaptivePortalLogin/Android.bp b/packages/CaptivePortalLogin/Android.bp
index bc614e9..a345091 100644
--- a/packages/CaptivePortalLogin/Android.bp
+++ b/packages/CaptivePortalLogin/Android.bp
@@ -23,6 +23,7 @@
     static_libs: [
         "androidx.legacy_legacy-support-v4",
         "metrics-constants-protos",
+        "captiveportal-lib",
     ],
     manifest: "AndroidManifest.xml",
 }
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
index 44e0a65..a528636 100644
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ b/packages/CaptivePortalLogin/AndroidManifest.xml
@@ -18,7 +18,7 @@
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.captiveportallogin"
-    android:versionCode="11"
+    android:versionCode="200000000"
     android:versionName="Q-initial">
 
     <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
diff --git a/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
index 395eac1..2fe9d21 100644
--- a/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -18,8 +18,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:fitsSystemWindows="true"
-    android:visibility="gone">
+    android:fitsSystemWindows="true">
 
     <LinearLayout
         android:id="@+id/container"
diff --git a/packages/CarSystemUI/res/layout/notification_center_activity.xml b/packages/CarSystemUI/res/layout/notification_center_activity.xml
index 383aba4..5c915b8 100644
--- a/packages/CarSystemUI/res/layout/notification_center_activity.xml
+++ b/packages/CarSystemUI/res/layout/notification_center_activity.xml
@@ -19,7 +19,8 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/notification_view"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:background="@color/notification_shade_background_color">
 
     <View
          android:id="@+id/glass_pane"
diff --git a/packages/CarSystemUI/res/layout/super_status_bar.xml b/packages/CarSystemUI/res/layout/super_status_bar.xml
index 0594dce..9a074dd 100644
--- a/packages/CarSystemUI/res/layout/super_status_bar.xml
+++ b/packages/CarSystemUI/res/layout/super_status_bar.xml
@@ -64,7 +64,6 @@
         <include layout="@layout/car_top_navigation_bar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_weight="1"
         />
     </LinearLayout>
 
@@ -80,6 +79,13 @@
         android:layout_height="match_parent"
         android:visibility="invisible"/>
 
+    <include layout="@layout/notification_center_activity"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent"
+             android:layout_marginBottom="112dp"
+             android:visibility="invisible"
+    />
+
     <com.android.systemui.statusbar.ScrimView
         android:id="@+id/scrim_in_front"
         android:layout_width="match_parent"
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index c9f9dea..d946fbc 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -21,6 +21,7 @@
     <string name="config_systemUIFactoryComponent" translatable="false">
         com.android.systemui.CarSystemUIFactory
     </string>
+
     <bool name="config_enableFullscreenUserSwitcher">true</bool>
 
     <!-- configure which system ui bars should be displayed -->
@@ -28,30 +29,12 @@
     <bool name="config_enableRightNavigationBar">false</bool>
     <bool name="config_enableBottomNavigationBar">true</bool>
 
-    <!-- SystemUI Services: The classes of the stuff to start. This is duplicated from core
-         SystemUi b/c it can't be overlayed at this level for now
-    -->
-    <string-array name="config_systemUIServiceComponents" translatable="false">
-        <item>com.android.systemui.Dependency$DependencyCreator</item>
-        <item>com.android.systemui.util.NotificationChannels</item>
-        <item>com.android.systemui.notifications.NotificationsUI</item>
-        <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
-        <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
-        <item>com.android.systemui.recents.Recents</item>
-        <item>com.android.systemui.volume.VolumeUI</item>
-        <item>com.android.systemui.stackdivider.Divider</item>
-        <item>com.android.systemui.SystemBars</item>
-        <item>com.android.systemui.usb.StorageNotification</item>
-        <item>com.android.systemui.power.PowerUI</item>
-        <item>com.android.systemui.media.RingtonePlayer</item>
-        <item>com.android.systemui.keyboard.KeyboardUI</item>
-        <item>com.android.systemui.pip.PipUI</item>
-        <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
-        <item>@string/config_systemUIVendorServiceComponent</item>
-        <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
-        <item>com.android.systemui.LatencyTester</item>
-        <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
-        <item>com.android.systemui.ScreenDecorations</item>
-        <item>com.android.systemui.SliceBroadcastRelayHandler</item>
-    </string-array>
+    <bool name="config_hideNavWhenKeyguardBouncerShown">true</bool>
+    <bool name="config_enablePersistentDockedActivity">false</bool>
+    <string name="config_persistentDockedActivityIntentUri" translatable="false"></string>
+
+    <!-- How many icons may be shown at once in the system bar. Includes any
+         slots that may be reused for things like IME control. -->
+    <integer name="config_maxNotificationIcons">0</integer>
+
 </resources>
diff --git a/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java b/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java
deleted file mode 100644
index 48cb55b..0000000
--- a/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.notifications;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.annotation.SuppressLint;
-import android.app.ActivityManager;
-import android.car.Car;
-import android.car.CarNotConnectedException;
-import android.car.drivingstate.CarUxRestrictionsManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ServiceConnection;
-import android.content.res.Configuration;
-import android.graphics.PixelFormat;
-import android.os.IBinder;
-import android.os.ServiceManager;
-import android.util.Log;
-import android.view.ContextThemeWrapper;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.WindowManager;
-
-import androidx.annotation.NonNull;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.car.notification.CarNotificationListener;
-import com.android.car.notification.CarNotificationView;
-import com.android.car.notification.CarUxRestrictionManagerWrapper;
-import com.android.car.notification.NotificationClickHandlerFactory;
-import com.android.car.notification.NotificationViewController;
-import com.android.car.notification.PreprocessingManager;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-import com.android.systemui.SystemUI;
-import com.android.systemui.statusbar.FlingAnimationUtils;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-
-/**
- * Standalone SystemUI for displaying Notifications that have been designed to be used in the car
- */
-public class NotificationsUI extends SystemUI
-        implements ConfigurationController.ConfigurationListener {
-
-    private static final String TAG = "NotificationsUI";
-    // used to calculate how fast to open or close the window
-    private static final float DEFAULT_FLING_VELOCITY = 0;
-    // max time a fling animation takes
-    private static final float FLING_ANIMATION_MAX_TIME = 0.5f;
-    // acceleration rate for the fling animation
-    private static final float FLING_SPEED_UP_FACTOR = 0.6f;
-    private CarNotificationListener mCarNotificationListener;
-    private CarUxRestrictionsManager mCarUxRestrictionsManager;
-    private NotificationClickHandlerFactory mClickHandlerFactory;
-    private Car mCar;
-    private ViewGroup mCarNotificationWindow;
-    private NotificationViewController mNotificationViewController;
-    private boolean mIsShowing;
-    private boolean mIsTracking;
-    private boolean mNotificationListAtBottom;
-    private boolean mNotificationListAtBottomAtTimeOfTouch;
-    private CarUxRestrictionManagerWrapper mCarUxRestrictionManagerWrapper =
-            new CarUxRestrictionManagerWrapper();
-    // Used in the Notification panel touch listener
-    private GestureDetector mGestureDetector;
-    // Used in scrollable content of the notifications
-    private GestureDetector mScrollUpDetector;
-    private View mContent;
-    private View.OnTouchListener mOnTouchListener;
-    private FlingAnimationUtils mFlingAnimationUtils;
-    private static int sSettleOpenPercentage;
-    private static int sSettleClosePercentage;
-
-    /**
-     * Inits the window that hosts the notifications and establishes the connections
-     * to the car related services.
-     */
-    @Override
-    public void start() {
-        sSettleOpenPercentage = mContext.getResources().getInteger(
-                R.integer.notification_settle_open_percentage);
-        sSettleClosePercentage = mContext.getResources().getInteger(
-                R.integer.notification_settle_close_percentage);
-        WindowManager windowManager =
-                (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-        mFlingAnimationUtils = new FlingAnimationUtils(mContext,
-                FLING_ANIMATION_MAX_TIME, FLING_SPEED_UP_FACTOR);
-        mCarNotificationListener = new CarNotificationListener();
-        // create a notification click handler that closes the notification ui if the an activity
-        // is launched successfully
-        mClickHandlerFactory = new NotificationClickHandlerFactory(
-                IStatusBarService.Stub.asInterface(
-                        ServiceManager.getService(Context.STATUS_BAR_SERVICE)),
-                launchResult -> {
-                    if (launchResult == ActivityManager.START_TASK_TO_FRONT
-                            || launchResult == ActivityManager.START_SUCCESS) {
-                        closeCarNotifications(DEFAULT_FLING_VELOCITY);
-                    }
-                });
-        mCarNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper,
-                mClickHandlerFactory);
-        mCar = Car.createCar(mContext, mCarConnectionListener);
-        mCar.connect();
-        NotificationGestureListener gestureListener = new NotificationGestureListener();
-        mGestureDetector = new GestureDetector(mContext, gestureListener);
-        mScrollUpDetector = new GestureDetector(mContext, new ScrollUpDetector());
-        mOnTouchListener = new NotificationPanelTouchListener();
-        mCarNotificationWindow = (ViewGroup) View.inflate(new ContextThemeWrapper(mContext,
-                        R.style.Theme_Notification),
-                R.layout.navigation_bar_window, null);
-        mCarNotificationWindow
-                .setBackgroundColor(mContext.getColor(R.color.notification_shade_background_color));
-        inflateNotificationContent();
-
-        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                PixelFormat.TRANSLUCENT);
-        layoutParams.setTitle("Car Notification Window");
-        // start in the hidden state
-        mCarNotificationWindow.setVisibility(View.GONE);
-        windowManager.addView(mCarNotificationWindow, layoutParams);
-
-        // Add this object to the SystemUI component registry such that the status bar
-        // can get a reference to it.
-        putComponent(NotificationsUI.class, this);
-        Dependency.get(ConfigurationController.class).addCallback(this);
-    }
-
-    @SuppressLint("ClickableViewAccessibility")
-    private void inflateNotificationContent() {
-        if (mNotificationViewController != null) {
-            mNotificationViewController.disable();
-        }
-        mCarNotificationWindow.removeAllViews();
-
-        mContent = View.inflate(new ContextThemeWrapper(mContext,
-                        com.android.car.notification.R.style.Theme_Notification),
-                R.layout.notification_center_activity,
-                mCarNotificationWindow);
-        // set the click handler such that we can dismiss the UI when a notification is clicked
-        CarNotificationView noteView = mCarNotificationWindow.findViewById(R.id.notification_view);
-        noteView.setClickHandlerFactory(mClickHandlerFactory);
-
-        mContent.setOnTouchListener(mOnTouchListener);
-        // set initial translation after size is calculated
-        mContent.getViewTreeObserver().addOnGlobalLayoutListener(
-                new ViewTreeObserver.OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        mContent.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                        if (!mIsShowing && !mIsTracking) {
-                            mContent.setTranslationY(mContent.getHeight() * -1);
-                        }
-                    }
-                });
-
-        RecyclerView notificationList = mCarNotificationWindow.findViewById(R.id.notifications);
-        // register a scroll listener so we can figure out if we are at the bottom of the
-        // list of notifications
-        notificationList.addOnScrollListener(new RecyclerView.OnScrollListener() {
-            @Override
-            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
-                super.onScrolled(recyclerView, dx, dy);
-                if (!notificationList.canScrollVertically(1)) {
-                    mNotificationListAtBottom = true;
-                    return;
-                }
-                mNotificationListAtBottom = false;
-                mNotificationListAtBottomAtTimeOfTouch = false;
-            }
-        });
-        // add a touch listener such that when the user scrolls up and they are at the bottom
-        // of the list we can start the closing of the view.
-        notificationList.setOnTouchListener(new NotificationListTouchListener());
-
-        // There's a view installed at a higher z-order such that we can intercept the ACTION_DOWN
-        // to set the initial click state.
-        mCarNotificationWindow.findViewById(R.id.glass_pane).setOnTouchListener((v, event) -> {
-            if (event.getActionMasked() == MotionEvent.ACTION_UP) {
-                mNotificationListAtBottomAtTimeOfTouch = false;
-            }
-            if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-                mNotificationListAtBottomAtTimeOfTouch = mNotificationListAtBottom;
-                // register the down event with the gesture detectors so then know where the down
-                // started. This is needed because at this point we don't know which listener
-                // is going to handle scroll and fling events.
-                mGestureDetector.onTouchEvent(event);
-                mScrollUpDetector.onTouchEvent(event);
-            }
-            return false;
-        });
-
-        mNotificationViewController = new NotificationViewController(
-                mCarNotificationWindow
-                        .findViewById(com.android.car.notification.R.id.notification_view),
-                PreprocessingManager.getInstance(mContext),
-                mCarNotificationListener,
-                mCarUxRestrictionManagerWrapper);
-        mNotificationViewController.enable();
-    }
-
-    // allows for day night switch
-    @Override
-    public void onConfigChanged(Configuration newConfig) {
-        inflateNotificationContent();
-    }
-
-    public View.OnTouchListener getDragDownListener() {
-        return mOnTouchListener;
-    }
-
-    /**
-     * This listener is attached to the notification list UI to intercept gestures if the user
-     * is scrolling up when the notification list is at the bottom
-     */
-    private class ScrollUpDetector extends GestureDetector.SimpleOnGestureListener {
-
-        @Override
-        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-            return distanceY > 0;
-        }
-
-        @Override
-        public boolean onSingleTapUp(MotionEvent motionEvent) {
-            closeCarNotifications(DEFAULT_FLING_VELOCITY);
-            return false;
-        }
-    }
-
-    private class NotificationListTouchListener implements View.OnTouchListener {
-
-        @Override
-        public boolean onTouch(View v, MotionEvent event) {
-            // reset mNotificationListAtBottomAtTimeOfTouch here since the "glass pane" will not
-            // get the up event
-            if (event.getActionMasked() == MotionEvent.ACTION_UP) {
-                mNotificationListAtBottomAtTimeOfTouch = false;
-            }
-            boolean wasScrolledUp = mScrollUpDetector.onTouchEvent(event);
-
-            if (mIsTracking
-                    || (mNotificationListAtBottomAtTimeOfTouch && mNotificationListAtBottom
-                    && wasScrolledUp)) {
-                mOnTouchListener.onTouch(v, event);
-                // touch event should not be propagated further
-                return true;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Touch listener installed on the notification panel. It is also used by the Nav and StatusBar
-     */
-    private class NotificationPanelTouchListener implements View.OnTouchListener {
-
-        @Override
-        public boolean onTouch(View v, MotionEvent event) {
-            boolean consumed = mGestureDetector.onTouchEvent(event);
-            if (consumed) {
-                return true;
-            }
-            if (!mIsTracking || event.getActionMasked() != MotionEvent.ACTION_UP) {
-                return false;
-            }
-
-            float percentFromBottom =
-                    Math.abs(mContent.getTranslationY() / mContent.getHeight()) * 100;
-            if (mIsShowing) {
-                if (percentFromBottom < sSettleOpenPercentage) {
-                    // panel started to close but did not cross minimum threshold thus we open
-                    // it back up
-                    openCarNotifications(DEFAULT_FLING_VELOCITY);
-                    return true;
-                }
-                // panel was lifted more than the threshold thus we close it the rest of the way
-                closeCarNotifications(DEFAULT_FLING_VELOCITY);
-                return true;
-            }
-
-            if (percentFromBottom > sSettleClosePercentage) {
-                // panel was only peeked at thus close it back up
-                closeCarNotifications(DEFAULT_FLING_VELOCITY);
-                return true;
-            }
-            // panel has been open more than threshold thus open it the rest of the way
-            openCarNotifications(DEFAULT_FLING_VELOCITY);
-            return true;
-
-        }
-    }
-
-    /**
-     * Listener called by mGestureDetector. This will be initiated from the
-     * NotificationPanelTouchListener
-     */
-    private class NotificationGestureListener extends GestureDetector.SimpleOnGestureListener {
-        private static final int SWIPE_UP_MIN_DISTANCE = 75;
-        private static final int SWIPE_DOWN_MIN_DISTANCE = 25;
-        private static final int SWIPE_MAX_OFF_PATH = 75;
-        private static final int SWIPE_THRESHOLD_VELOCITY = 200;
-
-        @Override
-        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
-                float distanceY) {
-            boolean isDown = event1.getY() - event2.getY() < 0;
-            // CarStatusBar and NavigationBar are identical so avoid the touch if it
-            // starts from NavigationBar to open.
-            if (event1.getRawY() > mCarNotificationWindow.getHeight() && isDown
-                    && mCarNotificationWindow.getVisibility() == View.GONE) {
-                mIsTracking = false;
-                return true;
-            }
-            mIsTracking = true;
-            mCarNotificationWindow.setVisibility(View.VISIBLE);
-
-            mContent.setTranslationY(Math.min(mContent.getTranslationY() - distanceY, 0));
-            if (mContent.getTranslationY() == 0) {
-                mIsTracking = false;
-            }
-            return true;
-        }
-
-        @Override
-        public boolean onFling(MotionEvent event1, MotionEvent event2,
-                float velocityX, float velocityY) {
-            if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH
-                    || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) {
-                // swipe was not vertical or was not fast enough
-                return false;
-            }
-
-            boolean isUp = velocityY < 0;
-            float distanceDelta = Math.abs(event1.getY() - event2.getY());
-            if (isUp && distanceDelta > SWIPE_UP_MIN_DISTANCE) {
-                // fling up
-                mIsTracking = false;
-                closeCarNotifications(Math.abs(velocityY));
-                return true;
-
-            } else if (!isUp && distanceDelta > SWIPE_DOWN_MIN_DISTANCE
-                    && (event1.getRawY() < mCarNotificationWindow.getHeight()
-                    || mCarNotificationWindow.getVisibility() == View.VISIBLE)) {
-                // fling down
-                mIsTracking = false;
-                openCarNotifications(velocityY);
-                return true;
-            }
-
-            return false;
-        }
-    }
-
-    /**
-     * Connection callback to establish UX Restrictions
-     */
-    private ServiceConnection mCarConnectionListener = new ServiceConnection() {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            try {
-                mCarUxRestrictionsManager = (CarUxRestrictionsManager) mCar.getCarManager(
-                        Car.CAR_UX_RESTRICTION_SERVICE);
-                mCarUxRestrictionManagerWrapper
-                        .setCarUxRestrictionsManager(mCarUxRestrictionsManager);
-                PreprocessingManager preprocessingManager = PreprocessingManager.getInstance(
-                        mContext);
-                preprocessingManager
-                        .setCarUxRestrictionManagerWrapper(mCarUxRestrictionManagerWrapper);
-            } catch (CarNotConnectedException e) {
-                Log.e(TAG, "Car not connected in CarConnectionListener", e);
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            Log.e(TAG, "Car service disconnected unexpectedly");
-        }
-    };
-
-    /**
-     * Toggles the visibility of the notifications
-     */
-    public void toggleShowingCarNotifications() {
-        if (mCarNotificationWindow.getVisibility() == View.VISIBLE) {
-            closeCarNotifications(DEFAULT_FLING_VELOCITY);
-            return;
-        }
-        openCarNotifications(DEFAULT_FLING_VELOCITY);
-    }
-
-    /**
-     * Hides the notifications
-     */
-    public void closeCarNotifications(float velocityY) {
-        float closedTranslation = mContent.getHeight() * -1;
-        ValueAnimator animator =
-                ValueAnimator.ofFloat(mContent.getTranslationY(), closedTranslation);
-        animator.addUpdateListener(
-                animation -> mContent.setTranslationY((Float) animation.getAnimatedValue()));
-        mFlingAnimationUtils.apply(
-                animator, mContent.getTranslationY(), closedTranslation, velocityY);
-        animator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mCarNotificationWindow.setVisibility(View.GONE);
-            }
-        });
-        animator.start();
-        mNotificationViewController.disable();
-        mIsShowing = false;
-        mIsTracking = false;
-        RecyclerView notificationListView = mCarNotificationWindow.findViewById(R.id.notifications);
-        notificationListView.scrollToPosition(0);
-    }
-
-    /**
-     * Sets the notifications to visible
-     */
-    public void openCarNotifications(float velocityY) {
-        mCarNotificationWindow.setVisibility(View.VISIBLE);
-
-        ValueAnimator animator = ValueAnimator.ofFloat(mContent.getTranslationY(), 0);
-        animator.addUpdateListener(
-                animation -> mContent.setTranslationY((Float) animation.getAnimatedValue()));
-        mFlingAnimationUtils.apply(animator, mContent.getTranslationY(), 0, velocityY);
-        animator.start();
-
-        mNotificationViewController.enable();
-        mIsShowing = true;
-        mIsTracking = false;
-    }
-}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
index afefa1b..a0f2367 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
@@ -38,6 +38,7 @@
     private CarStatusBar mCarStatusBar;
     private Context mContext;
     private View mLockScreenButtons;
+    // used to wire in open/close gestures for notifications
     private OnTouchListener mStatusBarWindowTouchListener;
 
 
@@ -65,26 +66,45 @@
             mDarkIconManager.setShouldLog(true);
             Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
         }
+        // needs to be clickable so that it will receive ACTION_MOVE events
+        setClickable(true);
     }
 
+    // Used to forward touch events even if the touch was initiated from a child component
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (mStatusBarWindowTouchListener == null) {
-            return false;
+        if (mStatusBarWindowTouchListener != null) {
+            // forward touch events to the status bar window so it can add a drag down
+            // windows if required (Notification shade)
+            mStatusBarWindowTouchListener.onTouch(this, ev);
         }
-        // forward touch events to the status bar window so it can add a drag down
-        // windows if required (Notification shade)
-        mStatusBarWindowTouchListener.onTouch(this, ev);
-        return false;
+        return super.onInterceptTouchEvent(ev);
     }
 
+
     void setStatusBar(CarStatusBar carStatusBar) {
         mCarStatusBar = carStatusBar;
-        mStatusBarWindowTouchListener = carStatusBar.getStatusBarWindowTouchListener();
+    }
+
+    /**
+     * Set a touch listener that will be called from onInterceptTouchEvent and onTouchEvent
+     *
+     * @param statusBarWindowTouchListener The listener to call from touch and intercept touch
+     */
+    void setStatusBarWindowTouchListener(OnTouchListener statusBarWindowTouchListener) {
+        mStatusBarWindowTouchListener = statusBarWindowTouchListener;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (mStatusBarWindowTouchListener != null) {
+            mStatusBarWindowTouchListener.onTouch(this, event);
+        }
+        return super.onTouchEvent(event);
     }
 
     protected void onNotificationsClick(View v) {
-        mCarStatusBar.toggleCarNotifications();
+        mCarStatusBar.togglePanel();
     }
 
     /**
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 45459fc..9bcc1ab 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -16,17 +16,29 @@
 
 package com.android.systemui.statusbar.car;
 
+import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.car.drivingstate.CarDrivingStateEvent;
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
 import android.util.Log;
+import android.view.GestureDetector;
 import android.view.Gravity;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.car.notification.CarNotificationListener;
+import com.android.car.notification.CarNotificationView;
+import com.android.car.notification.CarUxRestrictionManagerWrapper;
+import com.android.car.notification.NotificationClickHandlerFactory;
+import com.android.car.notification.NotificationViewController;
+import com.android.car.notification.PreprocessingManager;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.CarSystemUIFactory;
@@ -37,7 +49,6 @@
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.notifications.NotificationsUI;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -70,7 +81,6 @@
     private BatteryMeterView mBatteryMeterView;
     private Drawable mNotificationPanelBackground;
 
-    private ConnectedDeviceSignalController mConnectedDeviceSignalController;
     private ViewGroup mNavigationBarWindow;
     private ViewGroup mLeftNavigationBarWindow;
     private ViewGroup mRightNavigationBarWindow;
@@ -90,6 +100,17 @@
     private DrivingStateHelper mDrivingStateHelper;
     private SwitchToGuestTimer mSwitchToGuestTimer;
 
+    // The container for the notifications.
+    private CarNotificationView mNotificationView;
+    private RecyclerView mNotificationList;
+    // The state of if the notification list is currently showing the bottom.
+    private boolean mNotificationListAtBottom;
+    // Was the notification list at the bottom when the user first touched the screen
+    private boolean mNotificationListAtBottomAtTimeOfTouch;
+    // To be attached to the navigation bars such that they can close the notification panel if
+    // it's open.
+    private View.OnTouchListener mNavBarNotificationTouchListener;
+
     @Override
     public void start() {
         // get the provisioned state before calling the parent class since it's that flow that
@@ -223,7 +244,6 @@
      * Switch to the keyguard applicable content contained in the nav bars
      */
     private void updateNavBarForKeyguardContent() {
-        getComponent(NotificationsUI.class).closeCarNotifications(0);
         if (mNavigationBarView != null) {
             mNavigationBarView.showKeyguardButtons();
         }
@@ -255,16 +275,150 @@
             // when a device has connected by bluetooth.
             mBatteryMeterView.setVisibility(View.GONE);
         });
-        addTemperatureViewToController(mStatusBarWindow);
+
+        connectNotificationsUI();
+    }
+
+    /**
+     * Attach the notification listeners and controllers to the UI as well as build all the
+     * touch listeners needed for opening and closing the notification panel
+     */
+    private void connectNotificationsUI() {
+        // Attached to the status bar to detect pull down of the notification shade.
+        GestureDetector openGestureDetector = new GestureDetector(mContext,
+                new OpenNotificationGestureListener() {
+                    @Override
+                    protected void openNotification() {
+                        animateExpandNotificationsPanel();
+                    }
+                });
+        // Attached to the notification ui to detect close request of the notification shade.
+        GestureDetector closeGestureDetector = new GestureDetector(mContext,
+                new CloseNotificationGestureListener() {
+                    @Override
+                    protected void close() {
+                        animateCollapsePanels();
+                    }
+                });
+        // Attached to the NavBars to close the notification shade
+        GestureDetector navBarCloseNotificationGestureDetector = new GestureDetector(mContext,
+                new NavBarCloseNotificationGestureListener() {
+                    @Override
+                    protected void close() {
+                        animateCollapsePanels();
+                    }
+                });
+        mNavBarNotificationTouchListener =
+                (v, event) -> navBarCloseNotificationGestureDetector.onTouchEvent(event);
+
         // The following are the ui elements that the user would call the status bar.
         // This will set the status bar so it they can make call backs.
         CarNavigationBarView topBar = mStatusBarWindow.findViewById(R.id.car_top_bar);
         topBar.setStatusBar(this);
-        CarNavigationBarView qsTopBar = mStatusBarWindow.findViewById(R.id.qs_car_top_bar);
-        qsTopBar.setStatusBar(this);
+        topBar.setStatusBarWindowTouchListener((v1, event1) ->
+                openGestureDetector.onTouchEvent(event1));
+
+        NotificationClickHandlerFactory clickHandlerFactory = new NotificationClickHandlerFactory(
+                mBarService,
+                launchResult -> {
+                    if (launchResult == ActivityManager.START_TASK_TO_FRONT
+                            || launchResult == ActivityManager.START_SUCCESS) {
+                        animateCollapsePanels();
+                    }
+                });
+        CarNotificationListener carNotificationListener = new CarNotificationListener();
+        CarUxRestrictionManagerWrapper carUxRestrictionManagerWrapper =
+                new CarUxRestrictionManagerWrapper();
+        carNotificationListener.registerAsSystemService(mContext, carUxRestrictionManagerWrapper,
+                clickHandlerFactory);
+
+        mNotificationView = mStatusBarWindow.findViewById(R.id.notification_view);
+        View glassPane = mStatusBarWindow.findViewById(R.id.glass_pane);
+        mNotificationView.setClickHandlerFactory(clickHandlerFactory);
+
+        // The glass pane is used to view touch events before passed to the notification list.
+        // This allows us to initialize gesture listeners and detect when to close the notifications
+        glassPane.setOnTouchListener((v, event) -> {
+            if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+                mNotificationListAtBottomAtTimeOfTouch = false;
+            }
+            if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+                mNotificationListAtBottomAtTimeOfTouch = mNotificationListAtBottom;
+                // Pass the down event to gesture detector so that it knows where the touch event
+                // started.
+                closeGestureDetector.onTouchEvent(event);
+            }
+            return false;
+        });
+        mNotificationList = mNotificationView.findViewById(R.id.notifications);
+        mNotificationList.addOnScrollListener(new RecyclerView.OnScrollListener() {
+            @Override
+            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
+                super.onScrolled(recyclerView, dx, dy);
+                if (!mNotificationList.canScrollVertically(1)) {
+                    mNotificationListAtBottom = true;
+                    return;
+                }
+                mNotificationListAtBottom = false;
+                mNotificationListAtBottomAtTimeOfTouch = false;
+            }
+        });
+        mNotificationList.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                boolean handled = false;
+                if (mNotificationListAtBottomAtTimeOfTouch && mNotificationListAtBottom) {
+                    handled = closeGestureDetector.onTouchEvent(event);
+                }
+                // Updating the mNotificationListAtBottomAtTimeOfTouch state has to be done after
+                // the event has been passed to the closeGestureDetector above, such that the
+                // closeGestureDetector sees the up event before the state has changed.
+                if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+                    mNotificationListAtBottomAtTimeOfTouch = false;
+                }
+                return handled;
+            }
+        });
+
+        NotificationViewController mNotificationViewController = new NotificationViewController(
+                mNotificationView,
+                PreprocessingManager.getInstance(mContext),
+                carNotificationListener,
+                carUxRestrictionManagerWrapper);
+        mNotificationViewController.enable();
     }
 
     @Override
+    public void animateExpandNotificationsPanel() {
+        if (!mCommandQueue.panelsEnabled() || !mUserSetup) {
+            return;
+        }
+        // scroll to top
+        mNotificationList.scrollToPosition(0);
+        mStatusBarWindowController.setPanelVisible(true);
+        mNotificationView.setVisibility(View.VISIBLE);
+        // let the status bar know that the panel is open
+        setPanelExpanded(true);
+    }
+
+    @Override
+    public void animateCollapsePanels(int flags, boolean force, boolean delayed,
+            float speedUpFactor) {
+        super.animateCollapsePanels(flags, force, delayed, speedUpFactor);
+        if (!mPanelExpanded || mNotificationView.getVisibility() == View.INVISIBLE) {
+            return;
+        }
+        mStatusBarWindowController.setStatusBarFocusable(false);
+        mStatusBarWindow.cancelExpandHelper();
+        mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
+        mStatusBarWindowController.setPanelVisible(false);
+        mNotificationView.setVisibility(View.INVISIBLE);
+        // let the status bar know that the panel is cloased
+        setPanelExpanded(false);
+    }
+
+
+    @Override
     protected QS createDefaultQSFragment() {
         return new CarQSFragment();
     }
@@ -337,8 +491,8 @@
             lp.setTitle("CarNavigationBar");
             lp.windowAnimations = 0;
             mWindowManager.addView(mNavigationBarWindow, lp);
-            mNavigationBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
         }
+
         if (mShowLeft) {
             int width = mContext.getResources().getDimensionPixelSize(
                     R.dimen.car_left_navigation_bar_width);
@@ -388,6 +542,7 @@
         }
         mNavigationBarView.setStatusBar(this);
         addTemperatureViewToController(mNavigationBarView);
+        mNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener);
     }
 
     private void buildLeft(int layout) {
@@ -399,6 +554,7 @@
         }
         mLeftNavigationBarView.setStatusBar(this);
         addTemperatureViewToController(mLeftNavigationBarView);
+        mLeftNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener);
     }
 
 
@@ -411,6 +567,7 @@
         }
         mRightNavigationBarView.setStatusBar(this);
         addTemperatureViewToController(mRightNavigationBarView);
+        mRightNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener);
     }
 
     @Override
@@ -434,8 +591,6 @@
         pw.println(mCarBatteryController);
         pw.print("  mBatteryMeterView=");
         pw.println(mBatteryMeterView);
-        pw.print("  mConnectedDeviceSignalController=");
-        pw.println(mConnectedDeviceSignalController);
         pw.print("  mNavigationBarView=");
         pw.println(mNavigationBarView);
 
@@ -455,11 +610,6 @@
         }
     }
 
-    @Override
-    protected View.OnTouchListener getStatusBarWindowTouchListener() {
-        // Gets the car specific notification touch listener
-        return getComponent(NotificationsUI.class).getDragDownListener();
-    }
 
     @Override
     public void showBatteryView() {
@@ -584,15 +734,6 @@
                 true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
     }
 
-    @Override
-    public void animateExpandNotificationsPanel() {
-        // Because space is usually constrained in the auto use-case, there should not be a
-        // pinned notification when the shade has been expanded. Ensure this by removing all heads-
-        // up notifications.
-        mHeadsUpManager.releaseAllImmediately();
-        super.animateExpandNotificationsPanel();
-    }
-
     /**
      * Ensures that relevant child views are appropriately recreated when the device's density
      * changes.
@@ -614,12 +755,78 @@
         return mContext.getDrawable(com.android.internal.R.drawable.default_wallpaper);
     }
 
-    public void toggleCarNotifications() {
-        getComponent(NotificationsUI.class).toggleShowingCarNotifications();
+    /** Returns true if the current user makes it through the setup wizard, false otherwise. */
+    public boolean getIsUserSetup(){
+        return mUserSetup;
     }
 
-    @Override
-    public void maybeEscalateHeadsUp() {
-        // Never send full screen intent in car.
+
+    // TODO: add settle down/up logic
+    private static final int SWIPE_UP_MIN_DISTANCE = 75;
+    private static final int SWIPE_DOWN_MIN_DISTANCE = 25;
+    private static final int SWIPE_MAX_OFF_PATH = 75;
+    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
+    // Only responsible for open hooks. Since once the panel opens it covers all elements
+    // there is no need to merge with close.
+    private abstract class OpenNotificationGestureListener extends
+            GestureDetector.SimpleOnGestureListener {
+
+        @Override
+        public boolean onFling(MotionEvent event1, MotionEvent event2,
+                float velocityX, float velocityY) {
+            if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH
+                    || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) {
+                // swipe was not vertical or was not fast enough
+                return false;
+            }
+            boolean isDown = velocityY > 0;
+            float distanceDelta = Math.abs(event1.getY() - event2.getY());
+            if (isDown && distanceDelta > SWIPE_DOWN_MIN_DISTANCE) {
+                openNotification();
+                return true;
+            }
+
+            return false;
+        }
+        protected abstract void openNotification();
+    }
+
+    // to be installed on the open panel notification panel
+    private abstract class CloseNotificationGestureListener extends
+            GestureDetector.SimpleOnGestureListener {
+
+        @Override
+        public boolean onFling(MotionEvent event1, MotionEvent event2,
+                float velocityX, float velocityY) {
+            if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH
+                    || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) {
+                // swipe was not vertical or was not fast enough
+                return false;
+            }
+            boolean isUp = velocityY < 0;
+            float distanceDelta = Math.abs(event1.getY() - event2.getY());
+            if (isUp && distanceDelta > SWIPE_UP_MIN_DISTANCE) {
+                close();
+                return true;
+            }
+            return false;
+        }
+        protected abstract void close();
+    }
+
+    // to be installed on the nav bars
+    private abstract class NavBarCloseNotificationGestureListener extends
+            CloseNotificationGestureListener {
+        @Override
+        public boolean onSingleTapUp(MotionEvent e) {
+            close();
+            return super.onSingleTapUp(e);
+        }
+
+        @Override
+        public void onLongPress(MotionEvent e) {
+            close();
+            super.onLongPress(e);
+        }
     }
 }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index f896cf1..0a167d9 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -38,7 +38,9 @@
     public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub, Context context) {
         mStatusBar = statusBar;
         mParent = containerStub.inflate();
-        mParent.setVisibility(View.VISIBLE);
+        // Hide the user grid by default. It will only be made visible by clicking on a cancel
+        // button in a bouncer.
+        hide();
         View container = mParent.findViewById(R.id.container);
 
         // Initialize user grid.
@@ -49,10 +51,6 @@
         mUserGridView.buildAdapter();
         mUserGridView.setUserSelectionListener(this::onUserSelected);
 
-        // Hide the user grid by default. It will only be made visible by clicking on a cancel
-        // button in a bouncer.
-        hide();
-
         mShortAnimDuration = container.getResources()
                 .getInteger(android.R.integer.config_shortAnimTime);
     }
@@ -61,21 +59,21 @@
      * Makes user grid visible.
      */
     public void show() {
-        mUserGridView.setVisibility(View.VISIBLE);
+        mParent.setVisibility(View.VISIBLE);
     }
 
     /**
      * Hides the user grid.
      */
     public void hide() {
-        mUserGridView.setVisibility(View.INVISIBLE);
+        mParent.setVisibility(View.INVISIBLE);
     }
 
     /**
      * @return {@code true} if user grid is visible, {@code false} otherwise.
      */
     public boolean isVisible() {
-        return mUserGridView.getVisibility() == View.VISIBLE;
+        return mParent.getVisibility() == View.VISIBLE;
     }
 
     /**
diff --git a/packages/DynamicSystemInstallationService/AndroidManifest.xml b/packages/DynamicSystemInstallationService/AndroidManifest.xml
index 2911117..d718eae 100644
--- a/packages/DynamicSystemInstallationService/AndroidManifest.xml
+++ b/packages/DynamicSystemInstallationService/AndroidManifest.xml
@@ -16,7 +16,7 @@
             android:name=".DynamicSystemInstallationService"
             android:enabled="true"
             android:exported="true"
-            android:permission="android.permission.MANAGE_DYNAMIC_SYSTEM"
+            android:permission="android.permission.INSTALL_DYNAMIC_SYSTEM"
             android:process=":dynsystem">
             <intent-filter>
                 <action android:name="android.os.image.action.NOTIFY_IF_IN_USE" />
@@ -26,7 +26,7 @@
 
         <activity android:name=".VerificationActivity"
             android:exported="true"
-            android:permission="android.permission.MANAGE_DYNAMIC_SYSTEM"
+            android:permission="android.permission.INSTALL_DYNAMIC_SYSTEM"
             android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar"
             android:process=":dynsystem">
             <intent-filter>
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
index 38576ee..ea7b378 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
@@ -19,8 +19,10 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.image.DynamicSystemClient;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 
 
@@ -35,6 +37,10 @@
 
     @Override
     public void onReceive(Context context, Intent intent) {
+        if (!featureFlagEnabled()) {
+            return;
+        }
+
         String action = intent.getAction();
 
         Log.d(TAG, "Broadcast received: " + action);
@@ -47,4 +53,9 @@
             context.startServiceAsUser(startServiceIntent, UserHandle.SYSTEM);
         }
     }
+
+    private boolean featureFlagEnabled() {
+        return SystemProperties.getBoolean(
+                FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.DYNAMIC_SYSTEM, false);
+    }
 }
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
index df2c571..5c6885a 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
@@ -49,6 +49,7 @@
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Messenger;
+import android.os.ParcelableException;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.image.DynamicSystemClient;
@@ -170,13 +171,13 @@
     @Override
     public void onProgressUpdate(long installedSize) {
         mInstalledSize = installedSize;
-        postStatus(STATUS_IN_PROGRESS, CAUSE_NOT_SPECIFIED);
+        postStatus(STATUS_IN_PROGRESS, CAUSE_NOT_SPECIFIED, null);
     }
 
     @Override
-    public void onResult(int result) {
+    public void onResult(int result, Throwable detail) {
         if (result == RESULT_OK) {
-            postStatus(STATUS_READY, CAUSE_INSTALL_COMPLETED);
+            postStatus(STATUS_READY, CAUSE_INSTALL_COMPLETED, null);
             return;
         }
 
@@ -185,15 +186,15 @@
 
         switch (result) {
             case RESULT_ERROR_IO:
-                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_IO);
+                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_IO, detail);
                 break;
 
             case RESULT_ERROR_INVALID_URL:
-                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_INVALID_URL);
+                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_INVALID_URL, detail);
                 break;
 
             case RESULT_ERROR_EXCEPTION:
-                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_EXCEPTION);
+                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_EXCEPTION, detail);
                 break;
         }
     }
@@ -201,7 +202,7 @@
     @Override
     public void onCancelled() {
         resetTaskAndStop();
-        postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED);
+        postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED, null);
     }
 
     private void executeInstallCommand(Intent intent) {
@@ -220,12 +221,12 @@
             return;
         }
 
-        String url = intent.getStringExtra(DynamicSystemClient.KEY_SYSTEM_URL);
+        String url = intent.getDataString();
         mSystemSize = intent.getLongExtra(DynamicSystemClient.KEY_SYSTEM_SIZE, 0);
         mUserdataSize = intent.getLongExtra(DynamicSystemClient.KEY_USERDATA_SIZE, 0);
 
         mInstallTask = new InstallationAsyncTask(
-                url, mSystemSize, mUserdataSize, mDynSystem, this);
+                url, mSystemSize, mUserdataSize, this, mDynSystem, this);
 
         mInstallTask.execute();
 
@@ -256,7 +257,7 @@
             return;
         }
 
-        if (getStatus() != STATUS_READY) {
+        if (!isDynamicSystemInstalled() && (getStatus() != STATUS_READY)) {
             Log.e(TAG, "Trying to discard AOT while there is no complete installation");
             return;
         }
@@ -266,19 +267,31 @@
                 Toast.LENGTH_LONG).show();
 
         resetTaskAndStop();
-        postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED);
+        postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED, null);
 
         mDynSystem.remove();
     }
 
     private void executeRebootToDynSystemCommand() {
-        if (mInstallTask == null || mInstallTask.getStatus() != FINISHED) {
+        boolean enabled = false;
+
+        if (mInstallTask != null && mInstallTask.getStatus() == FINISHED) {
+            enabled = mInstallTask.commit();
+        } else if (isDynamicSystemInstalled()) {
+            enabled = mDynSystem.setEnable(true);
+        } else {
             Log.e(TAG, "Trying to reboot to AOT while there is no complete installation");
             return;
         }
 
-        if (!mInstallTask.commit()) {
-            Log.e(TAG, "Failed to commit installation because of native runtime error.");
+        if (enabled) {
+            PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+
+            if (powerManager != null) {
+                powerManager.reboot("dynsystem");
+            }
+        } else {
+            Log.e(TAG, "Failed to enable DynamicSystem because of native runtime error.");
             mNM.cancel(NOTIFICATION_ID);
 
             Toast.makeText(this,
@@ -286,14 +299,6 @@
                     Toast.LENGTH_LONG).show();
 
             mDynSystem.remove();
-
-            return;
-        }
-
-        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
-
-        if (powerManager != null) {
-            powerManager.reboot("dynsystem");
         }
     }
 
@@ -409,12 +414,12 @@
     }
 
     private boolean verifyRequest(Intent intent) {
-        String url = intent.getStringExtra(DynamicSystemClient.KEY_SYSTEM_URL);
+        String url = intent.getDataString();
 
         return VerificationActivity.isVerified(url);
     }
 
-    private void postStatus(int status, int cause) {
+    private void postStatus(int status, int cause, Throwable detail) {
         Log.d(TAG, "postStatus(): statusCode=" + status + ", causeCode=" + cause);
 
         boolean notifyOnNotificationBar = true;
@@ -433,18 +438,24 @@
 
         for (int i = mClients.size() - 1; i >= 0; i--) {
             try {
-                notifyOneClient(mClients.get(i), status, cause);
+                notifyOneClient(mClients.get(i), status, cause, detail);
             } catch (RemoteException e) {
                 mClients.remove(i);
             }
         }
     }
 
-    private void notifyOneClient(Messenger client, int status, int cause) throws RemoteException {
+    private void notifyOneClient(Messenger client, int status, int cause, Throwable detail)
+            throws RemoteException {
         Bundle bundle = new Bundle();
 
         bundle.putLong(DynamicSystemClient.KEY_INSTALLED_SIZE, mInstalledSize);
 
+        if (detail != null) {
+            bundle.putSerializable(DynamicSystemClient.KEY_EXCEPTION_DETAIL,
+                    new ParcelableException(detail));
+        }
+
         client.send(Message.obtain(null,
                   DynamicSystemClient.MSG_POST_STATUS, status, cause, bundle));
     }
@@ -496,7 +507,7 @@
                     int status = getStatus();
 
                     // tell just registered client my status, but do not specify cause
-                    notifyOneClient(client, status, CAUSE_NOT_SPECIFIED);
+                    notifyOneClient(client, status, CAUSE_NOT_SPECIFIED, null);
 
                     mClients.add(client);
                 } catch (RemoteException e) {
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
index 052fc0a..b0e28a0 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
@@ -16,7 +16,9 @@
 
 package com.android.dynsystem;
 
+import android.content.Context;
 import android.gsi.GsiProgress;
+import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.image.DynamicSystemManager;
 import android.util.Log;
@@ -31,7 +33,7 @@
 import java.util.zip.GZIPInputStream;
 
 
-class InstallationAsyncTask extends AsyncTask<String, Long, Integer> {
+class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
 
     private static final String TAG = "InstallationAsyncTask";
 
@@ -43,7 +45,6 @@
         }
     }
 
-
     /** Not completed, including being cancelled */
     static final int NO_RESULT = 0;
     static final int RESULT_OK = 1;
@@ -53,13 +54,14 @@
 
     interface InstallStatusListener {
         void onProgressUpdate(long installedSize);
-        void onResult(int resultCode);
+        void onResult(int resultCode, Throwable detail);
         void onCancelled();
     }
 
     private final String mUrl;
     private final long mSystemSize;
     private final long mUserdataSize;
+    private final Context mContext;
     private final DynamicSystemManager mDynSystem;
     private final InstallStatusListener mListener;
     private DynamicSystemManager.Session mInstallationSession;
@@ -69,11 +71,12 @@
     private InputStream mStream;
 
 
-    InstallationAsyncTask(String url, long systemSize, long userdataSize,
+    InstallationAsyncTask(String url, long systemSize, long userdataSize, Context context,
             DynamicSystemManager dynSystem, InstallStatusListener listener) {
         mUrl = url;
         mSystemSize = systemSize;
         mUserdataSize = userdataSize;
+        mContext = context;
         mDynSystem = dynSystem;
         mListener = listener;
     }
@@ -84,7 +87,7 @@
     }
 
     @Override
-    protected Integer doInBackground(String... voids) {
+    protected Throwable doInBackground(String... voids) {
         Log.d(TAG, "Start doInBackground(), URL: " + mUrl);
 
         try {
@@ -108,7 +111,7 @@
                 if (isCancelled()) {
                     boolean aborted = mDynSystem.abort();
                     Log.d(TAG, "Called DynamicSystemManager.abort(), result = " + aborted);
-                    return RESULT_OK;
+                    return null;
                 }
 
                 GsiProgress progress = mDynSystem.getInstallationProgress();
@@ -124,10 +127,8 @@
 
 
             if (mInstallationSession == null) {
-                Log.e(TAG, "Failed to start installation with requested size: "
+                throw new IOException("Failed to start installation with requested size: "
                         + (mSystemSize + mUserdataSize));
-
-                return RESULT_ERROR_IO;
             }
 
             installedSize = mUserdataSize;
@@ -157,20 +158,11 @@
                 }
             }
 
-            return RESULT_OK;
-
-        } catch (IOException e) {
-            e.printStackTrace();
-            return RESULT_ERROR_IO;
-
-        } catch (InvalidImageUrlException e) {
-            e.printStackTrace();
-            return RESULT_ERROR_INVALID_URL;
+            return null;
 
         } catch (Exception e) {
             e.printStackTrace();
-            return RESULT_ERROR_EXCEPTION;
-
+            return e;
         } finally {
             close();
         }
@@ -180,19 +172,24 @@
     protected void onCancelled() {
         Log.d(TAG, "onCancelled(), URL: " + mUrl);
 
-        close();
-
         mListener.onCancelled();
     }
 
     @Override
-    protected void onPostExecute(Integer result) {
-        Log.d(TAG, "onPostExecute(), URL: " + mUrl + ", result: " + result);
+    protected void onPostExecute(Throwable detail) {
+        if (detail == null) {
+            mResult = RESULT_OK;
+        } else if (detail instanceof IOException) {
+            mResult = RESULT_ERROR_IO;
+        } else if (detail instanceof InvalidImageUrlException) {
+            mResult = RESULT_ERROR_INVALID_URL;
+        } else {
+            mResult = RESULT_ERROR_EXCEPTION;
+        }
 
-        close();
+        Log.d(TAG, "onPostExecute(), URL: " + mUrl + ", result: " + mResult);
 
-        mResult = result;
-        mListener.onResult(mResult);
+        mListener.onResult(mResult, detail);
     }
 
     @Override
@@ -204,6 +201,10 @@
     private void initInputStream() throws IOException, InvalidImageUrlException {
         if (URLUtil.isNetworkUrl(mUrl) || URLUtil.isFileUrl(mUrl)) {
             mStream = new BufferedInputStream(new GZIPInputStream(new URL(mUrl).openStream()));
+        } else if (URLUtil.isContentUrl(mUrl)) {
+            Uri uri = Uri.parse(mUrl);
+            mStream = new BufferedInputStream(new GZIPInputStream(
+                    mContext.getContentResolver().openInputStream(uri)));
         } else {
             throw new InvalidImageUrlException(
                     String.format(Locale.US, "Unsupported file source: %s", mUrl));
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java
index f05930f..b1c09381 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java
@@ -17,16 +17,18 @@
 package com.android.dynsystem;
 
 import static android.os.image.DynamicSystemClient.KEY_SYSTEM_SIZE;
-import static android.os.image.DynamicSystemClient.KEY_SYSTEM_URL;
 import static android.os.image.DynamicSystemClient.KEY_USERDATA_SIZE;
 
 import android.app.Activity;
 import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.image.DynamicSystemClient;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 
 
@@ -49,6 +51,12 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        if (!featureFlagEnabled()) {
+            Log.w(TAG, FeatureFlagUtils.DYNAMIC_SYSTEM + " not enabled; activity aborted.");
+            finish();
+            return;
+        }
+
         KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
 
         if (km != null) {
@@ -81,16 +89,16 @@
         // retrieve data from calling intent
         Intent callingIntent = getIntent();
 
-        String url = callingIntent.getStringExtra(KEY_SYSTEM_URL);
+        Uri url = callingIntent.getData();
         long systemSize = callingIntent.getLongExtra(KEY_SYSTEM_SIZE, 0);
         long userdataSize = callingIntent.getLongExtra(KEY_USERDATA_SIZE, 0);
 
-        sVerifiedUrl = url;
+        sVerifiedUrl = url.toString();
 
         // start service
         Intent intent = new Intent(this, DynamicSystemInstallationService.class);
+        intent.setData(url);
         intent.setAction(DynamicSystemClient.ACTION_START_INSTALL);
-        intent.putExtra(KEY_SYSTEM_URL, url);
         intent.putExtra(KEY_SYSTEM_SIZE, systemSize);
         intent.putExtra(KEY_USERDATA_SIZE, userdataSize);
 
@@ -98,6 +106,11 @@
         startServiceAsUser(intent, UserHandle.SYSTEM);
     }
 
+    private boolean featureFlagEnabled() {
+        return SystemProperties.getBoolean(
+                FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.DYNAMIC_SYSTEM, false);
+    }
+
     static boolean isVerified(String url) {
         return sVerifiedUrl != null && sVerifiedUrl.equals(url);
     }
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
index 76e2fe7..45a59a3 100644
--- a/packages/ExtServices/AndroidManifest.xml
+++ b/packages/ExtServices/AndroidManifest.xml
@@ -17,7 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     package="android.ext.services"
-    android:versionCode="1"
+    android:versionCode="200000000"
     android:versionName="1"
     coreApp="true">
 
@@ -26,6 +26,7 @@
 
     <uses-permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" />
     <uses-permission android:name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 
     <uses-sdk
         android:targetSdkVersion="28"
@@ -78,6 +79,13 @@
             </intent-filter>
         </service>
 
+        <service android:name=".watchdog.ExplicitHealthCheckServiceImpl"
+                 android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.watchdog.ExplicitHealthCheckService" />
+            </intent-filter>
+        </service>
+
         <activity android:name=".notification.CopyCodeActivity"
                   android:exported="false"
                   android:theme="@android:style/Theme.NoDisplay"/>
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index 31a3ff4..1544adb 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -65,6 +65,8 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
  * Notification assistant that provides guidance on notification channel blocking
@@ -80,6 +82,7 @@
     private static final String ATT_KEY = "key";
     private static final int DB_VERSION = 1;
     private static final String ATTR_VERSION = "version";
+    private final ExecutorService mSingleThreadExecutor = Executors.newSingleThreadExecutor();
 
     private static final ArrayList<Integer> PREJUDICAL_DISMISSALS = new ArrayList<>();
     static {
@@ -233,15 +236,20 @@
         if (!isForCurrentUser(sbn)) {
             return null;
         }
-        NotificationEntry entry =
-                new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
-        SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry);
-        if (DEBUG) {
-            Log.d(TAG, String.format("Creating Adjustment for %s, with %d actions, and %d replies.",
-                    sbn.getKey(), suggestions.actions.size(), suggestions.replies.size()));
-        }
-        return createEnqueuedNotificationAdjustment(
-                entry, suggestions.actions, suggestions.replies);
+        mSingleThreadExecutor.submit(() -> {
+            NotificationEntry entry =
+                    new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
+            SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry);
+            if (DEBUG) {
+                Log.d(TAG, String.format(
+                        "Creating Adjustment for %s, with %d actions, and %d replies.",
+                        sbn.getKey(), suggestions.actions.size(), suggestions.replies.size()));
+            }
+            Adjustment adjustment = createEnqueuedNotificationAdjustment(
+                    entry, suggestions.actions, suggestions.replies);
+            adjustNotification(adjustment);
+        });
+        return null;
     }
 
     /** A convenience helper for creating an adjustment for an SBN. */
@@ -386,15 +394,15 @@
         NotificationEntry entry = mLiveNotifications.get(key);
 
         if (entry != null) {
-            entry.setExpanded(isExpanded);
-            mSmartActionsHelper.onNotificationExpansionChanged(entry, isUserAction, isExpanded);
+            mSingleThreadExecutor.submit(
+                    () -> mSmartActionsHelper.onNotificationExpansionChanged(entry, isExpanded));
         }
     }
 
     @Override
     public void onNotificationDirectReplied(@NonNull String key) {
         if (DEBUG) Log.i(TAG, "onNotificationDirectReplied " + key);
-        mSmartActionsHelper.onNotificationDirectReplied(key);
+        mSingleThreadExecutor.submit(() -> mSmartActionsHelper.onNotificationDirectReplied(key));
     }
 
     @Override
@@ -404,7 +412,8 @@
             Log.d(TAG, "onSuggestedReplySent() called with: key = [" + key + "], reply = [" + reply
                     + "], source = [" + source + "]");
         }
-        mSmartActionsHelper.onSuggestedReplySent(key, reply, source);
+        mSingleThreadExecutor.submit(
+                () -> mSmartActionsHelper.onSuggestedReplySent(key, reply, source));
     }
 
     @Override
@@ -415,7 +424,8 @@
                     "onActionInvoked() called with: key = [" + key + "], action = [" + action.title
                             + "], source = [" + source + "]");
         }
-        mSmartActionsHelper.onActionClicked(key, action, source);
+        mSingleThreadExecutor.submit(
+                () -> mSmartActionsHelper.onActionClicked(key, action, source));
     }
 
     @Override
@@ -494,11 +504,6 @@
     }
 
     @VisibleForTesting
-    public void setSmartActionsHelper(SmartActionsHelper smartActionsHelper) {
-        mSmartActionsHelper = smartActionsHelper;
-    }
-
-    @VisibleForTesting
     public ChannelImpressions getImpressions(String key) {
         synchronized (mkeyToImpressions) {
             return mkeyToImpressions.get(key);
diff --git a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
index 546bec2..84a8a8c 100644
--- a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
+++ b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
@@ -47,17 +47,18 @@
 public class NotificationEntry {
     static final String TAG = "NotificationEntry";
 
-    private StatusBarNotification mSbn;
+    private final StatusBarNotification mSbn;
     private final IPackageManager mPackageManager;
     private int mTargetSdkVersion = Build.VERSION_CODES.N_MR1;
-    private boolean mPreChannelsNotification = true;
-    private AudioAttributes mAttributes;
-    private NotificationChannel mChannel;
-    private int mImportance;
+    private final boolean mPreChannelsNotification;
+    private final AudioAttributes mAttributes;
+    private final NotificationChannel mChannel;
+    private final int mImportance;
     private boolean mSeen;
-    private boolean mExpanded;
     private boolean mIsShowActionEventLogged;
-    private SmsHelper mSmsHelper;
+    private final SmsHelper mSmsHelper;
+
+    private final Object mLock = new Object();
 
     public NotificationEntry(IPackageManager packageManager, StatusBarNotification sbn,
             NotificationChannel channel, SmsHelper smsHelper) {
@@ -233,23 +234,27 @@
     }
 
     public void setSeen() {
-        mSeen = true;
-    }
-
-    public void setExpanded(boolean expanded) {
-        mExpanded = expanded;
+        synchronized (mLock) {
+            mSeen = true;
+        }
     }
 
     public void setShowActionEventLogged() {
-        mIsShowActionEventLogged = true;
+        synchronized (mLock) {
+            mIsShowActionEventLogged = true;
+        }
     }
 
     public boolean hasSeen() {
-        return mSeen;
+        synchronized (mLock) {
+            return mSeen;
+        }
     }
 
     public boolean isShowActionEventLogged() {
-        return mIsShowActionEventLogged;
+        synchronized (mLock) {
+            return mIsShowActionEventLogged;
+        }
     }
 
     public StatusBarNotification getSbn() {
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
index bf8a3fa..0d687d4 100644
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
@@ -53,6 +53,11 @@
 import java.util.Map;
 import java.util.Objects;
 
+/**
+ * Generates suggestions from incoming notifications.
+ *
+ * Methods in this class should be called in a single worker thread.
+ */
 public class SmartActionsHelper {
     static final String ENTITIES_EXTRAS = "entities-extras";
     static final String KEY_ACTION_TYPE = "action_type";
@@ -287,8 +292,7 @@
         return conversationActions;
     }
 
-    void onNotificationExpansionChanged(NotificationEntry entry, boolean isUserAction,
-            boolean isExpanded) {
+    void onNotificationExpansionChanged(NotificationEntry entry, boolean isExpanded) {
         if (!isExpanded) {
             return;
         }
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
new file mode 100644
index 0000000..040e2ab
--- /dev/null
+++ b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.ext.services.watchdog;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.service.watchdog.ExplicitHealthCheckService;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Routes explicit health check requests to the appropriate {@link ExplicitHealthChecker}.
+ */
+public final class ExplicitHealthCheckServiceImpl extends ExplicitHealthCheckService {
+    private static final String TAG = "ExplicitHealthCheckServiceImpl";
+    // TODO: Add build dependency on NetworkStack stable AIDL so we can stop hard coding class name
+    private static final String NETWORK_STACK_CONNECTOR_CLASS =
+            "android.net.INetworkStackConnector";
+    // Modified only #onCreate, using concurrent collection to ensure thread visibility
+    private final Map<String, ExplicitHealthChecker> mSupportedCheckers = new ConcurrentHashMap<>();
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        initHealthCheckers();
+    }
+
+    @Override
+    public void onRequestHealthCheck(String packageName) {
+        ExplicitHealthChecker checker = mSupportedCheckers.get(packageName);
+        if (checker != null) {
+            checker.request();
+        } else {
+            Log.w(TAG, "Ignoring request for explicit health check for unsupported package "
+                    + packageName);
+        }
+    }
+
+    @Override
+    public void onCancelHealthCheck(String packageName) {
+        ExplicitHealthChecker checker = mSupportedCheckers.get(packageName);
+        if (checker != null) {
+            checker.cancel();
+        } else {
+            Log.w(TAG, "Ignoring request to cancel explicit health check for unsupported package "
+                    + packageName);
+        }
+    }
+
+    @Override
+    public List<String> onGetSupportedPackages() {
+        return new ArrayList<>(mSupportedCheckers.keySet());
+    }
+
+    @Override
+    public List<String> onGetRequestedPackages() {
+        List<String> packages = new ArrayList<>();
+        Iterator<ExplicitHealthChecker> it = mSupportedCheckers.values().iterator();
+        // Could potentially race, where we read a checker#isPending and it changes before we
+        // return list. However, if it races and it is in the list, the caller might call #cancel
+        // which would fail, but that is fine. If it races and it ends up *not* in the list, it was
+        // already cancelled, so there's no need for the caller to cancel it
+        while (it.hasNext()) {
+            ExplicitHealthChecker checker = it.next();
+            if (checker.isPending()) {
+                packages.add(checker.getPackageName());
+            }
+        }
+        return packages;
+    }
+
+    private void initHealthCheckers() {
+        Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
+        ComponentName comp = intent.resolveSystemService(getPackageManager(), 0);
+        if (comp != null) {
+            String networkStackPackageName = comp.getPackageName();
+            mSupportedCheckers.put(networkStackPackageName,
+                    new NetworkChecker(this, networkStackPackageName));
+        } else {
+            // On Go devices, or any device that does not ship the network stack module.
+            // The network stack will live in system_server process, so no need to monitor.
+            Log.i(TAG, "Network stack module not found");
+        }
+    }
+}
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java
new file mode 100644
index 0000000..650878e
--- /dev/null
+++ b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.ext.services.watchdog;
+
+/**
+ * A type of explicit health check that can be performed on a device, e.g network health check
+ */
+interface ExplicitHealthChecker {
+    /**
+     * Requests a checker to listen to explicit health checks for {@link #getPackageName}.
+     *  {@link #isPending} will now return {@code true}.
+     */
+    void request();
+
+    /**
+     * Cancels a pending explicit health check request for {@link #getPackageName}.
+     * {@link #isPending} will now return {@code false}.
+     */
+    void cancel();
+
+    /**
+     * Returns {@code true} if a request is pending, {@code false} otherwise.
+     */
+    boolean isPending();
+
+    /**
+     * Returns the package name this checker can make requests for.
+     */
+    String getPackageName();
+}
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java
new file mode 100644
index 0000000..32375e6
--- /dev/null
+++ b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.ext.services.watchdog;
+
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.service.watchdog.ExplicitHealthCheckService;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * Observes the network stack via the ConnectivityManager.
+ */
+final class NetworkChecker extends ConnectivityManager.NetworkCallback
+        implements ExplicitHealthChecker {
+    private static final String TAG = "NetworkChecker";
+
+    private final Object mLock = new Object();
+    private final ExplicitHealthCheckService mService;
+    private final String mPackageName;
+    @GuardedBy("mLock")
+    private boolean mIsPending;
+
+    NetworkChecker(ExplicitHealthCheckService service, String packageName) {
+        mService = service;
+        mPackageName = packageName;
+    }
+
+    @Override
+    public void request() {
+        synchronized (mLock) {
+            if (mIsPending) {
+                return;
+            }
+            mService.getSystemService(ConnectivityManager.class).registerNetworkCallback(
+                    new NetworkRequest.Builder().build(), this);
+            mIsPending = true;
+        }
+    }
+
+    @Override
+    public void cancel() {
+        synchronized (mLock) {
+            if (!mIsPending) {
+                return;
+            }
+            mService.getSystemService(ConnectivityManager.class).unregisterNetworkCallback(this);
+            mIsPending = false;
+        }
+    }
+
+    @Override
+    public boolean isPending() {
+        synchronized (mLock) {
+            return mIsPending;
+        }
+    }
+
+    @Override
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    // TODO(b/120598832): Also monitor NetworkCallback#onAvailable to see if we have any
+    // available networks that may be unusable. This could be additional signal to our heuristics
+    @Override
+    public void onCapabilitiesChanged(Network network, NetworkCapabilities capabilities) {
+        synchronized (mLock) {
+            if (mIsPending
+                    && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
+                mService.notifyHealthCheckPassed(mPackageName);
+                cancel();
+            }
+        }
+    }
+}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
index 3a7d799..ebcaee8 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
@@ -382,7 +382,7 @@
         when(mStatusBarNotification.getNotification()).thenReturn(notification);
 
         mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true, true);
+        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
 
         ArgumentCaptor<TextClassifierEvent> argumentCaptor =
                 ArgumentCaptor.forClass(TextClassifierEvent.class);
@@ -398,7 +398,7 @@
         when(mStatusBarNotification.getNotification()).thenReturn(notification);
 
         mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false, false);
+        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false);
 
         verify(mTextClassifier, never()).onTextClassifierEvent(
                 argThat(new TextClassifierEventMatcher(TextClassifierEvent.TYPE_ACTIONS_SHOWN)));
@@ -410,7 +410,7 @@
         when(mStatusBarNotification.getNotification()).thenReturn(notification);
 
         mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false, true);
+        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
 
         ArgumentCaptor<TextClassifierEvent> argumentCaptor =
                 ArgumentCaptor.forClass(TextClassifierEvent.class);
diff --git a/packages/NetworkStackPermissionStub/Android.bp b/packages/NetworkPermissionConfig/Android.bp
similarity index 95%
rename from packages/NetworkStackPermissionStub/Android.bp
rename to packages/NetworkPermissionConfig/Android.bp
index 8cee92e..d0d3276 100644
--- a/packages/NetworkStackPermissionStub/Android.bp
+++ b/packages/NetworkPermissionConfig/Android.bp
@@ -16,7 +16,7 @@
 
 // Stub APK to define permissions for NetworkStack
 android_app {
-    name: "NetworkStackPermissionStub",
+    name: "NetworkPermissionConfig",
     // TODO: mark app as hasCode=false in manifest once soong stops complaining about apps without
     // a classes.dex.
     srcs: ["src/**/*.java"],
diff --git a/packages/NetworkStackPermissionStub/AndroidManifest.xml b/packages/NetworkPermissionConfig/AndroidManifest.xml
similarity index 92%
rename from packages/NetworkStackPermissionStub/AndroidManifest.xml
rename to packages/NetworkPermissionConfig/AndroidManifest.xml
index e83f050..34f987c 100644
--- a/packages/NetworkStackPermissionStub/AndroidManifest.xml
+++ b/packages/NetworkPermissionConfig/AndroidManifest.xml
@@ -17,7 +17,7 @@
  */
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.networkstack.permissionstub"
+    package="com.android.networkstack.permissionconfig"
     android:sharedUserId="android.uid.networkstack"
     android:versionCode="11"
     android:versionName="Q-initial">
@@ -36,5 +36,5 @@
     <permission android:name="android.permission.MAINLINE_NETWORK_STACK"
                 android:protectionLevel="signature"/>
 
-    <application android:name="com.android.server.NetworkStackPermissionStub"/>
+    <application android:name="com.android.server.NetworkPermissionConfig"/>
 </manifest>
diff --git a/packages/NetworkStackPermissionStub/src/com/android/server/NetworkStackPermissionStub.java b/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java
similarity index 78%
rename from packages/NetworkStackPermissionStub/src/com/android/server/NetworkStackPermissionStub.java
rename to packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java
index 01e59d2..c904e23 100644
--- a/packages/NetworkStackPermissionStub/src/com/android/server/NetworkStackPermissionStub.java
+++ b/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java
@@ -19,8 +19,8 @@
 import android.app.Application;
 
 /**
- * Empty application for NetworkStackStub that only exists because soong builds complain if APKs
- * have no source file.
+ * Empty application for NetworkPermissionConfig that only exists because
+ * soong builds complain if APKs have no source file.
  */
-public class NetworkStackPermissionStub extends Application {
+public class NetworkPermissionConfig extends Application {
 }
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index 52534a8..57a3db5 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+java_library {
+    name: "captiveportal-lib",
+    srcs: ["common/**/*.java"],
+    libs: [
+        "androidx.annotation_annotation",
+    ],
+    sdk_version: "system_current",
+}
+
 java_defaults {
     name: "NetworkStackCommon",
     sdk_version: "system_current",
@@ -35,6 +44,7 @@
         "networkstack-aidl-interfaces-java",
         "datastallprotosnano",
         "networkstackprotosnano",
+        "captiveportal-lib",
     ],
     manifest: "AndroidManifestBase.xml",
 }
@@ -49,8 +59,11 @@
     // Resources already included in NetworkStackBase
     resource_dirs: [],
     jarjar_rules: "jarjar-rules-shared.txt",
+    optimize: {
+        proguard_flags_files: ["proguard.flags"],
+    },
     // The permission configuration *must* be included to ensure security of the device
-    required: ["NetworkStackPermissionStub"],
+    required: ["NetworkPermissionConfig"],
 }
 
 // Non-updatable network stack running in the system server process for devices not using the module
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
index b0a7923..b4588e0 100644
--- a/packages/NetworkStack/AndroidManifest.xml
+++ b/packages/NetworkStack/AndroidManifest.xml
@@ -17,9 +17,28 @@
  */
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.networkstack"
-          android:sharedUserId="android.uid.networkstack">
+  package="com.android.networkstack"
+  android:sharedUserId="android.uid.networkstack"
+  android:versionCode="200000000"
+  android:versionName="29 system image"
+>
+
     <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
+
+    <!-- Permissions must be defined here, and not in the base manifest, as the network stack
+         running in the system server process does not need any permission, and having privileged
+         permissions added would cause crashes on startup unless they are also added to the
+         privileged permissions whitelist for that package. -->
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <!-- Send latency broadcast as current user -->
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
+    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
     <!-- Signature permission defined in NetworkStackStub -->
     <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
     <application>
diff --git a/packages/NetworkStack/AndroidManifestBase.xml b/packages/NetworkStack/AndroidManifestBase.xml
index f69e4b2..d00a551 100644
--- a/packages/NetworkStack/AndroidManifestBase.xml
+++ b/packages/NetworkStack/AndroidManifestBase.xml
@@ -20,19 +20,14 @@
           package="com.android.networkstack"
           android:versionCode="11"
           android:versionName="Q-initial">
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
-    <!-- Send latency broadcast as current user -->
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <application
         android:label="NetworkStack"
         android:defaultToDeviceProtectedStorage="true"
         android:directBootAware="true"
         android:usesCleartextTraffic="true">
+
+        <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
+                 android:permission="android.permission.BIND_JOB_SERVICE" >
+        </service>
     </application>
 </manifest>
diff --git a/core/java/android/net/captiveportal/CaptivePortalProbeResult.java b/packages/NetworkStack/common/CaptivePortalProbeResult.java
similarity index 94%
rename from core/java/android/net/captiveportal/CaptivePortalProbeResult.java
rename to packages/NetworkStack/common/CaptivePortalProbeResult.java
index a1d3de2..48cd48b 100644
--- a/core/java/android/net/captiveportal/CaptivePortalProbeResult.java
+++ b/packages/NetworkStack/common/CaptivePortalProbeResult.java
@@ -16,17 +16,13 @@
 
 package android.net.captiveportal;
 
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 /**
  * Result of calling isCaptivePortal().
  * @hide
  */
-@SystemApi
-@TestApi
 public final class CaptivePortalProbeResult {
     public static final int SUCCESS_CODE = 204;
     public static final int FAILED_CODE = 599;
diff --git a/core/java/android/net/captiveportal/CaptivePortalProbeSpec.java b/packages/NetworkStack/common/CaptivePortalProbeSpec.java
similarity index 94%
rename from core/java/android/net/captiveportal/CaptivePortalProbeSpec.java
rename to packages/NetworkStack/common/CaptivePortalProbeSpec.java
index 6c6a16c..bf983a5 100644
--- a/core/java/android/net/captiveportal/CaptivePortalProbeSpec.java
+++ b/packages/NetworkStack/common/CaptivePortalProbeSpec.java
@@ -19,16 +19,12 @@
 import static android.net.captiveportal.CaptivePortalProbeResult.PORTAL_CODE;
 import static android.net.captiveportal.CaptivePortalProbeResult.SUCCESS_CODE;
 
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -40,8 +36,6 @@
 import java.util.regex.PatternSyntaxException;
 
 /** @hide */
-@SystemApi
-@TestApi
 public abstract class CaptivePortalProbeSpec {
     private static final String TAG = CaptivePortalProbeSpec.class.getSimpleName();
     private static final String REGEX_SEPARATOR = "@@/@@";
@@ -50,8 +44,7 @@
     private final String mEncodedSpec;
     private final URL mUrl;
 
-    CaptivePortalProbeSpec(@NonNull String encodedSpec, @NonNull URL url)
-            throws NullPointerException {
+    CaptivePortalProbeSpec(@NonNull String encodedSpec, @NonNull URL url) {
         mEncodedSpec = checkNotNull(encodedSpec);
         mUrl = checkNotNull(url);
     }
@@ -193,4 +186,10 @@
         // No value is a match ("no location header" passes the location rule for non-redirects)
         return pattern == null || TextUtils.isEmpty(value) || pattern.matcher(value).matches();
     }
+
+    // Throws NullPointerException if the input is null.
+    private static <T> T checkNotNull(T object) {
+        if (object == null) throw new NullPointerException();
+        return object;
+    }
 }
diff --git a/packages/NetworkStack/proguard.flags b/packages/NetworkStack/proguard.flags
new file mode 100644
index 0000000..c60f6c3
--- /dev/null
+++ b/packages/NetworkStack/proguard.flags
@@ -0,0 +1,9 @@
+-keepclassmembers class android.net.ip.IpClient {
+    static final int CMD_*;
+    static final int EVENT_*;
+}
+
+-keepclassmembers class android.net.dhcp.DhcpClient {
+    static final int CMD_*;
+    static final int EVENT_*;
+}
diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
index 3dd90ee..d2f3259 100644
--- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java
+++ b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
@@ -74,6 +74,7 @@
 import java.net.UnknownHostException;
 import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.Arrays;
 
@@ -282,6 +283,7 @@
     private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
             {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
     // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN.
+    private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
     private static final int IPV4_FRAGMENT_OFFSET_OFFSET = ETH_HEADER_LEN + 6;
     // Endianness is not an issue for this constant because the APF interpreter always operates in
     // network byte order.
@@ -881,10 +883,23 @@
 
         protected final TcpKeepaliveAckData mPacket;
         protected final byte[] mSrcDstAddr;
+        protected final byte[] mPortSeqAckFingerprint;
 
         TcpKeepaliveAck(final TcpKeepaliveAckData packet, final byte[] srcDstAddr) {
             mPacket = packet;
             mSrcDstAddr = srcDstAddr;
+            mPortSeqAckFingerprint = generatePortSeqAckFingerprint(mPacket.srcPort,
+                    mPacket.dstPort, mPacket.seq, mPacket.ack);
+        }
+
+        static byte[] generatePortSeqAckFingerprint(int srcPort, int dstPort, int seq, int ack) {
+            final ByteBuffer fp = ByteBuffer.allocate(12);
+            fp.order(ByteOrder.BIG_ENDIAN);
+            fp.putShort((short) srcPort);
+            fp.putShort((short) dstPort);
+            fp.putInt(seq);
+            fp.putInt(ack);
+            return fp.array();
         }
 
         static byte[] concatArrays(final byte[]... arr) {
@@ -919,10 +934,6 @@
 
     private class TcpKeepaliveAckV4 extends TcpKeepaliveAck {
         private static final int IPV4_SRC_ADDR_OFFSET = IP_HEADER_OFFSET + 12;
-        private static final int IPV4_TCP_SRC_PORT_OFFSET = 0;
-        private static final int IPV4_TCP_DST_PORT_OFFSET = 2;
-        private static final int IPV4_TCP_SEQ_OFFSET = 4;
-        private static final int IPV4_TCP_ACK_OFFSET = 8;
 
         TcpKeepaliveAckV4(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
             this(new TcpKeepaliveAckData(sentKeepalivePacket));
@@ -934,12 +945,12 @@
         @Override
         void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
             final String nextFilterLabel = "keepalive_ack" + getUniqueNumberLocked();
-            gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
-            gen.addJumpIfR0NotEquals(IPPROTO_TCP, nextFilterLabel);
+
             gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET);
             gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel);
 
-            // Pass the packet if it's not zero-sized :
+            // Skip to the next filter if it's not zero-sized :
+            // TCP_HEADER_SIZE + IPV4_HEADER_SIZE - ipv4_total_length == 0
             // Load the IP header size into R1
             gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
             // Load the TCP header size into R0 (it's indexed by R1)
@@ -947,27 +958,18 @@
             // Size offset is in the top nibble, but it must be multiplied by 4, and the two
             // top bits of the low nibble are guaranteed to be zeroes. Right-shift R0 by 2.
             gen.addRightShift(2);
-            // R0 += R1 -> R0 contains TCP + IP headers lenght
+            // R0 += R1 -> R0 contains TCP + IP headers length
             gen.addAddR1();
-            // Add the Ethernet header length to R0.
-            gen.addLoadImmediate(Register.R1, ETH_HEADER_LEN);
-            gen.addAddR1();
-            // Compare total length of headers to the size of the packet.
-            gen.addLoadFromMemory(Register.R1, gen.PACKET_SIZE_MEMORY_SLOT);
+            // Load IPv4 total length
+            gen.addLoad16(Register.R1, IPV4_TOTAL_LENGTH_OFFSET);
             gen.addNeg(Register.R0);
             gen.addAddR1();
             gen.addJumpIfR0NotEquals(0, nextFilterLabel);
-
             // Add IPv4 header length
             gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addLoad16Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_SRC_PORT_OFFSET);
-            gen.addJumpIfR0NotEquals(mPacket.srcPort, nextFilterLabel);
-            gen.addLoad16Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_DST_PORT_OFFSET);
-            gen.addJumpIfR0NotEquals(mPacket.dstPort, nextFilterLabel);
-            gen.addLoad32Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_SEQ_OFFSET);
-            gen.addJumpIfR0NotEquals(mPacket.seq, nextFilterLabel);
-            gen.addLoad32Indexed(Register.R0, ETH_HEADER_LEN + IPV4_TCP_ACK_OFFSET);
-            gen.addJumpIfR0NotEquals(mPacket.ack, nextFilterLabel);
+            gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN);
+            gen.addAddR1();
+            gen.addJumpIfBytesNotEqual(Register.R0, mPortSeqAckFingerprint, nextFilterLabel);
 
             maybeSetupCounter(gen, Counter.DROPPED_IPV4_KEEPALIVE_ACK);
             gen.addJump(mCountAndDropLabel);
@@ -1169,9 +1171,10 @@
                 gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
             }
 
-            // If any keepalive filters,
-            generateKeepaliveFilter(gen);
+            // If any keepalive filter matches, drop
+            generateV4KeepaliveFilters(gen);
 
+            // Otherwise, this is an IPv4 unicast, pass
             // If L2 broadcast packet, drop.
             // TODO: can we invert this condition to fall through to the common pass case below?
             maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST);
@@ -1180,7 +1183,7 @@
             maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
             gen.addJump(mCountAndDropLabel);
         } else {
-            generateKeepaliveFilter(gen);
+            generateV4KeepaliveFilters(gen);
         }
 
         // Otherwise, pass
@@ -1188,12 +1191,25 @@
         gen.addJump(mCountAndPassLabel);
     }
 
-    private void generateKeepaliveFilter(ApfGenerator gen) throws IllegalInstructionException {
+    private void generateV4KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
+        final String skipV4KeepaliveFilter = "skip_v4_keepalive_filter";
+        final boolean haveV4KeepaliveAcks = NetworkStackUtils.any(mKeepaliveAcks,
+                ack -> ack instanceof TcpKeepaliveAckV4);
+
+        // If no keepalive acks
+        if (!haveV4KeepaliveAcks) return;
+
+        // If not tcp, skip keepalive filters
+        gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
+        gen.addJumpIfR0NotEquals(IPPROTO_TCP, skipV4KeepaliveFilter);
+
         // Drop IPv4 Keepalive acks
         for (int i = 0; i < mKeepaliveAcks.size(); ++i) {
             final TcpKeepaliveAck ack = mKeepaliveAcks.valueAt(i);
             if (ack instanceof TcpKeepaliveAckV4) ack.generateFilterLocked(gen);
         }
+
+        gen.defineLabel(skipV4KeepaliveFilter);
     }
 
     /**
@@ -1244,11 +1260,14 @@
             maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
             gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET);
             gen.addJumpIfR0Equals(0xff, mCountAndDropLabel);
+            // If any keepalive filter matches, drop
+            generateV6KeepaliveFilters(gen);
             // Not multicast. Pass.
             maybeSetupCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
             gen.addJump(mCountAndPassLabel);
             gen.defineLabel(skipIPv6MulticastFilterLabel);
         } else {
+            generateV6KeepaliveFilters(gen);
             // If not ICMPv6, pass.
             maybeSetupCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
             gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel);
@@ -1272,12 +1291,27 @@
         maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
         gen.addJump(mCountAndDropLabel);
         gen.defineLabel(skipUnsolicitedMulticastNALabel);
+    }
+
+    private void generateV6KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
+        final String skipV6KeepaliveFilter = "skip_v6_keepalive_filter";
+        final boolean haveV6KeepaliveAcks = NetworkStackUtils.any(mKeepaliveAcks,
+                ack -> ack instanceof TcpKeepaliveAckV6);
+
+        // If no keepalive acks
+        if (!haveV6KeepaliveAcks) return;
+
+        // If not tcp, skip keepalive filters
+        gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET);
+        gen.addJumpIfR0NotEquals(IPPROTO_TCP, skipV6KeepaliveFilter);
 
         // Drop IPv6 Keepalive acks
         for (int i = 0; i < mKeepaliveAcks.size(); ++i) {
             final TcpKeepaliveAck ack = mKeepaliveAcks.valueAt(i);
             if (ack instanceof TcpKeepaliveAckV6) ack.generateFilterLocked(gen);
         }
+
+        gen.defineLabel(skipV6KeepaliveFilter);
     }
 
     /**
@@ -1294,6 +1328,8 @@
      * <li>Pass all non-IPv4 and non-IPv6 packets,
      * <li>Drop IPv6 ICMPv6 NAs to ff02::1.
      * <li>Drop IPv6 ICMPv6 RSs.
+     * <li>Filter IPv4 packets (see generateIPv4FilterLocked())
+     * <li>Filter IPv6 packets (see generateIPv6FilterLocked())
      * <li>Let execution continue off the end of the program for IPv6 ICMPv6 packets. This allows
      *     insertion of RA filters here, or if there aren't any, just passes the packets.
      * </ul>
@@ -1737,7 +1773,7 @@
         }
         pw.decreaseIndent();
 
-        pw.println("Keepalive filter:");
+        pw.println("Keepalive filters:");
         pw.increaseIndent();
         for (int i = 0; i < mKeepaliveAcks.size(); ++i) {
             final TcpKeepaliveAck keepaliveAck = mKeepaliveAcks.valueAt(i);
diff --git a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
index 809327a..44ce2db 100644
--- a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
+++ b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
@@ -108,7 +108,7 @@
         private String mLabel;
         // When mOpcode == Opcodes.JNEBS:
         private byte[] mCompareBytes;
-        // Offset in bytes from the begining of this program. Set by {@link ApfGenerator#generate}.
+        // Offset in bytes from the beginning of this program. Set by {@link ApfGenerator#generate}.
         int offset;
 
         Instruction(Opcodes opcode, Register register) {
@@ -431,7 +431,7 @@
 
     /**
      * Add an instruction to the end of the program to load the byte at offset {@code offset}
-     * bytes from the begining of the packet into {@code register}.
+     * bytes from the beginning of the packet into {@code register}.
      */
     public ApfGenerator addLoad8(Register register, int offset) {
         Instruction instruction = new Instruction(Opcodes.LDB, register);
@@ -442,7 +442,7 @@
 
     /**
      * Add an instruction to the end of the program to load 16-bits at offset {@code offset}
-     * bytes from the begining of the packet into {@code register}.
+     * bytes from the beginning of the packet into {@code register}.
      */
     public ApfGenerator addLoad16(Register register, int offset) {
         Instruction instruction = new Instruction(Opcodes.LDH, register);
@@ -453,7 +453,7 @@
 
     /**
      * Add an instruction to the end of the program to load 32-bits at offset {@code offset}
-     * bytes from the begining of the packet into {@code register}.
+     * bytes from the beginning of the packet into {@code register}.
      */
     public ApfGenerator addLoad32(Register register, int offset) {
         Instruction instruction = new Instruction(Opcodes.LDW, register);
@@ -464,7 +464,7 @@
 
     /**
      * Add an instruction to the end of the program to load a byte from the packet into
-     * {@code register}. The offset of the loaded byte from the begining of the packet is
+     * {@code register}. The offset of the loaded byte from the beginning of the packet is
      * the sum of {@code offset} and the value in register R1.
      */
     public ApfGenerator addLoad8Indexed(Register register, int offset) {
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
index 0b7809e..79d6a55 100644
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
+++ b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
@@ -102,9 +102,9 @@
 
     private static final String TAG = "DhcpClient";
     private static final boolean DBG = true;
-    private static final boolean STATE_DBG = false;
-    private static final boolean MSG_DBG = false;
-    private static final boolean PACKET_DBG = false;
+    private static final boolean STATE_DBG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean MSG_DBG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean PACKET_DBG = Log.isLoggable(TAG, Log.DEBUG);
 
     // Metrics events: must be kept in sync with server-side aggregation code.
     /** Represents transitions from DhcpInitState to DhcpBoundState */
@@ -126,6 +126,7 @@
     // DhcpClient uses IpClient's handler.
     private static final int PUBLIC_BASE = IpClient.DHCPCLIENT_CMD_BASE;
 
+    // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
     /* Commands from controller to start/stop DHCP */
     public static final int CMD_START_DHCP                  = PUBLIC_BASE + 1;
     public static final int CMD_STOP_DHCP                   = PUBLIC_BASE + 2;
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
index 346ac68..c1f178a 100644
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ b/packages/NetworkStack/src/android/net/ip/IpClient.java
@@ -282,6 +282,7 @@
 
     public static final String DUMP_ARG_CONFIRM = "confirm";
 
+    // Below constants are picked up by MessageUtils and exempt from ProGuard optimization.
     private static final int CMD_TERMINATE_AFTER_STOP             = 1;
     private static final int CMD_STOP                             = 2;
     private static final int CMD_START                            = 3;
@@ -1388,8 +1389,8 @@
             apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;
             apfConfig.multicastFilter = mMulticastFiltering;
             // Get the Configuration for ApfFilter from Context
-            apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames(mContext);
-            apfConfig.ethTypeBlackList = ApfCapabilities.getApfEthTypeBlackList(mContext);
+            apfConfig.ieee802_3Filter = ApfCapabilities.getApfDrop8023Frames();
+            apfConfig.ethTypeBlackList = ApfCapabilities.getApfEtherTypeBlackList();
             mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback);
             // TODO: investigate the effects of any multicast filtering racing/interfering with the
             // rest of this IP configuration startup.
diff --git a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
index 3aa6933..c19a24e 100644
--- a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
+++ b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
@@ -129,8 +129,8 @@
  */
 public class IpReachabilityMonitor {
     private static final String TAG = "IpReachabilityMonitor";
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
 
     public interface Callback {
         // This callback function must execute as quickly as possible as it is
diff --git a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
index 481dbda..9d2df57 100644
--- a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
+++ b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
@@ -17,10 +17,15 @@
 package android.net.util;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.provider.DeviceConfig;
+import android.util.SparseArray;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.util.List;
+import java.util.function.Predicate;
+
 
 /**
  * Collection of utilities for the network stack.
@@ -65,4 +70,32 @@
         }
         return array;
     }
+
+    /**
+     * @return True if there exists at least one element in the sparse array for which
+     * condition {@code predicate}
+     */
+    public static <T> boolean any(SparseArray<T> array, Predicate<T> predicate) {
+        for (int i = 0; i < array.size(); ++i) {
+            if (predicate.test(array.valueAt(i))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Look up the value of a property for a particular namespace from {@link DeviceConfig}.
+     * @param namespace The namespace containing the property to look up.
+     * @param name The name of the property to look up.
+     * @param defaultValue The value to return if the property does not exist or has no non-null
+     *                     value.
+     * @return the corresponding value, or defaultValue if none exists.
+     */
+    @Nullable
+    public static String getDeviceConfigProperty(@NonNull String namespace, @NonNull String name,
+            @Nullable String defaultValue) {
+        String value = DeviceConfig.getProperty(namespace, name);
+        return value != null ? value : defaultValue;
+    }
 }
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
index 19e9108..a0a90fd 100644
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
@@ -35,7 +35,9 @@
 import android.net.INetworkMonitor;
 import android.net.INetworkMonitorCallbacks;
 import android.net.INetworkStackConnector;
+import android.net.LinkProperties;
 import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.PrivateDnsConfigParcel;
 import android.net.dhcp.DhcpServer;
 import android.net.dhcp.DhcpServingParams;
@@ -301,15 +303,9 @@
         }
 
         @Override
-        public void notifySystemReady() {
+        public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
             checkNetworkStackCallingPermission();
-            mNm.notifySystemReady();
-        }
-
-        @Override
-        public void notifyNetworkConnected() {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkConnected();
+            mNm.notifyNetworkConnected(lp, nc);
         }
 
         @Override
@@ -319,15 +315,15 @@
         }
 
         @Override
-        public void notifyLinkPropertiesChanged() {
+        public void notifyLinkPropertiesChanged(LinkProperties lp) {
             checkNetworkStackCallingPermission();
-            mNm.notifyLinkPropertiesChanged();
+            mNm.notifyLinkPropertiesChanged(lp);
         }
 
         @Override
-        public void notifyNetworkCapabilitiesChanged() {
+        public void notifyNetworkCapabilitiesChanged(NetworkCapabilities nc) {
             checkNetworkStackCallingPermission();
-            mNm.notifyNetworkCapabilitiesChanged();
+            mNm.notifyNetworkCapabilitiesChanged(nc);
         }
     }
 }
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index f3476ed..6f31f9b 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -78,6 +78,7 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.RingBufferIndices;
@@ -221,19 +222,31 @@
      * Message to self indicating captive portal detection is completed.
      * obj = CaptivePortalProbeResult for detection result;
      */
-    public static final int CMD_PROBE_COMPLETE = 16;
+    private static final int CMD_PROBE_COMPLETE = 16;
 
     /**
      * ConnectivityService notifies NetworkMonitor of DNS query responses event.
      * arg1 = returncode in OnDnsEvent which indicates the response code for the DNS query.
      */
-    public static final int EVENT_DNS_NOTIFICATION = 17;
+    private static final int EVENT_DNS_NOTIFICATION = 17;
 
     /**
      * ConnectivityService notifies NetworkMonitor that the user accepts partial connectivity and
      * NetworkMonitor should ignore the https probe.
      */
-    public static final int EVENT_ACCEPT_PARTIAL_CONNECTIVITY = 18;
+    private static final int EVENT_ACCEPT_PARTIAL_CONNECTIVITY = 18;
+
+    /**
+     * ConnectivityService notifies NetworkMonitor of changed LinkProperties.
+     * obj = new LinkProperties.
+     */
+    private static final int EVENT_LINK_PROPERTIES_CHANGED = 19;
+
+    /**
+     * ConnectivityService notifies NetworkMonitor of changed NetworkCapabilities.
+     * obj = new NetworkCapabilities.
+     */
+    private static final int EVENT_NETWORK_CAPABILITIES_CHANGED = 20;
 
     // Start mReevaluateDelayMs at this value and double.
     private static final int INITIAL_REEVALUATE_DELAY_MS = 1000;
@@ -285,8 +298,6 @@
     // Avoids surfacing "Sign in to network" notification.
     private boolean mDontDisplaySigninNotification = false;
 
-    private volatile boolean mSystemReady = false;
-
     private final State mDefaultState = new DefaultState();
     private final State mValidatedState = new ValidatedState();
     private final State mMaybeNotifyState = new MaybeNotifyState();
@@ -379,10 +390,8 @@
         mDataStallValidDnsTimeThreshold = getDataStallValidDnsTimeThreshold();
         mDataStallEvaluationType = getDataStallEvalutionType();
 
-        // mLinkProperties and mNetworkCapbilities must never be null or we will NPE.
-        // Provide empty objects in case we are started and the network disconnects before
-        // we can ever fetch them.
-        // TODO: Delete ASAP.
+        // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null,
+        // even before notifyNetworkConnected.
         mLinkProperties = new LinkProperties();
         mNetworkCapabilities = new NetworkCapabilities(null);
     }
@@ -423,19 +432,18 @@
     }
 
     /**
-     * Send a notification to NetworkMonitor indicating that the system is ready.
-     */
-    public void notifySystemReady() {
-        // No need to run on the handler thread: mSystemReady is volatile and read only once on the
-        // isCaptivePortal() thread.
-        mSystemReady = true;
-    }
-
-    /**
      * Send a notification to NetworkMonitor indicating that the network is now connected.
      */
-    public void notifyNetworkConnected() {
-        sendMessage(CMD_NETWORK_CONNECTED);
+    public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
+        sendMessage(CMD_NETWORK_CONNECTED, new Pair<>(
+                new LinkProperties(lp), new NetworkCapabilities(nc)));
+    }
+
+    private void updateConnectedNetworkAttributes(Message connectedMsg) {
+        final Pair<LinkProperties, NetworkCapabilities> attrs =
+                (Pair<LinkProperties, NetworkCapabilities>) connectedMsg.obj;
+        mLinkProperties = attrs.first;
+        mNetworkCapabilities = attrs.second;
     }
 
     /**
@@ -448,37 +456,15 @@
     /**
      * Send a notification to NetworkMonitor indicating that link properties have changed.
      */
-    public void notifyLinkPropertiesChanged() {
-        getHandler().post(() -> {
-            updateLinkProperties();
-        });
-    }
-
-    private void updateLinkProperties() {
-        final LinkProperties lp = mCm.getLinkProperties(mNetwork);
-        // If null, we should soon get a message that the network was disconnected, and will stop.
-        if (lp != null) {
-            // TODO: send LinkProperties parceled in notifyLinkPropertiesChanged() and start().
-            mLinkProperties = lp;
-        }
+    public void notifyLinkPropertiesChanged(final LinkProperties lp) {
+        sendMessage(EVENT_LINK_PROPERTIES_CHANGED, new LinkProperties(lp));
     }
 
     /**
      * Send a notification to NetworkMonitor indicating that network capabilities have changed.
      */
-    public void notifyNetworkCapabilitiesChanged() {
-        getHandler().post(() -> {
-            updateNetworkCapabilities();
-        });
-    }
-
-    private void updateNetworkCapabilities() {
-        final NetworkCapabilities nc = mCm.getNetworkCapabilities(mNetwork);
-        // If null, we should soon get a message that the network was disconnected, and will stop.
-        if (nc != null) {
-            // TODO: send NetworkCapabilities parceled in notifyNetworkCapsChanged() and start().
-            mNetworkCapabilities = nc;
-        }
+    public void notifyNetworkCapabilitiesChanged(final NetworkCapabilities nc) {
+        sendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED, new NetworkCapabilities(nc));
     }
 
     /**
@@ -547,16 +533,10 @@
     // does not entail any real state (hence no enter() or exit() routines).
     private class DefaultState extends State {
         @Override
-        public void enter() {
-            // TODO: have those passed parceled in start() and remove this
-            updateLinkProperties();
-            updateNetworkCapabilities();
-        }
-
-        @Override
         public boolean processMessage(Message message) {
             switch (message.what) {
                 case CMD_NETWORK_CONNECTED:
+                    updateConnectedNetworkAttributes(message);
                     logNetworkEvent(NetworkEvent.NETWORK_CONNECTED);
                     transitionTo(mEvaluatingState);
                     return HANDLED;
@@ -660,6 +640,12 @@
                 case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
                     mAcceptPartialConnectivity = true;
                     break;
+                case EVENT_LINK_PROPERTIES_CHANGED:
+                    mLinkProperties = (LinkProperties) message.obj;
+                    break;
+                case EVENT_NETWORK_CAPABILITIES_CHANGED:
+                    mNetworkCapabilities = (NetworkCapabilities) message.obj;
+                    break;
                 default:
                     break;
             }
@@ -684,6 +670,7 @@
         public boolean processMessage(Message message) {
             switch (message.what) {
                 case CMD_NETWORK_CONNECTED:
+                    updateConnectedNetworkAttributes(message);
                     transitionTo(mValidatedState);
                     break;
                 case CMD_EVALUATE_PRIVATE_DNS:
@@ -1594,10 +1581,6 @@
      */
     private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal,
             long requestTimestampMs, long responseTimestampMs) {
-        if (!mSystemReady) {
-            return;
-        }
-
         Intent latencyBroadcast =
                 new Intent(NetworkMonitorUtils.ACTION_NETWORK_CONDITIONS_MEASURED);
         if (mNetworkCapabilities.hasTransport(TRANSPORT_WIFI)) {
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
index 4d4ceed..764e2d0 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
@@ -72,6 +72,10 @@
         public static final String COLNAME_ASSIGNEDV4ADDRESS = "assignedV4Address";
         public static final String COLTYPE_ASSIGNEDV4ADDRESS = "INTEGER";
 
+        public static final String COLNAME_ASSIGNEDV4ADDRESSEXPIRY = "assignedV4AddressExpiry";
+        // The lease expiry timestamp in uint of milliseconds
+        public static final String COLTYPE_ASSIGNEDV4ADDRESSEXPIRY = "BIGINT";
+
         // Please note that the group hint is only a *hint*, hence its name. The client can offer
         // this information to nudge the grouping in the decision it thinks is right, but it can't
         // decide for the memory store what is the same L3 network.
@@ -86,13 +90,14 @@
         public static final String COLTYPE_MTU = "INTEGER DEFAULT -1";
 
         public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
-                + TABLENAME                 + " ("
-                + COLNAME_L2KEY             + " " + COLTYPE_L2KEY + " PRIMARY KEY NOT NULL, "
-                + COLNAME_EXPIRYDATE        + " " + COLTYPE_EXPIRYDATE        + ", "
-                + COLNAME_ASSIGNEDV4ADDRESS + " " + COLTYPE_ASSIGNEDV4ADDRESS + ", "
-                + COLNAME_GROUPHINT         + " " + COLTYPE_GROUPHINT         + ", "
-                + COLNAME_DNSADDRESSES      + " " + COLTYPE_DNSADDRESSES      + ", "
-                + COLNAME_MTU               + " " + COLTYPE_MTU               + ")";
+                + TABLENAME                       + " ("
+                + COLNAME_L2KEY                   + " " + COLTYPE_L2KEY + " PRIMARY KEY NOT NULL, "
+                + COLNAME_EXPIRYDATE              + " " + COLTYPE_EXPIRYDATE              + ", "
+                + COLNAME_ASSIGNEDV4ADDRESS       + " " + COLTYPE_ASSIGNEDV4ADDRESS       + ", "
+                + COLNAME_ASSIGNEDV4ADDRESSEXPIRY + " " + COLTYPE_ASSIGNEDV4ADDRESSEXPIRY + ", "
+                + COLNAME_GROUPHINT               + " " + COLTYPE_GROUPHINT               + ", "
+                + COLNAME_DNSADDRESSES            + " " + COLTYPE_DNSADDRESSES            + ", "
+                + COLNAME_MTU                     + " " + COLTYPE_MTU                     + ")";
         public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
     }
 
@@ -134,8 +139,9 @@
     /** The SQLite DB helper */
     public static class DbHelper extends SQLiteOpenHelper {
         // Update this whenever changing the schema.
-        private static final int SCHEMA_VERSION = 2;
+        private static final int SCHEMA_VERSION = 4;
         private static final String DATABASE_FILENAME = "IpMemoryStore.db";
+        private static final String TRIGGER_NAME = "delete_cascade_to_private";
 
         public DbHelper(@NonNull final Context context) {
             super(context, DATABASE_FILENAME, null, SCHEMA_VERSION);
@@ -147,16 +153,38 @@
         public void onCreate(@NonNull final SQLiteDatabase db) {
             db.execSQL(NetworkAttributesContract.CREATE_TABLE);
             db.execSQL(PrivateDataContract.CREATE_TABLE);
+            createTrigger(db);
         }
 
         /** Called when the database is upgraded */
         @Override
         public void onUpgrade(@NonNull final SQLiteDatabase db, final int oldVersion,
                 final int newVersion) {
-            // No upgrade supported yet.
-            db.execSQL(NetworkAttributesContract.DROP_TABLE);
-            db.execSQL(PrivateDataContract.DROP_TABLE);
-            onCreate(db);
+            try {
+                if (oldVersion < 2) {
+                    // upgrade from version 1 to version 2
+                    // since we starts from version 2, do nothing here
+                }
+
+                if (oldVersion < 3) {
+                    // upgrade from version 2 to version 3
+                    final String sqlUpgradeAddressExpiry = "alter table"
+                            + " " + NetworkAttributesContract.TABLENAME + " ADD"
+                            + " " + NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY
+                            + " " + NetworkAttributesContract.COLTYPE_ASSIGNEDV4ADDRESSEXPIRY;
+                    db.execSQL(sqlUpgradeAddressExpiry);
+                }
+
+                if (oldVersion < 4) {
+                    createTrigger(db);
+                }
+            } catch (SQLiteException e) {
+                Log.e(TAG, "Could not upgrade to the new version", e);
+                // create database with new version
+                db.execSQL(NetworkAttributesContract.DROP_TABLE);
+                db.execSQL(PrivateDataContract.DROP_TABLE);
+                onCreate(db);
+            }
         }
 
         /** Called when the database is downgraded */
@@ -166,8 +194,20 @@
             // Downgrades always nuke all data and recreate an empty table.
             db.execSQL(NetworkAttributesContract.DROP_TABLE);
             db.execSQL(PrivateDataContract.DROP_TABLE);
+            db.execSQL("DROP TRIGGER " + TRIGGER_NAME);
             onCreate(db);
         }
+
+        private void createTrigger(@NonNull final SQLiteDatabase db) {
+            final String createTrigger = "CREATE TRIGGER " + TRIGGER_NAME
+                    + " DELETE ON " + NetworkAttributesContract.TABLENAME
+                    + " BEGIN"
+                    + " DELETE FROM " + PrivateDataContract.TABLENAME + " WHERE OLD."
+                    + NetworkAttributesContract.COLNAME_L2KEY
+                    + "=" + PrivateDataContract.COLNAME_L2KEY
+                    + "; END;";
+            db.execSQL(createTrigger);
+        }
     }
 
     @NonNull
@@ -204,6 +244,10 @@
             values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS,
                     inet4AddressToIntHTH(attributes.assignedV4Address));
         }
+        if (null != attributes.assignedV4AddressExpiry) {
+            values.put(NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY,
+                    attributes.assignedV4AddressExpiry);
+        }
         if (null != attributes.groupHint) {
             values.put(NetworkAttributesContract.COLNAME_GROUPHINT, attributes.groupHint);
         }
@@ -251,6 +295,8 @@
         final NetworkAttributes.Builder builder = new NetworkAttributes.Builder();
         final int assignedV4AddressInt = getInt(cursor,
                 NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESS, 0);
+        final long assignedV4AddressExpiry = getLong(cursor,
+                NetworkAttributesContract.COLNAME_ASSIGNEDV4ADDRESSEXPIRY, 0);
         final String groupHint = getString(cursor, NetworkAttributesContract.COLNAME_GROUPHINT);
         final byte[] dnsAddressesBlob =
                 getBlob(cursor, NetworkAttributesContract.COLNAME_DNSADDRESSES);
@@ -258,6 +304,9 @@
         if (0 != assignedV4AddressInt) {
             builder.setAssignedV4Address(intToInet4AddressHTH(assignedV4AddressInt));
         }
+        if (0 != assignedV4AddressExpiry) {
+            builder.setAssignedV4AddressExpiry(assignedV4AddressExpiry);
+        }
         builder.setGroupHint(groupHint);
         if (null != dnsAddressesBlob) {
             builder.setDnsAddresses(decodeAddressList(dnsAddressesBlob));
@@ -305,7 +354,7 @@
     }
 
     // If the attributes are null, this will only write the expiry.
-    // Returns an int out of Status.{SUCCESS,ERROR_*}
+    // Returns an int out of Status.{SUCCESS, ERROR_*}
     static int storeNetworkAttributes(@NonNull final SQLiteDatabase db, @NonNull final String key,
             final long expiry, @Nullable final NetworkAttributes attributes) {
         final ContentValues cv = toContentValues(key, attributes, expiry);
@@ -330,7 +379,7 @@
         return Status.ERROR_STORAGE;
     }
 
-    // Returns an int out of Status.{SUCCESS,ERROR_*}
+    // Returns an int out of Status.{SUCCESS, ERROR_*}
     static int storeBlob(@NonNull final SQLiteDatabase db, @NonNull final String key,
             @NonNull final String clientId, @NonNull final String name,
             @NonNull final byte[] data) {
@@ -493,6 +542,93 @@
         return bestKey;
     }
 
+    // Drops all records that are expired. Relevance has decayed to zero of these records. Returns
+    // an int out of Status.{SUCCESS, ERROR_*}
+    static int dropAllExpiredRecords(@NonNull final SQLiteDatabase db) {
+        db.beginTransaction();
+        try {
+            // Deletes NetworkAttributes that have expired.
+            db.delete(NetworkAttributesContract.TABLENAME,
+                    NetworkAttributesContract.COLNAME_EXPIRYDATE + " < ?",
+                    new String[]{Long.toString(System.currentTimeMillis())});
+            db.setTransactionSuccessful();
+        } catch (SQLiteException e) {
+            Log.e(TAG, "Could not delete data from memory store", e);
+            return Status.ERROR_STORAGE;
+        } finally {
+            db.endTransaction();
+        }
+
+        // Execute vacuuming here if above operation has no exception. If above operation got
+        // exception, vacuuming can be ignored for reducing unnecessary consumption.
+        try {
+            db.execSQL("VACUUM");
+        } catch (SQLiteException e) {
+            // Do nothing.
+        }
+        return Status.SUCCESS;
+    }
+
+    // Drops number of records that start from the lowest expiryDate. Returns an int out of
+    // Status.{SUCCESS, ERROR_*}
+    static int dropNumberOfRecords(@NonNull final SQLiteDatabase db, int number) {
+        if (number <= 0) {
+            return Status.ERROR_ILLEGAL_ARGUMENT;
+        }
+
+        // Queries number of NetworkAttributes that start from the lowest expiryDate.
+        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
+                new String[] {NetworkAttributesContract.COLNAME_EXPIRYDATE}, // columns
+                null, // selection
+                null, // selectionArgs
+                null, // groupBy
+                null, // having
+                NetworkAttributesContract.COLNAME_EXPIRYDATE, // orderBy
+                Integer.toString(number)); // limit
+        if (cursor == null || cursor.getCount() <= 0) return Status.ERROR_GENERIC;
+        cursor.moveToLast();
+
+        //Get the expiryDate from last record.
+        final long expiryDate = getLong(cursor, NetworkAttributesContract.COLNAME_EXPIRYDATE, 0);
+        cursor.close();
+
+        db.beginTransaction();
+        try {
+            // Deletes NetworkAttributes that expiryDate are lower than given value.
+            db.delete(NetworkAttributesContract.TABLENAME,
+                    NetworkAttributesContract.COLNAME_EXPIRYDATE + " <= ?",
+                    new String[]{Long.toString(expiryDate)});
+            db.setTransactionSuccessful();
+        } catch (SQLiteException e) {
+            Log.e(TAG, "Could not delete data from memory store", e);
+            return Status.ERROR_STORAGE;
+        } finally {
+            db.endTransaction();
+        }
+
+        // Execute vacuuming here if above operation has no exception. If above operation got
+        // exception, vacuuming can be ignored for reducing unnecessary consumption.
+        try {
+            db.execSQL("VACUUM");
+        } catch (SQLiteException e) {
+            // Do nothing.
+        }
+        return Status.SUCCESS;
+    }
+
+    static int getTotalRecordNumber(@NonNull final SQLiteDatabase db) {
+        // Query the total number of NetworkAttributes
+        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
+                new String[] {"COUNT(*)"}, // columns
+                null, // selection
+                null, // selectionArgs
+                null, // groupBy
+                null, // having
+                null); // orderBy
+        cursor.moveToFirst();
+        return cursor == null ? 0 : cursor.getInt(0);
+    }
+
     // Helper methods
     private static String getString(final Cursor cursor, final String columnName) {
         final int columnIndex = cursor.getColumnIndex(columnName);
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
index f801b35..bee4bbd9 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
@@ -22,6 +22,7 @@
 import static android.net.ipmemorystore.Status.SUCCESS;
 
 import static com.android.server.connectivity.ipmemorystore.IpMemoryStoreDatabase.EXPIRY_ERROR;
+import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -32,8 +33,8 @@
 import android.net.ipmemorystore.Blob;
 import android.net.ipmemorystore.IOnBlobRetrievedListener;
 import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
+import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
 import android.net.ipmemorystore.IOnStatusListener;
 import android.net.ipmemorystore.NetworkAttributes;
 import android.net.ipmemorystore.NetworkAttributesParcelable;
@@ -43,6 +44,9 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.File;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -57,8 +61,17 @@
 public class IpMemoryStoreService extends IIpMemoryStore.Stub {
     private static final String TAG = IpMemoryStoreService.class.getSimpleName();
     private static final int MAX_CONCURRENT_THREADS = 4;
+    private static final int DATABASE_SIZE_THRESHOLD = 10 * 1024 * 1024; //10MB
+    private static final int MAX_DROP_RECORD_TIMES = 500;
+    private static final int MIN_DELETE_NUM = 5;
     private static final boolean DBG = true;
 
+    // Error codes below are internal and used for notifying status beteween IpMemoryStore modules.
+    static final int ERROR_INTERNAL_BASE = -1_000_000_000;
+    // This error code is used for maintenance only to notify RegularMaintenanceJobService that
+    // full maintenance job has been interrupted.
+    static final int ERROR_INTERNAL_INTERRUPTED = ERROR_INTERNAL_BASE - 1;
+
     @NonNull
     final Context mContext;
     @Nullable
@@ -111,6 +124,7 @@
         // with judicious subclassing of ThreadPoolExecutor, but that's a lot of dangerous
         // complexity for little benefit in this case.
         mExecutor = Executors.newWorkStealingPool(MAX_CONCURRENT_THREADS);
+        RegularMaintenanceJobService.schedule(mContext, this);
     }
 
     /**
@@ -125,6 +139,7 @@
         // guarantee the threads can be terminated in any given amount of time.
         mExecutor.shutdownNow();
         if (mDb != null) mDb.close();
+        RegularMaintenanceJobService.unschedule(mContext);
     }
 
     /** Helper function to make a status object */
@@ -282,16 +297,16 @@
      */
     @Override
     public void isSameNetwork(@Nullable final String l2Key1, @Nullable final String l2Key2,
-            @Nullable final IOnSameNetworkResponseListener listener) {
+            @Nullable final IOnSameL3NetworkResponseListener listener) {
         if (null == listener) return;
         mExecutor.execute(() -> {
             try {
                 if (null == l2Key1 || null == l2Key2) {
-                    listener.onSameNetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
+                    listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
                     return;
                 }
                 if (null == mDb) {
-                    listener.onSameNetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
+                    listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
                     return;
                 }
                 try {
@@ -300,16 +315,16 @@
                     final NetworkAttributes attr2 =
                             IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key2);
                     if (null == attr1 || null == attr2) {
-                        listener.onSameNetworkResponse(makeStatus(SUCCESS),
+                        listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
                                 new SameL3NetworkResponse(l2Key1, l2Key2,
                                         -1f /* never connected */).toParcelable());
                         return;
                     }
                     final float confidence = attr1.getNetworkGroupSamenessConfidence(attr2);
-                    listener.onSameNetworkResponse(makeStatus(SUCCESS),
+                    listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
                             new SameL3NetworkResponse(l2Key1, l2Key2, confidence).toParcelable());
                 } catch (Exception e) {
-                    listener.onSameNetworkResponse(makeStatus(ERROR_GENERIC), null);
+                    listener.onSameL3NetworkResponse(makeStatus(ERROR_GENERIC), null);
                 }
             } catch (final RemoteException e) {
                 // Client at the other end died
@@ -328,7 +343,7 @@
      */
     @Override
     public void retrieveNetworkAttributes(@Nullable final String l2Key,
-            @Nullable final IOnNetworkAttributesRetrieved listener) {
+            @Nullable final IOnNetworkAttributesRetrievedListener listener) {
         if (null == listener) return;
         mExecutor.execute(() -> {
             try {
@@ -394,4 +409,89 @@
             }
         });
     }
+
+    /** Get db size threshold. */
+    @VisibleForTesting
+    protected int getDbSizeThreshold() {
+        return DATABASE_SIZE_THRESHOLD;
+    }
+
+    private long getDbSize() {
+        final File dbFile = new File(mDb.getPath());
+        try {
+            return dbFile.length();
+        } catch (final SecurityException e) {
+            if (DBG) Log.e(TAG, "Read db size access deny.", e);
+            // Return zero value if can't get disk usage exactly.
+            return 0;
+        }
+    }
+
+    /** Check if db size is over the threshold. */
+    @VisibleForTesting
+    boolean isDbSizeOverThreshold() {
+        return getDbSize() > getDbSizeThreshold();
+    }
+
+    /**
+     * Full maintenance.
+     *
+     * @param listener A listener to inform of the completion of this call.
+     */
+    void fullMaintenance(@NonNull final IOnStatusListener listener,
+            @NonNull final InterruptMaintenance interrupt) {
+        mExecutor.execute(() -> {
+            try {
+                if (null == mDb) {
+                    listener.onComplete(makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED));
+                    return;
+                }
+
+                // Interrupt maintenance because the scheduling job has been canceled.
+                if (checkForInterrupt(listener, interrupt)) return;
+
+                int result = SUCCESS;
+                // Drop all records whose relevance has decayed to zero.
+                // This is the first step to decrease memory store size.
+                result = IpMemoryStoreDatabase.dropAllExpiredRecords(mDb);
+
+                if (checkForInterrupt(listener, interrupt)) return;
+
+                // Aggregate historical data in passes
+                // TODO : Waiting for historical data implement.
+
+                // Check if db size meets the storage goal(10MB). If not, keep dropping records and
+                // aggregate historical data until the storage goal is met. Use for loop with 500
+                // times restriction to prevent infinite loop (Deleting records always fail and db
+                // size is still over the threshold)
+                for (int i = 0; isDbSizeOverThreshold() && i < MAX_DROP_RECORD_TIMES; i++) {
+                    if (checkForInterrupt(listener, interrupt)) return;
+
+                    final int totalNumber = IpMemoryStoreDatabase.getTotalRecordNumber(mDb);
+                    final long dbSize = getDbSize();
+                    final float decreaseRate = (dbSize == 0)
+                            ? 0 : (float) (dbSize - getDbSizeThreshold()) / (float) dbSize;
+                    final int deleteNumber = Math.max(
+                            (int) (totalNumber * decreaseRate), MIN_DELETE_NUM);
+
+                    result = IpMemoryStoreDatabase.dropNumberOfRecords(mDb, deleteNumber);
+
+                    if (checkForInterrupt(listener, interrupt)) return;
+
+                    // Aggregate historical data
+                    // TODO : Waiting for historical data implement.
+                }
+                listener.onComplete(makeStatus(result));
+            } catch (final RemoteException e) {
+                // Client at the other end died
+            }
+        });
+    }
+
+    private boolean checkForInterrupt(@NonNull final IOnStatusListener listener,
+            @NonNull final InterruptMaintenance interrupt) throws RemoteException {
+        if (!interrupt.isInterrupted()) return false;
+        listener.onComplete(makeStatus(ERROR_INTERNAL_INTERRUPTED));
+        return true;
+    }
 }
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
new file mode 100644
index 0000000..2775fde
--- /dev/null
+++ b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity.ipmemorystore;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.ipmemorystore.IOnStatusListener;
+import android.net.ipmemorystore.Status;
+import android.net.ipmemorystore.StatusParcelable;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Regular maintenance job service.
+ * @hide
+ */
+public final class RegularMaintenanceJobService extends JobService {
+    // Must be unique within the system server uid.
+    public static final int REGULAR_MAINTENANCE_ID = 3345678;
+
+    /**
+     * Class for interrupt check of maintenance job.
+     */
+    public static final class InterruptMaintenance {
+        private volatile boolean mIsInterrupted;
+        private final int mJobId;
+
+        public InterruptMaintenance(int jobId) {
+            mJobId = jobId;
+            mIsInterrupted = false;
+        }
+
+        public int getJobId() {
+            return mJobId;
+        }
+
+        public void setInterrupted(boolean interrupt) {
+            mIsInterrupted = interrupt;
+        }
+
+        public boolean isInterrupted() {
+            return mIsInterrupted;
+        }
+    }
+
+    private static final ArrayList<InterruptMaintenance> sInterruptList = new ArrayList<>();
+    private static IpMemoryStoreService sIpMemoryStoreService;
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        if (sIpMemoryStoreService == null) {
+            Log.wtf("RegularMaintenanceJobService",
+                    "Can not start job because sIpMemoryStoreService is null.");
+            return false;
+        }
+        final InterruptMaintenance im = new InterruptMaintenance(params.getJobId());
+        sInterruptList.add(im);
+
+        sIpMemoryStoreService.fullMaintenance(new IOnStatusListener() {
+            @Override
+            public void onComplete(final StatusParcelable statusParcelable) throws RemoteException {
+                final Status result = new Status(statusParcelable);
+                if (!result.isSuccess()) {
+                    Log.e("RegularMaintenanceJobService", "Regular maintenance failed."
+                            + " Error is " + result.resultCode);
+                }
+                sInterruptList.remove(im);
+                jobFinished(params, !result.isSuccess());
+            }
+
+            @Override
+            public IBinder asBinder() {
+                return null;
+            }
+        }, im);
+        return true;
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        final int jobId = params.getJobId();
+        for (InterruptMaintenance im : sInterruptList) {
+            if (im.getJobId() == jobId) {
+                im.setInterrupted(true);
+            }
+        }
+        return true;
+    }
+
+    /** Schedule regular maintenance job */
+    static void schedule(Context context, IpMemoryStoreService ipMemoryStoreService) {
+        final JobScheduler jobScheduler =
+                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+
+        final ComponentName maintenanceJobName =
+                new ComponentName(context, RegularMaintenanceJobService.class);
+
+        // Regular maintenance is scheduled for when the device is idle with access power and a
+        // minimum interval of one day.
+        final JobInfo regularMaintenanceJob =
+                new JobInfo.Builder(REGULAR_MAINTENANCE_ID, maintenanceJobName)
+                        .setRequiresDeviceIdle(true)
+                        .setRequiresCharging(true)
+                        .setRequiresBatteryNotLow(true)
+                        .setPeriodic(TimeUnit.HOURS.toMillis(24)).build();
+
+        jobScheduler.schedule(regularMaintenanceJob);
+        sIpMemoryStoreService = ipMemoryStoreService;
+    }
+
+    /** Unschedule regular maintenance job */
+    static void unschedule(Context context) {
+        final JobScheduler jobScheduler =
+                (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        jobScheduler.cancel(REGULAR_MAINTENANCE_ID);
+        sIpMemoryStoreService = null;
+    }
+}
diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp
index aadf99e..0535af3 100644
--- a/packages/NetworkStack/tests/Android.bp
+++ b/packages/NetworkStack/tests/Android.bp
@@ -45,6 +45,8 @@
         "libcrypto",
         "libcutils",
         "libdexfile",
+        "ld-android",
+        "libdl_android",
         "libhidl-gen-utils",
         "libhidlbase",
         "libhidltransport",
diff --git a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
index 88a05d5..a0e508f 100644
--- a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
+++ b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
@@ -1006,7 +1006,7 @@
 
     private static final int IPV4_HEADER_LEN = 20;
     private static final int IPV4_VERSION_IHL_OFFSET = ETH_HEADER_LEN + 0;
-    private static final int IPV4_TOTAL_LENGTH_OFFSET  = ETH_HEADER_LEN + 2;
+    private static final int IPV4_TOTAL_LENGTH_OFFSET = ETH_HEADER_LEN + 2;
     private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
     private static final int IPV4_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 12;
     private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
diff --git a/tests/net/java/android/net/captiveportal/CaptivePortalProbeSpecTest.java b/packages/NetworkStack/tests/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
similarity index 100%
rename from tests/net/java/android/net/captiveportal/CaptivePortalProbeSpecTest.java
rename to packages/NetworkStack/tests/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
index d732c4e..6665aae 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -26,6 +26,8 @@
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -60,6 +62,7 @@
 import android.os.Bundle;
 import android.os.ConditionVariable;
 import android.os.Handler;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.telephony.CellSignalStrength;
@@ -73,6 +76,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
@@ -107,6 +111,7 @@
     private @Spy Network mNetwork = new Network(TEST_NETID);
     private @Mock DataStallStatsUtils mDataStallStatsUtils;
     private @Mock WifiInfo mWifiInfo;
+    private @Captor ArgumentCaptor<String> mNetworkTestedRedirectUrlCaptor;
 
     private static final int TEST_NETID = 4242;
 
@@ -122,7 +127,7 @@
 
     private static final int HANDLER_TIMEOUT_MS = 1000;
 
-    private static final LinkProperties TEST_LINKPROPERTIES = new LinkProperties();
+    private static final LinkProperties TEST_LINK_PROPERTIES = new LinkProperties();
 
     private static final NetworkCapabilities METERED_CAPABILITIES = new NetworkCapabilities()
             .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
@@ -182,10 +187,6 @@
                 InetAddresses.parseNumericAddress("192.168.0.0")
         }).when(mNetwork).getAllByName(any());
 
-        // Default values. Individual tests can override these.
-        when(mCm.getLinkProperties(any())).thenReturn(TEST_LINKPROPERTIES);
-        when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES);
-
         setMinDataStallEvaluateInterval(500);
         setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS);
         setValidDataStallDnsTimeThreshold(500);
@@ -195,10 +196,9 @@
     private class WrappedNetworkMonitor extends NetworkMonitor {
         private long mProbeTime = 0;
 
-        WrappedNetworkMonitor(Context context, Network network, IpConnectivityLog logger,
-                Dependencies deps, DataStallStatsUtils statsUtils) {
-                super(context, mCallbacks, network, logger,
-                        new SharedLog("test_nm"), deps, statsUtils);
+        WrappedNetworkMonitor() {
+                super(mContext, mCallbacks, mNetwork, mLogger, mValidationLogger, mDependencies,
+                        mDataStallStatsUtils);
         }
 
         @Override
@@ -216,33 +216,30 @@
         }
     }
 
-    private WrappedNetworkMonitor makeMeteredWrappedNetworkMonitor() {
-        final WrappedNetworkMonitor nm = new WrappedNetworkMonitor(
-                mContext, mNetwork, mLogger, mDependencies, mDataStallStatsUtils);
-        when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES);
+    private WrappedNetworkMonitor makeMonitor() {
+        final WrappedNetworkMonitor nm = new WrappedNetworkMonitor();
         nm.start();
         waitForIdle(nm.getHandler());
         return nm;
     }
 
-    private WrappedNetworkMonitor makeNotMeteredWrappedNetworkMonitor() {
-        final WrappedNetworkMonitor nm = new WrappedNetworkMonitor(
-                mContext, mNetwork, mLogger, mDependencies, mDataStallStatsUtils);
-        when(mCm.getNetworkCapabilities(any())).thenReturn(NOT_METERED_CAPABILITIES);
-        nm.start();
-        waitForIdle(nm.getHandler());
+    private WrappedNetworkMonitor makeMeteredNetworkMonitor() {
+        final WrappedNetworkMonitor nm = makeMonitor();
+        setNetworkCapabilities(nm, METERED_CAPABILITIES);
         return nm;
     }
 
-    private NetworkMonitor makeMonitor() {
-        final NetworkMonitor nm = new NetworkMonitor(
-                mContext, mCallbacks, mNetwork, mLogger, mValidationLogger,
-                mDependencies, mDataStallStatsUtils);
-        nm.start();
-        waitForIdle(nm.getHandler());
+    private WrappedNetworkMonitor makeNotMeteredNetworkMonitor() {
+        final WrappedNetworkMonitor nm = makeMonitor();
+        setNetworkCapabilities(nm, NOT_METERED_CAPABILITIES);
         return nm;
     }
 
+    private void setNetworkCapabilities(NetworkMonitor nm, NetworkCapabilities nc) {
+        nm.notifyNetworkCapabilitiesChanged(nc);
+        waitForIdle(nm.getHandler());
+    }
+
     private void waitForIdle(Handler handler) {
         final ConditionVariable cv = new ConditionVariable(false);
         handler.post(cv::open);
@@ -256,7 +253,7 @@
         setSslException(mHttpsConnection);
         setPortal302(mHttpConnection);
 
-        assertPortal(makeMonitor().isCaptivePortal());
+        runPortalNetworkTest();
     }
 
     @Test
@@ -264,17 +261,7 @@
         setStatus(mHttpsConnection, 204);
         setStatus(mHttpConnection, 500);
 
-        assertNotPortal(makeMonitor().isCaptivePortal());
-    }
-
-    @Test
-    public void testIsCaptivePortal_HttpsProbeFailedHttpSuccessNotUsed() throws IOException {
-        setSslException(mHttpsConnection);
-        // Even if HTTP returns a 204, do not use the result unless HTTPS succeeded
-        setStatus(mHttpConnection, 204);
-        setStatus(mFallbackConnection, 500);
-
-        assertFailed(makeMonitor().isCaptivePortal());
+        runNotPortalNetworkTest();
     }
 
     @Test
@@ -283,17 +270,17 @@
         setStatus(mHttpConnection, 500);
         setPortal302(mFallbackConnection);
 
-        assertPortal(makeMonitor().isCaptivePortal());
+        runPortalNetworkTest();
     }
 
     @Test
     public void testIsCaptivePortal_FallbackProbeIsNotPortal() throws IOException {
         setSslException(mHttpsConnection);
         setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 204);
+        setStatus(mFallbackConnection, 500);
 
         // Fallback probe did not see portal, HTTPS failed -> inconclusive
-        assertFailed(makeMonitor().isCaptivePortal());
+        runFailedNetworkTest();
     }
 
     @Test
@@ -310,15 +297,15 @@
         // TEST_OTHER_FALLBACK_URL is third
         when(mRandom.nextInt()).thenReturn(2);
 
-        final NetworkMonitor monitor = makeMonitor();
-
         // First check always uses the first fallback URL: inconclusive
-        assertFailed(monitor.isCaptivePortal());
+        final NetworkMonitor monitor = runNetworkTest(NETWORK_TEST_RESULT_INVALID);
+        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
         verify(mFallbackConnection, times(1)).getResponseCode();
         verify(mOtherFallbackConnection, never()).getResponseCode();
 
         // Second check uses the URL chosen by Random
-        assertPortal(monitor.isCaptivePortal());
+        final CaptivePortalProbeResult result = monitor.isCaptivePortal();
+        assertTrue(result.isPortal());
         verify(mOtherFallbackConnection, times(1)).getResponseCode();
     }
 
@@ -328,7 +315,7 @@
         setStatus(mHttpConnection, 500);
         setStatus(mFallbackConnection, 404);
 
-        assertFailed(makeMonitor().isCaptivePortal());
+        runFailedNetworkTest();
         verify(mFallbackConnection, times(1)).getResponseCode();
         verify(mOtherFallbackConnection, never()).getResponseCode();
     }
@@ -342,7 +329,7 @@
         setStatus(mHttpConnection, 500);
         setPortal302(mOtherFallbackConnection);
 
-        assertPortal(makeMonitor().isCaptivePortal());
+        runPortalNetworkTest();
         verify(mOtherFallbackConnection, times(1)).getResponseCode();
         verify(mFallbackConnection, never()).getResponseCode();
     }
@@ -360,12 +347,12 @@
     }
 
     @Test
-    public void testIsCaptivePortal_FallbackSpecIsNotPortal() throws IOException {
+    public void testIsCaptivePortal_FallbackSpecIsPartial() throws IOException {
         setupFallbackSpec();
         set302(mOtherFallbackConnection, "https://www.google.com/test?q=3");
 
-        // HTTPS failed, fallback spec did not see a portal -> inconclusive
-        assertFailed(makeMonitor().isCaptivePortal());
+        // HTTPS failed, fallback spec went through -> partial connectivity
+        runPartialConnectivityNetworkTest();
         verify(mOtherFallbackConnection, times(1)).getResponseCode();
         verify(mFallbackConnection, never()).getResponseCode();
     }
@@ -375,7 +362,7 @@
         setupFallbackSpec();
         set302(mOtherFallbackConnection, "http://login.portal.example.com");
 
-        assertPortal(makeMonitor().isCaptivePortal());
+        runPortalNetworkTest();
     }
 
     @Test
@@ -384,20 +371,20 @@
         setSslException(mHttpsConnection);
         setPortal302(mHttpConnection);
 
-        assertNotPortal(makeMonitor().isCaptivePortal());
+        runNotPortalNetworkTest();
     }
 
     @Test
     public void testIsDataStall_EvaluationDisabled() {
         setDataStallEvaluationType(0);
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredWrappedNetworkMonitor();
+        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
         wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
         assertFalse(wrappedMonitor.isDataStall());
     }
 
     @Test
     public void testIsDataStall_EvaluationDnsOnNotMeteredNetwork() {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor();
+        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
         wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
         makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
         assertTrue(wrappedMonitor.isDataStall());
@@ -405,7 +392,7 @@
 
     @Test
     public void testIsDataStall_EvaluationDnsOnMeteredNetwork() {
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredWrappedNetworkMonitor();
+        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
         wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
         assertFalse(wrappedMonitor.isDataStall());
 
@@ -416,7 +403,7 @@
 
     @Test
     public void testIsDataStall_EvaluationDnsWithDnsTimeoutCount() {
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredWrappedNetworkMonitor();
+        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
         wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
         makeDnsTimeoutEvent(wrappedMonitor, 3);
         assertFalse(wrappedMonitor.isDataStall());
@@ -430,7 +417,7 @@
 
         // Set the value to larger than the default dns log size.
         setConsecutiveDnsTimeoutThreshold(51);
-        wrappedMonitor = makeMeteredWrappedNetworkMonitor();
+        wrappedMonitor = makeMeteredNetworkMonitor();
         wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
         makeDnsTimeoutEvent(wrappedMonitor, 50);
         assertFalse(wrappedMonitor.isDataStall());
@@ -442,7 +429,7 @@
     @Test
     public void testIsDataStall_EvaluationDnsWithDnsTimeThreshold() {
         // Test dns events happened in valid dns time threshold.
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredWrappedNetworkMonitor();
+        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
         wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
         makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
         assertFalse(wrappedMonitor.isDataStall());
@@ -451,7 +438,7 @@
 
         // Test dns events happened before valid dns time threshold.
         setValidDataStallDnsTimeThreshold(0);
-        wrappedMonitor = makeMeteredWrappedNetworkMonitor();
+        wrappedMonitor = makeMeteredNetworkMonitor();
         wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
         makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
         assertFalse(wrappedMonitor.isDataStall());
@@ -464,24 +451,13 @@
         setSslException(mHttpsConnection);
         setStatus(mHttpConnection, 500);
         setStatus(mFallbackConnection, 404);
-        when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES);
 
-        final NetworkMonitor nm = makeMonitor();
-        nm.notifyNetworkConnected();
-
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(NETWORK_TEST_RESULT_INVALID, null);
+        runFailedNetworkTest();
     }
 
     @Test
     public void testNoInternetCapabilityValidated() throws Exception {
-        when(mCm.getNetworkCapabilities(any())).thenReturn(NO_INTERNET_CAPABILITIES);
-
-        final NetworkMonitor nm = makeMonitor();
-        nm.notifyNetworkConnected();
-
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(NETWORK_TEST_RESULT_VALID, null);
+        runNetworkTest(NO_INTERNET_CAPABILITIES, NETWORK_TEST_RESULT_VALID);
         verify(mNetwork, never()).openConnection(any());
     }
 
@@ -491,7 +467,7 @@
         setPortal302(mHttpConnection);
 
         final NetworkMonitor nm = makeMonitor();
-        nm.notifyNetworkConnected();
+        nm.notifyNetworkConnected(TEST_LINK_PROPERTIES, METERED_CAPABILITIES);
 
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
                 .showProvisioningNotification(any(), any());
@@ -522,7 +498,7 @@
 
     @Test
     public void testDataStall_StallSuspectedAndSendMetrics() throws IOException {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor();
+        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
         wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
         makeDnsTimeoutEvent(wrappedMonitor, 5);
         assertTrue(wrappedMonitor.isDataStall());
@@ -531,7 +507,7 @@
 
     @Test
     public void testDataStall_NoStallSuspectedAndSendMetrics() throws IOException {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor();
+        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
         wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
         makeDnsTimeoutEvent(wrappedMonitor, 3);
         assertFalse(wrappedMonitor.isDataStall());
@@ -540,7 +516,7 @@
 
     @Test
     public void testCollectDataStallMetrics() {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor();
+        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
 
         when(mTelephony.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE);
         when(mTelephony.getNetworkOperator()).thenReturn(TEST_MCCMNC);
@@ -578,14 +554,11 @@
         setSslException(mHttpsConnection);
         setStatus(mHttpConnection, 204);
 
-        final NetworkMonitor nm = makeMonitor();
-        nm.notifyNetworkConnected();
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY, null);
+        final NetworkMonitor nm = runNetworkTest(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY);
 
         nm.setAcceptPartialConnectivity();
         verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(NETWORK_TEST_RESULT_VALID, null);
+                .notifyNetworkTested(eq(NETWORK_TEST_RESULT_VALID), any());
     }
 
     @Test
@@ -593,12 +566,12 @@
         setStatus(mHttpsConnection, 500);
         setStatus(mHttpConnection, 204);
         setStatus(mFallbackConnection, 500);
-        assertPartialConnectivity(makeMonitor().isCaptivePortal());
+        runPartialConnectivityNetworkTest();
 
         setStatus(mHttpsConnection, 500);
         setStatus(mHttpConnection, 500);
         setStatus(mFallbackConnection, 204);
-        assertPartialConnectivity(makeMonitor().isCaptivePortal());
+        runPartialConnectivityNetworkTest();
     }
 
     private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
@@ -660,26 +633,41 @@
                 eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt())).thenReturn(mode);
     }
 
-    private void assertPortal(CaptivePortalProbeResult result) {
-        assertTrue(result.isPortal());
-        assertFalse(result.isFailed());
-        assertFalse(result.isSuccessful());
+    private void runPortalNetworkTest() {
+        runNetworkTest(NETWORK_TEST_RESULT_INVALID);
+        assertNotNull(mNetworkTestedRedirectUrlCaptor.getValue());
     }
 
-    private void assertNotPortal(CaptivePortalProbeResult result) {
-        assertFalse(result.isPortal());
-        assertFalse(result.isFailed());
-        assertTrue(result.isSuccessful());
+    private void runNotPortalNetworkTest() {
+        runNetworkTest(NETWORK_TEST_RESULT_VALID);
+        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
     }
 
-    private void assertFailed(CaptivePortalProbeResult result) {
-        assertFalse(result.isPortal());
-        assertTrue(result.isFailed());
-        assertFalse(result.isSuccessful());
+    private void runFailedNetworkTest() {
+        runNetworkTest(NETWORK_TEST_RESULT_INVALID);
+        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
     }
 
-    private void assertPartialConnectivity(CaptivePortalProbeResult result) {
-        assertTrue(result.isPartialConnectivity());
+    private void runPartialConnectivityNetworkTest() {
+        runNetworkTest(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY);
+        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
+    }
+
+    private NetworkMonitor runNetworkTest(int testResult) {
+        return runNetworkTest(METERED_CAPABILITIES, testResult);
+    }
+
+    private NetworkMonitor runNetworkTest(NetworkCapabilities nc, int testResult) {
+        final NetworkMonitor monitor = makeMonitor();
+        monitor.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc);
+        try {
+            verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
+                    .notifyNetworkTested(eq(testResult), mNetworkTestedRedirectUrlCaptor.capture());
+        } catch (RemoteException e) {
+            fail("Unexpected exception: " + e);
+        }
+
+        return monitor;
     }
 
     private void setSslException(HttpURLConnection connection) throws IOException {
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
index d0e58b8..a00eff7 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.connectivity.ipmemorystore;
 
+import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
@@ -24,12 +26,13 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
 
+import android.app.job.JobScheduler;
 import android.content.Context;
 import android.net.ipmemorystore.Blob;
 import android.net.ipmemorystore.IOnBlobRetrievedListener;
 import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
+import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
 import android.net.ipmemorystore.IOnStatusListener;
 import android.net.ipmemorystore.NetworkAttributes;
 import android.net.ipmemorystore.NetworkAttributesParcelable;
@@ -37,6 +40,7 @@
 import android.net.ipmemorystore.SameL3NetworkResponseParcelable;
 import android.net.ipmemorystore.Status;
 import android.net.ipmemorystore.StatusParcelable;
+import android.os.ConditionVariable;
 import android.os.IBinder;
 import android.os.RemoteException;
 
@@ -69,6 +73,9 @@
     private static final String TEST_CLIENT_ID = "testClientId";
     private static final String TEST_DATA_NAME = "testData";
 
+    private static final int TEST_DATABASE_SIZE_THRESHOLD = 100 * 1024; //100KB
+    private static final int DEFAULT_TIMEOUT_MS = 5000;
+    private static final int LONG_TIMEOUT_MS = 30000;
     private static final int FAKE_KEY_COUNT = 20;
     private static final String[] FAKE_KEYS;
     static {
@@ -80,6 +87,8 @@
 
     @Mock
     private Context mMockContext;
+    @Mock
+    private JobScheduler mMockJobScheduler;
     private File mDbFile;
 
     private IpMemoryStoreService mService;
@@ -91,7 +100,22 @@
         final File dir = context.getFilesDir();
         mDbFile = new File(dir, "test.db");
         doReturn(mDbFile).when(mMockContext).getDatabasePath(anyString());
-        mService = new IpMemoryStoreService(mMockContext);
+        doReturn(mMockJobScheduler).when(mMockContext)
+                .getSystemService(Context.JOB_SCHEDULER_SERVICE);
+        mService = new IpMemoryStoreService(mMockContext) {
+            @Override
+            protected int getDbSizeThreshold() {
+                return TEST_DATABASE_SIZE_THRESHOLD;
+            }
+
+            @Override
+            boolean isDbSizeOverThreshold() {
+                // Add a 100ms delay here for pausing maintenance job a while. Interrupted flag can
+                // be set at this time.
+                waitForMs(100);
+                return super.isDbSizeOverThreshold();
+            }
+        };
     }
 
     @After
@@ -139,9 +163,9 @@
     private interface OnNetworkAttributesRetrievedListener  {
         void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attr);
     }
-    private IOnNetworkAttributesRetrieved onNetworkAttributesRetrieved(
+    private IOnNetworkAttributesRetrievedListener onNetworkAttributesRetrieved(
             final OnNetworkAttributesRetrievedListener functor) {
-        return new IOnNetworkAttributesRetrieved() {
+        return new IOnNetworkAttributesRetrievedListener() {
             @Override
             public void onNetworkAttributesRetrieved(final StatusParcelable status,
                     final String l2Key, final NetworkAttributesParcelable attributes)
@@ -158,17 +182,17 @@
     }
 
     /** Helper method to make an IOnSameNetworkResponseListener */
-    private interface OnSameNetworkResponseListener {
-        void onSameNetworkResponse(Status status, SameL3NetworkResponse answer);
+    private interface OnSameL3NetworkResponseListener {
+        void onSameL3NetworkResponse(Status status, SameL3NetworkResponse answer);
     }
-    private IOnSameNetworkResponseListener onSameResponse(
-            final OnSameNetworkResponseListener functor) {
-        return new IOnSameNetworkResponseListener() {
+    private IOnSameL3NetworkResponseListener onSameResponse(
+            final OnSameL3NetworkResponseListener functor) {
+        return new IOnSameL3NetworkResponseListener() {
             @Override
-            public void onSameNetworkResponse(final StatusParcelable status,
+            public void onSameL3NetworkResponse(final StatusParcelable status,
                     final SameL3NetworkResponseParcelable sameL3Network)
                     throws RemoteException {
-                functor.onSameNetworkResponse(new Status(status),
+                functor.onSameL3NetworkResponse(new Status(status),
                         null == sameL3Network ? null : new SameL3NetworkResponse(sameL3Network));
             }
 
@@ -200,10 +224,15 @@
 
     // Helper method to factorize some boilerplate
     private void doLatched(final String timeoutMessage, final Consumer<CountDownLatch> functor) {
+        doLatched(timeoutMessage, functor, DEFAULT_TIMEOUT_MS);
+    }
+
+    private void doLatched(final String timeoutMessage, final Consumer<CountDownLatch> functor,
+            final int timeout) {
         final CountDownLatch latch = new CountDownLatch(1);
         functor.accept(latch);
         try {
-            if (!latch.await(5000, TimeUnit.MILLISECONDS)) {
+            if (!latch.await(timeout, TimeUnit.MILLISECONDS)) {
                 fail(timeoutMessage);
             }
         } catch (InterruptedException e) {
@@ -224,10 +253,51 @@
                 })));
     }
 
+    /** Insert large data that db size will be over threshold for maintenance test usage. */
+    private void insertFakeDataAndOverThreshold() {
+        try {
+            final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
+            na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
+            na.setGroupHint("hint1");
+            na.setMtu(219);
+            na.setDnsAddresses(Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")));
+            final byte[] data = new byte[]{-3, 6, 8, -9, 12, -128, 0, 89, 112, 91, -34};
+            final long time = System.currentTimeMillis() - 1;
+            for (int i = 0; i < 1000; i++) {
+                int errorCode = IpMemoryStoreDatabase.storeNetworkAttributes(
+                        mService.mDb,
+                        "fakeKey" + i,
+                        // Let first 100 records get expiry.
+                        i < 100 ? time : time + TimeUnit.HOURS.toMillis(i),
+                        na.build());
+                assertEquals(errorCode, Status.SUCCESS);
+
+                errorCode = IpMemoryStoreDatabase.storeBlob(
+                        mService.mDb, "fakeKey" + i, TEST_CLIENT_ID, TEST_DATA_NAME, data);
+                assertEquals(errorCode, Status.SUCCESS);
+            }
+
+            // After added 5000 records, db size is larger than fake threshold(100KB).
+            assertTrue(mService.isDbSizeOverThreshold());
+        } catch (final UnknownHostException e) {
+            fail("Insert fake data fail");
+        }
+    }
+
+    /** Wait for assigned time. */
+    private void waitForMs(long ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (final InterruptedException e) {
+            fail("Thread was interrupted");
+        }
+    }
+
     @Test
     public void testNetworkAttributes() throws UnknownHostException {
         final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
         na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
+        na.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000);
         na.setGroupHint("hint1");
         na.setMtu(219);
         final String l2Key = FAKE_KEYS[0];
@@ -257,6 +327,8 @@
                                     + status.resultCode, status.isSuccess());
                             assertEquals(l2Key, key);
                             assertEquals(attributes.assignedV4Address, attr.assignedV4Address);
+                            assertEquals(attributes.assignedV4AddressExpiry,
+                                    attr.assignedV4AddressExpiry);
                             assertEquals(attributes.groupHint, attr.groupHint);
                             assertEquals(attributes.mtu, attr.mtu);
                             assertEquals(attributes2.dnsAddresses, attr.dnsAddresses);
@@ -278,7 +350,7 @@
         // Verify that this test does not miss any new field added later.
         // If any field is added to NetworkAttributes it must be tested here for storing
         // and retrieving.
-        assertEquals(4, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
+        assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
                 .filter(f -> !Modifier.isStatic(f.getModifiers())).count());
     }
 
@@ -341,7 +413,7 @@
                                     status.isSuccess());
                             assertEquals(l2Key, key);
                             assertEquals(name, TEST_DATA_NAME);
-                            Arrays.equals(b.data, data);
+                            assertTrue(Arrays.equals(b.data, data));
                             latch.countDown();
                         })));
 
@@ -503,4 +575,64 @@
                     latch.countDown();
                 })));
     }
+
+
+    @Test
+    public void testFullMaintenance() {
+        insertFakeDataAndOverThreshold();
+
+        final InterruptMaintenance im = new InterruptMaintenance(0/* Fake JobId */);
+        // Do full maintenance and then db size should go down and meet the threshold.
+        doLatched("Maintenance unexpectedly completed successfully", latch ->
+                mService.fullMaintenance(onStatus((status) -> {
+                    assertTrue("Execute full maintenance failed: "
+                            + status.resultCode, status.isSuccess());
+                    latch.countDown();
+                }), im), LONG_TIMEOUT_MS);
+
+        // Assume that maintenance is successful, db size shall meet the threshold.
+        assertFalse(mService.isDbSizeOverThreshold());
+    }
+
+    @Test
+    public void testInterruptMaintenance() {
+        insertFakeDataAndOverThreshold();
+
+        final InterruptMaintenance im = new InterruptMaintenance(0/* Fake JobId */);
+
+        // Test interruption immediately.
+        im.setInterrupted(true);
+        // Do full maintenance and the expectation is not completed by interruption.
+        doLatched("Maintenance unexpectedly completed successfully", latch ->
+                mService.fullMaintenance(onStatus((status) -> {
+                    assertFalse(status.isSuccess());
+                    latch.countDown();
+                }), im), LONG_TIMEOUT_MS);
+
+        // Assume that no data are removed, db size shall be over the threshold.
+        assertTrue(mService.isDbSizeOverThreshold());
+
+        // Reset the flag and test interruption during maintenance.
+        im.setInterrupted(false);
+
+        final ConditionVariable latch = new ConditionVariable();
+        // Do full maintenance and the expectation is not completed by interruption.
+        mService.fullMaintenance(onStatus((status) -> {
+            assertFalse(status.isSuccess());
+            latch.open();
+        }), im);
+
+        // Give a little bit of time for maintenance to start up for realism
+        waitForMs(50);
+        // Interrupt maintenance job.
+        im.setInterrupted(true);
+
+        if (!latch.block(LONG_TIMEOUT_MS)) {
+            fail("Maintenance unexpectedly completed successfully");
+        }
+
+        // Assume that only do dropAllExpiredRecords method in previous maintenance, db size shall
+        // still be over the threshold.
+        assertTrue(mService.isDbSizeOverThreshold());
+    }
 }
diff --git a/packages/OsuLogin/res/values/strings.xml b/packages/OsuLogin/res/values/strings.xml
index 06fa8c7..14de0f5 100644
--- a/packages/OsuLogin/res/values/strings.xml
+++ b/packages/OsuLogin/res/values/strings.xml
@@ -3,4 +3,6 @@
     <string name="app_name">OsuLogin</string>
     <!-- action bar label [CHAR LIMIT=32] -->
     <string name="action_bar_label">Online Sign Up</string>
+    <!-- toast message [CHAR LIMIT=32] -->
+    <string name="sign_up_failed">Sign-up failed</string>
 </resources>
diff --git a/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java b/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java
index 82e33cc..3a994d7 100644
--- a/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java
+++ b/packages/OsuLogin/src/com/android/hotspot2/osu/OsuLoginActivity.java
@@ -38,6 +38,7 @@
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.ProgressBar;
+import android.widget.Toast;
 
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 
@@ -63,6 +64,7 @@
     private SwipeRefreshLayout mSwipeRefreshLayout;
     private ProgressBar mProgressBar;
     private boolean mForceDisconnect = true;
+    boolean mRedirectResponseReceived = false;
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -141,6 +143,9 @@
                     Log.d(TAG, "Lost for the current Network, close the browser");
                 }
                 mForceDisconnect = false; // It is already disconnected.
+                if (!mRedirectResponseReceived) {
+                    showSignUpFailedToast();
+                }
                 if (mNetwork.equals(network)) {
                     finishAndRemoveTask();
                 }
@@ -229,9 +234,13 @@
         return "";
     }
 
+    private void showSignUpFailedToast() {
+        Toast.makeText(getApplicationContext(), R.string.sign_up_failed,
+                Toast.LENGTH_SHORT).show();
+    }
+
     private class OsuWebViewClient extends WebViewClient {
         boolean mPageError = false;
-        boolean mRedirectResponseReceived = false;
 
         @Override
         public void onPageStarted(WebView view, String urlString, Bitmap favicon) {
diff --git a/packages/NetworkStackPermissionStub/Android.bp b/packages/PackageInstaller/Android.bp
similarity index 63%
copy from packages/NetworkStackPermissionStub/Android.bp
copy to packages/PackageInstaller/Android.bp
index 8cee92e..9420954 100644
--- a/packages/NetworkStackPermissionStub/Android.bp
+++ b/packages/PackageInstaller/Android.bp
@@ -1,5 +1,4 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2018 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,17 +11,18 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-//
 
-// Stub APK to define permissions for NetworkStack
 android_app {
-    name: "NetworkStackPermissionStub",
-    // TODO: mark app as hasCode=false in manifest once soong stops complaining about apps without
-    // a classes.dex.
+    name: "PackageInstaller",
+
     srcs: ["src/**/*.java"],
-    platform_apis: true,
-    min_sdk_version: "28",
-    certificate: "networkstack",
+
+    certificate: "platform",
     privileged: true,
-    manifest: "AndroidManifest.xml",
+    platform_apis: true,
+
+    static_libs: [
+        "xz-java",
+        "androidx.leanback_leanback",
+    ],
 }
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index 62535b6..b0e2700 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -43,14 +43,12 @@
                 <action android:name="android.intent.action.VIEW" />
                 <action android:name="android.intent.action.INSTALL_PACKAGE" />
                 <category android:name="android.intent.category.DEFAULT" />
-                <data android:scheme="file" />
                 <data android:scheme="content" />
                 <data android:mimeType="application/vnd.android.package-archive" />
             </intent-filter>
             <intent-filter android:priority="1">
                 <action android:name="android.intent.action.INSTALL_PACKAGE" />
                 <category android:name="android.intent.category.DEFAULT" />
-                <data android:scheme="file" />
                 <data android:scheme="package" />
                 <data android:scheme="content" />
             </intent-filter>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index 441dbac..bde1b25 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -26,6 +26,7 @@
 import android.app.AppOpsManager;
 import android.app.Dialog;
 import android.app.DialogFragment;
+import android.app.admin.DevicePolicyManager;
 import android.content.ActivityNotFoundException;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -427,7 +428,7 @@
         if (mAllowUnknownSources || !isInstallRequestFromUnknownSource(getIntent())) {
             initiateInstall();
         } else {
-            // Check for unknown sources restriction
+            // Check for unknown sources restrictions.
             final int unknownSourcesRestrictionSource = mUserManager.getUserRestrictionSource(
                     UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, Process.myUserHandle());
             final int unknownSourcesGlobalRestrictionSource = mUserManager.getUserRestrictionSource(
@@ -436,16 +437,28 @@
                     & (unknownSourcesRestrictionSource | unknownSourcesGlobalRestrictionSource);
             if (systemRestriction != 0) {
                 showDialogInner(DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER);
-            } else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET
-                    || unknownSourcesGlobalRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
-                startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS));
-                finish();
+            } else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
+                startAdminSupportDetailsActivity(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
+            } else if (unknownSourcesGlobalRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
+                startAdminSupportDetailsActivity(
+                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY);
             } else {
                 handleUnknownSources();
             }
         }
     }
 
+    private void startAdminSupportDetailsActivity(String restriction) {
+        // If the given restriction is set by an admin, display information about the
+        // admin enforcing the restriction for the affected user.
+        final DevicePolicyManager dpm = getSystemService(DevicePolicyManager.class);
+        final Intent showAdminSupportDetailsIntent = dpm.createAdminSupportIntent(restriction);
+        if (showAdminSupportDetailsIntent != null) {
+            startActivity(showAdminSupportDetailsIntent);
+        }
+        finish();
+    }
+
     private void handleUnknownSources() {
         if (mOriginatingPackage == null) {
             Log.i(TAG, "No source found for package " + mPkgInfo.packageName);
diff --git a/packages/SettingsLib/AdaptiveIcon/Android.bp b/packages/SettingsLib/AdaptiveIcon/Android.bp
new file mode 100644
index 0000000..7f4442d
--- /dev/null
+++ b/packages/SettingsLib/AdaptiveIcon/Android.bp
@@ -0,0 +1,13 @@
+android_library {
+    name: "SettingsLibAdaptiveIcon",
+
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+
+    static_libs: [
+          "androidx.annotation_annotation",
+          "SettingsLibTile"
+    ],
+
+    min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml b/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml
new file mode 100644
index 0000000..256b8f3
--- /dev/null
+++ b/packages/SettingsLib/AdaptiveIcon/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.settingslib.widget">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml b/packages/SettingsLib/AdaptiveIcon/res/values/colors.xml
similarity index 72%
copy from packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
copy to packages/SettingsLib/AdaptiveIcon/res/values/colors.xml
index 66cfaff..76d106a 100644
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
+++ b/packages/SettingsLib/AdaptiveIcon/res/values/colors.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
+<!-- Copyright (C) 2019 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,5 +13,9 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.166666667,0 0.2,1 1,1" />
+
+<resources>
+    <color name="homepage_generic_icon_background">#1A73E8</color>
+
+    <color name="bt_outline_color">#1f000000</color> <!-- icon outline color -->
+</resources>
diff --git a/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml b/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml
new file mode 100644
index 0000000..7f5b58c
--- /dev/null
+++ b/packages/SettingsLib/AdaptiveIcon/res/values/dimens.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <!-- Dashboard foreground image inset (from background edge to foreground edge) -->
+    <dimen name="dashboard_tile_foreground_image_inset">6dp</dimen>
+
+    <!-- Stroke size of adaptive outline -->
+    <dimen name="adaptive_outline_stroke">1dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java
new file mode 100644
index 0000000..fc93650
--- /dev/null
+++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIcon.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.widget;
+
+import static androidx.annotation.VisibleForTesting.NONE;
+
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settingslib.drawer.Tile;
+
+/**
+ * Adaptive icon that can set background color
+ */
+public class AdaptiveIcon extends LayerDrawable {
+
+    private static final String TAG = "AdaptiveHomepageIcon";
+
+    @VisibleForTesting(otherwise = NONE)
+    int mBackgroundColor = -1;
+    private AdaptiveConstantState mAdaptiveConstantState;
+
+    public AdaptiveIcon(Context context, Drawable foreground) {
+        super(new Drawable[]{
+                new AdaptiveIconShapeDrawable(context.getResources()),
+                foreground
+        });
+        final int insetPx = context.getResources()
+                .getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset);
+        setLayerInset(1 /* index */, insetPx, insetPx, insetPx, insetPx);
+        mAdaptiveConstantState = new AdaptiveConstantState(context, foreground);
+    }
+
+    /**
+     *  According {@code tile} metaData to set background color
+     */
+    public void setBackgroundColor(Context context, Tile tile) {
+        final Bundle metaData = tile.getMetaData();
+        try {
+            if (metaData != null) {
+                // Load from bg.argb first
+                int bgColor = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB,
+                        0 /* default */);
+                // Not found, load from bg.hint
+                if (bgColor == 0) {
+                    final int colorRes = metaData.getInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
+                            0 /* default */);
+                    if (colorRes != 0) {
+                        bgColor = context.getPackageManager()
+                                .getResourcesForApplication(tile.getPackageName())
+                                .getColor(colorRes, null /* theme */);
+                    }
+                }
+                // If found anything, use it.
+                if (bgColor != 0) {
+                    setBackgroundColor(bgColor);
+                    return;
+                }
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "Failed to set background color for " + tile.getPackageName());
+        }
+        setBackgroundColor(context.getColor(R.color.homepage_generic_icon_background));
+    }
+
+    /**
+     * Set background color by {@code color}
+     */
+    public void setBackgroundColor(int color) {
+        mBackgroundColor = color;
+        getDrawable(0).setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+        Log.d(TAG, "Setting background color " + mBackgroundColor);
+        mAdaptiveConstantState.mColor = color;
+    }
+
+    @Override
+    public ConstantState getConstantState() {
+        return mAdaptiveConstantState;
+    }
+
+    @VisibleForTesting
+    static class AdaptiveConstantState extends ConstantState {
+        Context mContext;
+        Drawable mDrawable;
+        int mColor;
+
+        AdaptiveConstantState(Context context, Drawable drawable) {
+            this.mContext = context;
+            this.mDrawable = drawable;
+        }
+
+        @Override
+        public Drawable newDrawable() {
+            final AdaptiveIcon
+                    icon = new AdaptiveIcon(mContext, mDrawable);
+            icon.setBackgroundColor(mColor);
+
+            return icon;
+        }
+
+        @Override
+        public int getChangingConfigurations() {
+            return 0;
+        }
+    }
+}
diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIconShapeDrawable.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIconShapeDrawable.java
new file mode 100644
index 0000000..4d7610c
--- /dev/null
+++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveIconShapeDrawable.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.widget;
+
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.graphics.Path;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.PathShape;
+import android.util.AttributeSet;
+import android.util.PathParser;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * Draws a filled {@link ShapeDrawable} using the path from {@link AdaptiveIconDrawable}.
+ */
+public class AdaptiveIconShapeDrawable extends ShapeDrawable {
+    public AdaptiveIconShapeDrawable() {
+        super();
+    }
+
+    public AdaptiveIconShapeDrawable(Resources resources) {
+        super();
+        init(resources);
+    }
+
+    @Override
+    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
+            throws XmlPullParserException, IOException {
+        super.inflate(r, parser, attrs, theme);
+        init(r);
+    }
+
+    private void init(Resources resources) {
+        final float pathSize = AdaptiveIconDrawable.MASK_SIZE;
+        final Path path = new Path(PathParser.createPathFromPathData(
+                resources.getString(com.android.internal.R.string.config_icon_mask)));
+        setShape(new PathShape(path, pathSize, pathSize));
+    }
+}
diff --git a/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java
new file mode 100644
index 0000000..1c65bc2
--- /dev/null
+++ b/packages/SettingsLib/AdaptiveIcon/src/com/android/settingslib/widget/AdaptiveOutlineDrawable.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.widget;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.DrawableWrapper;
+import android.util.PathParser;
+
+import androidx.annotation.VisibleForTesting;
+
+/**
+ * Adaptive outline drawable with white plain background color and black outline
+ */
+public class AdaptiveOutlineDrawable extends DrawableWrapper {
+    @VisibleForTesting
+    final Paint mOutlinePaint;
+    private Path mPath;
+    private final int mInsetPx;
+    private final Bitmap mBitmap;
+
+    public AdaptiveOutlineDrawable(Resources resources, Bitmap bitmap) {
+        super(new AdaptiveIconShapeDrawable(resources));
+
+        getDrawable().setTint(Color.WHITE);
+        mPath = new Path(PathParser.createPathFromPathData(
+                resources.getString(com.android.internal.R.string.config_icon_mask)));
+        mOutlinePaint = new Paint();
+        mOutlinePaint.setColor(resources.getColor(R.color.bt_outline_color, null));
+        mOutlinePaint.setStyle(Paint.Style.STROKE);
+        mOutlinePaint.setStrokeWidth(resources.getDimension(R.dimen.adaptive_outline_stroke));
+        mOutlinePaint.setAntiAlias(true);
+
+        mInsetPx = resources
+                .getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset);
+        mBitmap = bitmap;
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+        final Rect bounds = getBounds();
+        final float pathSize = AdaptiveIconDrawable.MASK_SIZE;
+
+        final float scaleX = (bounds.right - bounds.left) / pathSize;
+        final float scaleY = (bounds.bottom - bounds.top) / pathSize;
+
+        final int count = canvas.save();
+        canvas.scale(scaleX, scaleY);
+        // Draw outline
+        canvas.drawPath(mPath, mOutlinePaint);
+        canvas.restoreToCount(count);
+
+        // Draw the foreground icon
+        canvas.drawBitmap(mBitmap, bounds.left + mInsetPx, bounds.top + mInsetPx, null);
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mBitmap.getHeight() + 2 * mInsetPx;
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mBitmap.getWidth() + 2 * mInsetPx;
+    }
+}
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 730e9e1..b532621 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -22,6 +22,7 @@
         "SettingsLibEntityHeaderWidgets",
         "SettingsLibBarChartPreference",
         "SettingsLibProgressBar",
+        "SettingsLibAdaptiveIcon",
     ],
 
     // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES
diff --git a/packages/SettingsLib/AppPreference/res/layout/preference_app.xml b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
index 711dad4..dbc51958 100644
--- a/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
+++ b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
@@ -88,7 +88,7 @@
         android:id="@android:id/widget_frame"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:gravity="center"
+        android:gravity="center_vertical|end"
         android:minWidth="64dp"
         android:orientation="vertical"/>
 
diff --git a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml
index 814246f..0a336bf 100644
--- a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml
+++ b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_chart.xml
@@ -20,17 +20,11 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_marginStart="16dp"
-    android:layout_marginEnd="16dp"
-    android:gravity="center"
-    android:orientation="vertical">
+    style="@style/SettingsBarChart">
 
     <TextView
         android:id="@+id/bar_chart_title"
-        android:layout_width="wrap_content"
-        android:layout_height="48dp"
-        android:gravity="center"
-        android:textAppearance="@style/BarChart.Text.HeaderTitle"/>
+        style="@style/SettingsBarChartTitle"/>
 
     <LinearLayout
         android:id="@+id/bar_views_container"
@@ -42,40 +36,34 @@
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:layout_marginBottom="20dp"
             android:gravity="center|bottom">
 
             <com.android.settingslib.widget.BarView
                 android:id="@+id/bar_view1"
-                style="@style/BarViewStyle"
-                settings:barColor="#FA7B17"/>
+                style="@style/SettingsBarViewStyle"
+                settings:barColor="@color/settings_bar_view_1_color"/>
             <com.android.settingslib.widget.BarView
                 android:id="@+id/bar_view2"
-                style="@style/BarViewStyle"
-                settings:barColor="#F439A0"/>
+                style="@style/SettingsBarViewStyle"
+                settings:barColor="@color/settings_bar_view_2_color"/>
             <com.android.settingslib.widget.BarView
                 android:id="@+id/bar_view3"
-                style="@style/BarViewStyle"
-                settings:barColor="#A142F4"/>
+                style="@style/SettingsBarViewStyle"
+                settings:barColor="@color/settings_bar_view_3_color"/>
             <com.android.settingslib.widget.BarView
                 android:id="@+id/bar_view4"
-                style="@style/BarViewStyle"
-                settings:barColor="#24C1E0"/>
+                style="@style/SettingsBarViewStyle"
+                settings:barColor="@color/settings_bar_view_4_color"/>
         </LinearLayout>
 
         <Button
             android:id="@+id/bar_chart_details"
-            style="@android:style/Widget.DeviceDefault.Button.Borderless.Colored"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:gravity="center"/>
+            style="@style/SettingsBarChartDetailsButton"/>
     </LinearLayout>
 
     <TextView
         android:id="@+id/empty_view"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/settings_bar_view_max_height"
-        android:gravity="center"
-        android:visibility="gone"
-        android:textAppearance="@style/BarChart.Text.Summary"/>
+        style="@style/SettingsBarChartEmptyText"/>
 
 </LinearLayout>
diff --git a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml
index 4bc68b3..e5d8284 100644
--- a/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml
+++ b/packages/SettingsLib/BarChartPreference/res/layout/settings_bar_view.xml
@@ -24,34 +24,19 @@
 
     <View
         android:id="@+id/bar_view"
-        android:layout_width="8dp"
-        android:layout_height="wrap_content"/>
+        android:layout_height="wrap_content"
+        style="@style/SettingsBarChartBar"/>
 
     <ImageView
         android:id="@+id/icon_view"
-        android:layout_width="@dimen/settings_bar_view_icon_size"
-        android:layout_height="@dimen/settings_bar_view_icon_size"
-        android:scaleType="fitCenter"
-        android:layout_marginTop="12dp"
-        android:layout_marginBottom="12dp"/>
+        style="@style/SettingsBarChartBarIcon"/>
 
     <TextView
         android:id="@+id/bar_title"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="10dp"
-        android:layout_marginBottom="2dp"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="@style/BarChart.Text.Title"/>
+        style="@style/SettingsBarChartBarTitle"/>
 
     <TextView
         android:id="@+id/bar_summary"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="12dp"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="@style/BarChart.Text.Summary"/>
+        style="@style/SettingsBarChartBarSummary"/>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/BarChartPreference/res/values/colors.xml b/packages/SettingsLib/BarChartPreference/res/values/colors.xml
new file mode 100644
index 0000000..f10fb12
--- /dev/null
+++ b/packages/SettingsLib/BarChartPreference/res/values/colors.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <color name="settings_bar_view_1_color">#A142F4</color>
+    <color name="settings_bar_view_2_color">#24C1E0</color>
+    <color name="settings_bar_view_3_color">#4285F4</color>
+    <color name="settings_bar_view_4_color">#009688</color>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/BarChartPreference/res/values/dimens.xml b/packages/SettingsLib/BarChartPreference/res/values/dimens.xml
index 7148afa..5f741a0 100644
--- a/packages/SettingsLib/BarChartPreference/res/values/dimens.xml
+++ b/packages/SettingsLib/BarChartPreference/res/values/dimens.xml
@@ -16,6 +16,6 @@
   -->
 
 <resources>
-    <dimen name="settings_bar_view_max_height">106dp</dimen>
+    <dimen name="settings_bar_view_max_height">72dp</dimen>
     <dimen name="settings_bar_view_icon_size">24dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/BarChartPreference/res/values/styles.xml b/packages/SettingsLib/BarChartPreference/res/values/styles.xml
index 5587928..7a3fb7d 100644
--- a/packages/SettingsLib/BarChartPreference/res/values/styles.xml
+++ b/packages/SettingsLib/BarChartPreference/res/values/styles.xml
@@ -16,14 +16,74 @@
   -->
 
 <resources>
-    <style name="BarViewStyle">
+
+    <style name="SettingsBarChart">
+        <item name="android:layout_marginStart">10dp</item>
+        <item name="android:layout_marginEnd">10dp</item>
+        <item name="android:gravity">center</item>
+        <item name="android:orientation">vertical</item>
+    </style>
+
+    <style name="SettingsBarChartTitle">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">48dp</item>
+        <item name="android:gravity">center</item>
+        <item name="android:textAppearance">@style/BarChart.Text.HeaderTitle</item>
+    </style>
+
+    <style name="SettingsBarChartDetailsButton"
+           parent="@android:style/Widget.DeviceDefault.Button.Borderless.Colored">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
+    </style>
+
+    <style name="SettingsBarViewStyle">
         <item name="android:layout_width">0dp</item>
-        <item name="android:layout_height">250dp</item>
+        <item name="android:layout_height">168dp</item>
         <item name="android:layout_weight">1</item>
         <item name="android:layout_marginStart">8dp</item>
         <item name="android:layout_marginEnd">8dp</item>
     </style>
 
+    <style name="SettingsBarChartEmptyText">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">@dimen/settings_bar_view_max_height</item>
+        <item name="android:gravity">center</item>
+        <item name="android:visibility">gone</item>
+        <item name="android:textAppearance">@style/BarChart.Text.Summary</item>
+    </style>
+
+    <style name="SettingsBarChartBar">
+        <item name="android:layout_width">8dp</item>
+    </style>
+
+    <style name="SettingsBarChartBarIcon">
+        <item name="android:layout_width">@dimen/settings_bar_view_icon_size</item>
+        <item name="android:layout_height">@dimen/settings_bar_view_icon_size</item>
+        <item name="android:scaleType">fitCenter</item>
+        <item name="android:layout_marginTop">12dp</item>
+        <item name="android:tint">?android:attr/textColorPrimary</item>
+    </style>
+
+    <style name="SettingsBarChartBarTitle">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">12dp</item>
+        <item name="android:singleLine">true</item>
+        <item name="android:ellipsize">marquee</item>
+        <item name="android:textAppearance">@style/BarChart.Text.Title</item>
+    </style>
+
+    <style name="SettingsBarChartBarSummary">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">4dp</item>
+        <item name="android:singleLine">true</item>
+        <item name="android:ellipsize">marquee</item>
+        <item name="android:textAppearance">@style/BarChart.Text.Summary</item>
+    </style>
+
     <style name="BarChart.Text"
            parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
@@ -35,12 +95,12 @@
     </style>
 
     <style name="BarChart.Text.Title">
-        <item name="android:textSize">22sp</item>
+        <item name="android:textSize">14sp</item>
     </style>
 
     <style name="BarChart.Text.Summary"
-           parent="@android:style/TextAppearance.Material.Body1">
+           parent="@*android:style/TextAppearance.DeviceDefault.Body1">
         <item name="android:textColor">?android:attr/textColorSecondary</item>
-        <item name="android:textSize">14sp</item>
+        <item name="android:textSize">12sp</item>
     </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java
index 03dfd3e..fccb719 100644
--- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java
+++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java
@@ -71,8 +71,7 @@
         //Set height of bar view
         mBarView.getLayoutParams().height = barViewInfo.getNormalizedHeight();
         mIcon.setImageDrawable(barViewInfo.getIcon());
-        // For now, we use the bar number as title.
-        mBarTitle.setText(Integer.toString(barViewInfo.getHeight()));
+        mBarTitle.setText(barViewInfo.getTitle());
         mBarSummary.setText(barViewInfo.getSummary());
         mIcon.setContentDescription(barViewInfo.getContentDescription());
     }
diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java
index 1ef36a2..922337a 100644
--- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java
+++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java
@@ -21,7 +21,6 @@
 
 import androidx.annotation.IntRange;
 import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
 
 import java.util.Comparator;
 
@@ -32,8 +31,8 @@
 
     private final Drawable mIcon;
     private View.OnClickListener mClickListener;
-    @StringRes
-    private int mSummary;
+    private CharSequence mTitle;
+    private CharSequence mSummary;
     private @Nullable CharSequence mContentDescription;
     // A number indicates this bar's height. The larger number shows a higher bar view.
     private int mHeight;
@@ -45,13 +44,16 @@
      *
      * @param icon      The icon of bar view.
      * @param barHeight The height of bar view. Larger number shows a higher bar view.
-     * @param summary   The string resource id for summary.
+     * @param title     The string for title.  If this is null, use the height of the bar.
+     * @param summary   The string for summary.
      * @param contentDescription Optional text that briefly describes the contents of the icon.
      */
-    public BarViewInfo(Drawable icon, @IntRange(from = 0) int barHeight, @StringRes int summary,
+    public BarViewInfo(Drawable icon, @IntRange(from = 0) int barHeight,
+            @Nullable CharSequence title, CharSequence summary,
             @Nullable CharSequence contentDescription) {
         mIcon = icon;
         mHeight = barHeight;
+        mTitle = title;
         mSummary = summary;
         mContentDescription = contentDescription;
     }
@@ -74,8 +76,12 @@
         mHeight = height;
     }
 
-    void setSummary(@StringRes int resId) {
-        mSummary = resId;
+    void setTitle(CharSequence title) {
+        mTitle = title;
+    }
+
+    void setSummary(CharSequence summary) {
+        mSummary = summary;
     }
 
     Drawable getIcon() {
@@ -90,8 +96,12 @@
         return mClickListener;
     }
 
-    @StringRes
-    int getSummary() {
+    @Nullable
+    CharSequence getTitle() {
+        return mTitle;
+    }
+
+    CharSequence getSummary() {
         return mSummary;
     }
 
diff --git a/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_entities_header.xml b/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_entities_header.xml
index 716fc8d..71bbd5b 100644
--- a/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_entities_header.xml
+++ b/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_entities_header.xml
@@ -20,8 +20,8 @@
     android:id="@+id/app_entities_header"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingStart="24dp"
-    android:paddingEnd="8dp"
+    android:paddingStart="16dp"
+    android:paddingEnd="16dp"
     android:gravity="center"
     android:orientation="vertical">
 
diff --git a/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_view.xml b/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_view.xml
index 013d2d0..0db6dfb 100644
--- a/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_view.xml
+++ b/packages/SettingsLib/EntityHeaderWidgets/res/layout/app_view.xml
@@ -20,7 +20,8 @@
     android:layout_width="0dp"
     android:layout_height="wrap_content"
     android:layout_weight="1"
-    android:layout_marginEnd="16dp"
+    android:layout_marginStart="8dp"
+    android:layout_marginEnd="8dp"
     android:gravity="center"
     android:clickable="true"
     android:background="@*android:drawable/btn_borderless_material"
diff --git a/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml b/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml
index da575db..3f0a06c 100644
--- a/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml
+++ b/packages/SettingsLib/LayoutPreference/res/layout/settings_entity_header.xml
@@ -46,6 +46,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:singleLine="false"
+            android:gravity="center"
             android:ellipsize="marquee"
             android:textDirection="locale"
             android:layout_marginTop="8dp"/>
diff --git a/packages/SettingsLib/Tile/Android.bp b/packages/SettingsLib/Tile/Android.bp
new file mode 100644
index 0000000..bf16ef3
--- /dev/null
+++ b/packages/SettingsLib/Tile/Android.bp
@@ -0,0 +1,11 @@
+android_library {
+    name: "SettingsLibTile",
+
+    srcs: ["src/**/*.java"],
+
+    static_libs: [
+          "androidx.annotation_annotation",
+    ],
+
+    min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/Tile/AndroidManifest.xml b/packages/SettingsLib/Tile/AndroidManifest.xml
new file mode 100644
index 0000000..b13532e
--- /dev/null
+++ b/packages/SettingsLib/Tile/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.settingslib.drawer">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/DashboardCategory.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DashboardCategory.java
similarity index 93%
rename from packages/SettingsLib/src/com/android/settingslib/drawer/DashboardCategory.java
rename to packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DashboardCategory.java
index a3dda65..7b062b1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/DashboardCategory.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/DashboardCategory.java
@@ -1,11 +1,11 @@
-/**
- * Copyright (C) 2015 The Android Open Source Project
+/*
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package com.android.settingslib.drawer;
 
 import static java.lang.String.CASE_INSENSITIVE_ORDER;
@@ -26,6 +25,9 @@
 import java.util.Collections;
 import java.util.List;
 
+/**
+ * The category for handle {@link Tile}
+ */
 public class DashboardCategory implements Parcelable {
 
     /**
@@ -67,18 +69,30 @@
         return result;
     }
 
+    /**
+     * Add tile
+     */
     public synchronized void addTile(Tile tile) {
         mTiles.add(tile);
     }
 
+    /**
+     * Remove tile
+     */
     public synchronized void removeTile(int n) {
         mTiles.remove(n);
     }
 
+    /**
+     * Get size of tile
+     */
     public int getTilesCount() {
         return mTiles.size();
     }
 
+    /**
+     * Get tile
+     */
     public Tile getTile(int n) {
         return mTiles.get(n);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
similarity index 91%
rename from packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
rename to packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
index d28b00a..0ffd471 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
@@ -1,11 +1,11 @@
-/**
- * Copyright (C) 2015 The Android Open Source Project
+/*
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -33,6 +33,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -84,8 +85,8 @@
         mActivityPackage = in.readString();
         mActivityName = in.readString();
         mIntent = new Intent().setClassName(mActivityPackage, mActivityName);
-        final int N = in.readInt();
-        for (int i = 0; i < N; i++) {
+        final int number = in.readInt();
+        for (int i = 0; i < number; i++) {
             userHandle.add(UserHandle.CREATOR.createFromParcel(in));
         }
         mCategory = in.readString();
@@ -101,9 +102,9 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeString(mActivityPackage);
         dest.writeString(mActivityName);
-        final int N = userHandle.size();
-        dest.writeInt(N);
-        for (int i = 0; i < N; i++) {
+        final int size = userHandle.size();
+        dest.writeInt(size);
+        for (int i = 0; i < size; i++) {
             userHandle.get(i).writeToParcel(dest, flags);
         }
         dest.writeString(mCategory);
@@ -151,6 +152,9 @@
         }
     }
 
+    /**
+     * Check whether title has order.
+     */
     public boolean hasOrder() {
         return mMetaData.containsKey(META_DATA_KEY_ORDER)
                 && mMetaData.get(META_DATA_KEY_ORDER) instanceof Integer;
@@ -262,6 +266,9 @@
         }
     }
 
+    /**
+     * Check whether title has key.
+     */
     public boolean hasKey() {
         return mMetaData != null && mMetaData.containsKey(META_DATA_PREFERENCE_KEYHINT);
     }
@@ -293,7 +300,15 @@
             }
         }
         if (iconResId != 0) {
-            return Icon.createWithResource(activityInfo.packageName, iconResId);
+            final Icon icon = Icon.createWithResource(activityInfo.packageName, iconResId);
+            if (isIconTintable(context)) {
+                final TypedArray a = context.obtainStyledAttributes(new int[] {
+                        android.R.attr.colorControlNormal});
+                final int tintColor = a.getColor(0, 0);
+                a.recycle();
+                icon.setTint(tintColor);
+            }
+            return icon;
         } else {
             return null;
         }
@@ -303,16 +318,12 @@
      * Whether the icon can be tinted. This is true when icon needs to be monochrome (single-color)
      */
     public boolean isIconTintable(Context context) {
+        ensureMetadataNotStale(context);
         if (mMetaData != null
                 && mMetaData.containsKey(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE)) {
             return mMetaData.getBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE);
         }
-        ensureMetadataNotStale(context);
-        final String pkgName = context.getPackageName();
-        // If this drawable is coming from outside Settings, tint it to match the color.
-        final ActivityInfo activityInfo = getActivityInfo(context);
-        return activityInfo != null
-                && !TextUtils.equals(pkgName, activityInfo.packageName);
+        return false;
     }
 
     /**
@@ -361,9 +372,12 @@
         }
     };
 
+    /**
+     * Check whether title is only have primary profile
+     */
     public boolean isPrimaryProfileOnly() {
-        String profile = mMetaData != null ?
-                mMetaData.getString(META_DATA_KEY_PROFILE) : PROFILE_ALL;
+        String profile = mMetaData != null
+                ? mMetaData.getString(META_DATA_KEY_PROFILE) : PROFILE_ALL;
         profile = (profile != null ? profile : PROFILE_ALL);
         return TextUtils.equals(profile, PROFILE_PRIMARY);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
similarity index 98%
rename from packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
rename to packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index 91892ab..31925ab 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 package com.android.settingslib.drawer;
 
@@ -39,6 +39,10 @@
 import java.util.List;
 import java.util.Map;
 
+/**
+ * Utils is a helper class that contains profile key, meta data, settings action
+ * and static methods for get icon or text from uri.
+ */
 public class TileUtils {
 
     private static final boolean DEBUG_TIMING = false;
diff --git a/packages/SettingsLib/res/drawable/ic_media_device.xml b/packages/SettingsLib/res/drawable/ic_media_device.xml
new file mode 100644
index 0000000..5a6aeb4
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_media_device.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2019 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:width="24dp"
+        android:height="24dp"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#00000000"
+        android:fillAlpha=".1"
+        android:pathData="M0 0h24v24H0z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0 0h24v24H0z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M21 3H3c-1.1 0-2 0.9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2 -0.9 2-2V5c0-1.1 -0.9-2-2-2zM1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0-4v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index ed3c11c..39c55fd 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -603,4 +603,26 @@
         <item>3</item><item>3</item>
     </array>
 
+    <!-- Bluetooth icon foreground colors -->
+    <integer-array name="bt_icon_fg_colors">
+        <item>@color/bt_color_icon_1</item>
+        <item>@color/bt_color_icon_2</item>
+        <item>@color/bt_color_icon_3</item>
+        <item>@color/bt_color_icon_4</item>
+        <item>@color/bt_color_icon_5</item>
+        <item>@color/bt_color_icon_6</item>
+        <item>@color/bt_color_icon_7</item>
+    </integer-array>
+
+    <!-- Bluetooth icon background colors -->
+    <integer-array name="bt_icon_bg_colors">
+        <item>@color/bt_color_bg_1</item>
+        <item>@color/bt_color_bg_2</item>
+        <item>@color/bt_color_bg_3</item>
+        <item>@color/bt_color_bg_4</item>
+        <item>@color/bt_color_bg_5</item>
+        <item>@color/bt_color_bg_6</item>
+        <item>@color/bt_color_bg_7</item>
+    </integer-array>
+
 </resources>
diff --git a/packages/SettingsLib/res/values/colors.xml b/packages/SettingsLib/res/values/colors.xml
index 66bbb3a..209b2cb 100644
--- a/packages/SettingsLib/res/values/colors.xml
+++ b/packages/SettingsLib/res/values/colors.xml
@@ -19,4 +19,20 @@
 
     <color name="usage_graph_dots">@*android:color/tertiary_device_default_settings</color>
     <color name="list_divider_color">#64000000</color>
+
+    <color name="bt_color_icon_1">#b4a50e0e</color> <!-- 72% Material Red 900 -->
+    <color name="bt_color_icon_2">#b40d652d</color> <!-- 72% Material Green 900 -->
+    <color name="bt_color_icon_3">#b4e37400</color> <!-- 72% Material Yellow 900 -->
+    <color name="bt_color_icon_4">#b4b06000</color> <!-- 72% Material Orange 900 -->
+    <color name="bt_color_icon_5">#b49c166b</color> <!-- 72% Material Pink 900 -->
+    <color name="bt_color_icon_6">#b4681da8</color> <!-- 72% Material Purple 900 -->
+    <color name="bt_color_icon_7">#b4007b83</color> <!-- 72% Material Cyan 900 -->
+
+    <color name="bt_color_bg_1">#fad2cf</color> <!-- Material Red 100 -->
+    <color name="bt_color_bg_2">#ceead6</color> <!-- Material Green 100 -->
+    <color name="bt_color_bg_3">#feefc3</color> <!-- Material Yellow 100 -->
+    <color name="bt_color_bg_4">#fedfc8</color> <!-- Material Orange 100 -->
+    <color name="bt_color_bg_5">#fdcfe8</color> <!-- Material Pink 100 -->
+    <color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 -->
+    <color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 -->
 </resources>
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index a9c5061..2cb9d4b 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -91,6 +91,7 @@
     <!-- How far to inset the rounded edges -->
     <dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
 
-
+    <!-- Size of nearby icon -->
+    <dimen name="bt_nearby_icon_size">24dp</dimen>
 
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index bb8c8a6..46e9129 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -1,18 +1,30 @@
 package com.android.settingslib.bluetooth;
 
 import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.util.Log;
 import android.util.Pair;
 
 import androidx.annotation.DrawableRes;
 
 import com.android.settingslib.R;
+import com.android.settingslib.widget.AdaptiveIcon;
+import com.android.settingslib.widget.AdaptiveOutlineDrawable;
 
+import java.io.IOException;
 import java.util.List;
 
 public class BluetoothUtils {
+    private static final String TAG = "BluetoothUtils";
+
     public static final boolean V = false; // verbose logging
     public static final boolean D = true;  // regular logging
 
@@ -112,4 +124,74 @@
     public static Drawable getBluetoothDrawable(Context context, @DrawableRes int resId) {
         return context.getDrawable(resId);
     }
+
+    /**
+     * Get colorful bluetooth icon with description
+     */
+    public static Pair<Drawable, String> getBtRainbowDrawableWithDescription(Context context,
+            CachedBluetoothDevice cachedDevice) {
+        final Pair<Drawable, String> pair = BluetoothUtils.getBtClassDrawableWithDescription(
+                context, cachedDevice);
+        final BluetoothDevice bluetoothDevice = cachedDevice.getDevice();
+        final boolean untetheredHeadset = bluetoothDevice != null
+                ? Boolean.parseBoolean(bluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET))
+                : false;
+        final int iconSize = context.getResources().getDimensionPixelSize(
+                R.dimen.bt_nearby_icon_size);
+        final Resources resources = context.getResources();
+
+        // Deal with untethered headset
+        if (untetheredHeadset) {
+            final String uriString = bluetoothDevice != null
+                    ? bluetoothDevice.getMetadata(BluetoothDevice.METADATA_MAIN_ICON)
+                    : null;
+            final Uri iconUri = uriString != null ? Uri.parse(uriString) : null;
+            if (iconUri != null) {
+                try {
+                    context.getContentResolver().takePersistableUriPermission(iconUri,
+                            Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                } catch (SecurityException e) {
+                    Log.e(TAG, "Failed to take persistable permission for: " + iconUri);
+                }
+                try {
+                    final Bitmap bitmap = MediaStore.Images.Media.getBitmap(
+                            context.getContentResolver(), iconUri);
+                    if (bitmap != null) {
+                        final Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, iconSize,
+                                iconSize, false);
+                        bitmap.recycle();
+                        final AdaptiveOutlineDrawable drawable = new AdaptiveOutlineDrawable(
+                                resources, resizedBitmap);
+                        return new Pair<>(drawable, pair.second);
+                    }
+                } catch (IOException e) {
+                    Log.e(TAG, "Failed to get drawable for: " + iconUri, e);
+                }
+            }
+        }
+
+        return new Pair<>(buildBtRainbowDrawable(context,
+                pair.first, cachedDevice.getAddress().hashCode()), pair.second);
+    }
+
+    /**
+     * Build Bluetooth device icon with rainbow
+     */
+    public static Drawable buildBtRainbowDrawable(Context context, Drawable drawable,
+            int hashCode) {
+        final Resources resources = context.getResources();
+
+        // Deal with normal headset
+        final int[] iconFgColors = resources.getIntArray(R.array.bt_icon_fg_colors);
+        final int[] iconBgColors = resources.getIntArray(R.array.bt_icon_bg_colors);
+
+        // get color index based on mac address
+        final int index = Math.abs(hashCode % iconBgColors.length);
+        drawable.setTint(iconFgColors[index]);
+        final Drawable adaptiveIcon = new AdaptiveIcon(context, drawable);
+        ((AdaptiveIcon) adaptiveIcon).setBackgroundColor(iconBgColors[index]);
+
+        return adaptiveIcon;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index b025df4..530c73a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -31,7 +31,9 @@
  * Utilities related to battery saver.
  */
 public class BatterySaverUtils {
+
     private static final String TAG = "BatterySaverUtils";
+    public static final String EXTRA_CONFIRM_ONLY = "extra_confirm_only";
 
     private BatterySaverUtils() {
     }
@@ -96,7 +98,7 @@
         }
         final ContentResolver cr = context.getContentResolver();
 
-        if (enable && needFirstTimeWarning && maybeShowBatterySaverConfirmation(context)) {
+        if (enable && needFirstTimeWarning && maybeShowBatterySaverConfirmation(context, false)) {
             return false;
         }
         if (enable && !needFirstTimeWarning) {
@@ -116,7 +118,7 @@
                         && Global.getInt(cr, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) == 0
                         && Secure.getInt(cr,
                         Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 0) == 0) {
-                    showAutoBatterySaverSuggestion(context);
+                    showAutoBatterySaverSuggestion(context, false);
                 }
             }
 
@@ -125,23 +127,36 @@
         return false;
     }
 
-    private static boolean maybeShowBatterySaverConfirmation(Context context) {
+    /**
+     * Shows the battery saver confirmation warning if it hasn't been acknowledged by the user in
+     * the past before. When confirmOnly is true, the dialog will have generic info about battery
+     * saver but will only update that the user has been shown the notification and take no
+     * further action. if confirmOnly is false it will show a more specific version of the dialog
+     * that toggles battery saver when acknowledged
+     * @param context A valid context
+     * @param confirmOnly Whether to show the actionless generic dialog (true) or the specific one
+     * that toggles battery saver (false)
+     * @return True if it showed the notification because it has not been previously acknowledged.
+     */
+    public static boolean maybeShowBatterySaverConfirmation(Context context, boolean confirmOnly) {
         if (Secure.getInt(context.getContentResolver(),
                 Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0) {
             return false; // Already shown.
         }
-        context.sendBroadcast(getSystemUiBroadcast(ACTION_SHOW_START_SAVER_CONFIRMATION));
+        context.sendBroadcast(
+                getSystemUiBroadcast(ACTION_SHOW_START_SAVER_CONFIRMATION, confirmOnly));
         return true;
     }
 
-    private static void showAutoBatterySaverSuggestion(Context context) {
-        context.sendBroadcast(getSystemUiBroadcast(ACTION_SHOW_AUTO_SAVER_SUGGESTION));
+    private static void showAutoBatterySaverSuggestion(Context context, boolean confirmOnly) {
+        context.sendBroadcast(getSystemUiBroadcast(ACTION_SHOW_AUTO_SAVER_SUGGESTION, confirmOnly));
     }
 
-    private static Intent getSystemUiBroadcast(String action) {
+    private static Intent getSystemUiBroadcast(String action, boolean confirmOnly) {
         final Intent i = new Intent(action);
         i.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         i.setPackage(SYSUI_PACKAGE);
+        i.putExtra(EXTRA_CONFIRM_ONLY, confirmOnly);
         return i;
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
index 9feacac..eeb6cb0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
@@ -75,20 +75,32 @@
             return true;
         }
 
+        if (isDefaultActiveApp(pkg)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Check if it is default active app in multiple area(i.e. SMS, Dialer, Device admin..)
+     */
+    public boolean isDefaultActiveApp(String pkg) {
         // Additionally, check if pkg is default dialer/sms. They are considered essential apps and
         // should be automatically whitelisted (otherwise user may be able to set restriction on
         // them, leading to bad device behavior.)
-        if (!mAppContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
-            return false;
-        }
+
+        final boolean hasTelephony = mAppContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_TELEPHONY);
         final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(mAppContext,
                 true /* updateIfNeeded */);
-        if (defaultSms != null && TextUtils.equals(pkg, defaultSms.getPackageName())) {
+        if (hasTelephony && defaultSms != null && TextUtils.equals(pkg,
+                defaultSms.getPackageName())) {
             return true;
         }
 
         final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(mAppContext);
-        if (TextUtils.equals(pkg, defaultDialer)) {
+        if (hasTelephony && TextUtils.equals(pkg, defaultDialer)) {
             return true;
         }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
index 1bb6c44..239b1d4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
@@ -130,11 +130,12 @@
     }
 
     private val errorPaint = Paint(Paint.ANTI_ALIAS_FLAG).also { p ->
-        p.color = Utils.getColorErrorDefaultColor(context)
+        p.color = Utils.getColorStateListDefaultColor(context, R.color.batterymeter_plus_color)
         p.alpha = 255
         p.isDither = true
         p.strokeWidth = 0f
         p.style = Paint.Style.FILL_AND_STROKE
+        p.blendMode = BlendMode.SRC
     }
 
     // Only used if dualTone is set to true
@@ -201,10 +202,6 @@
             if (!invertFillIcon) {
                 c.drawPath(scaledBolt, fillPaint)
             }
-        } else if (powerSaveEnabled) {
-            // Clip out the plus shape
-            unifiedPath.op(scaledPlus, Path.Op.DIFFERENCE)
-            c.drawPath(scaledPlus, errorPaint)
         }
 
         if (dualTone) {
@@ -243,10 +240,8 @@
         } else if (powerSaveEnabled) {
             // If power save is enabled draw the perimeter path with colorError
             c.drawPath(scaledPerimeter, errorPaint)
-
-            // But always put path protection around the plus sign
-            c.clipOutPath(scaledPlus)
-            c.drawPath(scaledPlus, fillColorStrokeProtection)
+            // And draw the plus sign on top of the fill
+            c.drawPath(scaledPlus, errorPaint)
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
index 3092b99..2711e31 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
@@ -18,8 +18,11 @@
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.util.Log;
+import android.util.Pair;
 
+import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 
 /**
@@ -48,9 +51,10 @@
     }
 
     @Override
-    public int getIcon() {
-        //TODO(b/117129183): This is not final icon for bluetooth device, just for demo.
-        return com.android.internal.R.drawable.ic_bt_headphones_a2dp;
+    public Drawable getIcon() {
+        final Pair<Drawable, String> pair = BluetoothUtils
+                .getBtRainbowDrawableWithDescription(mContext, mCachedDevice);
+        return pair.first;
     }
 
     @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
index 95f3d3d..732e8db 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
@@ -16,10 +16,14 @@
 package com.android.settingslib.media;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.widget.Toast;
 
 import androidx.mediarouter.media.MediaRouter;
 
+import com.android.settingslib.R;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+
 /**
  * InfoMediaDevice extends MediaDevice to represents wifi device.
  */
@@ -46,9 +50,10 @@
     }
 
     @Override
-    public int getIcon() {
-        //TODO(b/121083246): This is not final icon for cast device, just for demo.
-        return com.android.internal.R.drawable.ic_settings_print;
+    public Drawable getIcon() {
+        //TODO(b/120669861): Return remote device icon uri once api is ready.
+        return BluetoothUtils.buildBtRainbowDrawable(mContext,
+                mContext.getDrawable(R.drawable.ic_media_device), getId().hashCode());
     }
 
     @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 9b9e803..53a8520 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -16,6 +16,7 @@
 package com.android.settingslib.media;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 
 import androidx.annotation.IntDef;
@@ -70,11 +71,11 @@
     public abstract String getSummary();
 
     /**
-     * Get resource id of MediaDevice.
+     * Get icon of MediaDevice.
      *
-     * @return resource id of MediaDevice.
+     * @return drawable of icon.
      */
-    public abstract int getIcon();
+    public abstract Drawable getIcon();
 
     /**
      * Get unique ID that represent MediaDevice
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index 8c3fcc0..af91c34 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -16,10 +16,12 @@
 package com.android.settingslib.media;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.util.Log;
 
 import com.android.settingslib.R;
 import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.HearingAidProfile;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
@@ -56,8 +58,9 @@
     }
 
     @Override
-    public int getIcon() {
-        return R.drawable.ic_smartphone;
+    public Drawable getIcon() {
+        return BluetoothUtils.buildBtRainbowDrawable(mContext,
+                mContext.getDrawable(R.drawable.ic_smartphone), getId().hashCode());
     }
 
     @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
index b9197fe..66ee802 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
@@ -210,7 +210,6 @@
     private void setupUi(ConditionTag tag, View row) {
         if (tag.lines == null) {
             tag.lines = row.findViewById(android.R.id.content);
-            tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
         }
 
         if (tag.line1 == null) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 3acbcd3..8a88a4c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -53,6 +53,7 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.Pair;
 
 import androidx.annotation.NonNull;
 
@@ -65,8 +66,10 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -197,6 +200,9 @@
 
     private final Context mContext;
 
+    private WifiManager mWifiManager;
+    private WifiManager.ActionListener mConnectListener;
+
     private String ssid;
     private String bssid;
     private int security;
@@ -1068,8 +1074,10 @@
     /**
      * Starts the OSU Provisioning flow.
      */
-    public void startOsuProvisioning() {
-        mContext.getSystemService(WifiManager.class).startSubscriptionProvisioning(
+    public void startOsuProvisioning(@Nullable WifiManager.ActionListener connectListener) {
+        mConnectListener = connectListener;
+
+        getWifiManager().startSubscriptionProvisioning(
                 mOsuProvider,
                 mContext.getMainExecutor(),
                 new AccessPointProvisioningCallback()
@@ -1539,12 +1547,20 @@
         return string;
     }
 
+    private WifiManager getWifiManager() {
+        if (mWifiManager == null) {
+            mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+        }
+        return mWifiManager;
+    }
+
     /**
      * Callbacks relaying changes to the AccessPoint representation.
      *
      * <p>All methods are invoked on the Main Thread.
      */
     public interface AccessPointListener {
+
         /**
          * Indicates a change to the externally visible state of the AccessPoint trigger by an
          * update of ScanResults, saved configuration state, connection state, or score
@@ -1561,7 +1577,6 @@
          *                    changed
          */
         @MainThread void onAccessPointChanged(AccessPoint accessPoint);
-
         /**
          * Indicates the "wifi pie signal level" has changed, retrieved via calls to
          * {@link AccessPoint#getLevel()}.
@@ -1643,11 +1658,46 @@
             mOsuProvisioningComplete = true;
             mOsuFailure = null;
             mOsuStatus = null;
+
             ThreadUtils.postOnMainThread(() -> {
                 if (mAccessPointListener != null) {
                     mAccessPointListener.onAccessPointChanged(AccessPoint.this);
                 }
             });
+
+            // Connect to the freshly provisioned network.
+            WifiManager wifiManager = getWifiManager();
+
+            PasspointConfiguration passpointConfig = wifiManager
+                    .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(mOsuProvider))
+                    .get(mOsuProvider);
+            if (passpointConfig == null) {
+                Log.e(TAG, "Missing PasspointConfiguration for newly provisioned network!");
+                if (mConnectListener != null) {
+                    mConnectListener.onFailure(0);
+                }
+                return;
+            }
+
+            String fqdn = passpointConfig.getHomeSp().getFqdn();
+            for (Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> pairing :
+                    wifiManager.getAllMatchingWifiConfigs(wifiManager.getScanResults())) {
+                WifiConfiguration config = pairing.first;
+                if (TextUtils.equals(config.FQDN, fqdn)) {
+                    List<ScanResult> homeScans =
+                            pairing.second.get(WifiManager.PASSPOINT_HOME_NETWORK);
+                    List<ScanResult> roamingScans =
+                            pairing.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK);
+
+                    AccessPoint connectionAp =
+                            new AccessPoint(mContext, config, homeScans, roamingScans);
+                    wifiManager.connect(connectionAp.getConfig(), mConnectListener);
+                    return;
+                }
+            }
+            if (mConnectListener != null) {
+                mConnectListener.onFailure(0);
+            }
         }
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index fdc0fd3..5f2bc4e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -84,7 +84,7 @@
     private static final long DEFAULT_MAX_CACHED_SCORE_AGE_MILLIS = 20 * DateUtils.MINUTE_IN_MILLIS;
 
     /** Maximum age of scan results to hold onto while actively scanning. **/
-    private static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000;
+    @VisibleForTesting static final long MAX_SCAN_RESULT_AGE_MILLIS = 15000;
 
     private static final String TAG = "WifiTracker";
     private static final boolean DBG() {
@@ -142,6 +142,13 @@
      */
     private boolean mStaleScanResults = true;
 
+    /**
+     * Tracks whether the latest SCAN_RESULTS_AVAILABLE_ACTION contained new scans. If not, then
+     * we treat the last scan as an aborted scan and increase the eviction timeout window to avoid
+     * completely flushing the AP list before the next successful scan completes.
+     */
+    private boolean mLastScanSucceeded = true;
+
     // Does not need to be locked as it only updated on the worker thread, with the exception of
     // during onStart, which occurs before the receiver is registered on the work handler.
     private final HashMap<String, ScanResult> mScanResultCache = new HashMap<>();
@@ -478,17 +485,22 @@
     }
 
     /**
-     * Remove old scan results from the cache.
+     * Remove old scan results from the cache. If {@link #mLastScanSucceeded} is false, then
+     * increase the timeout window to avoid completely flushing the AP list before the next
+     * successful scan completes.
      *
      * <p>Should only ever be invoked from {@link #updateScanResultCache(List)} when
      * {@link #mStaleScanResults} is false.
      */
     private void evictOldScans() {
+        long evictionTimeoutMillis = mLastScanSucceeded ? MAX_SCAN_RESULT_AGE_MILLIS
+                : MAX_SCAN_RESULT_AGE_MILLIS * 2;
+
         long nowMs = SystemClock.elapsedRealtime();
         for (Iterator<ScanResult> iter = mScanResultCache.values().iterator(); iter.hasNext(); ) {
             ScanResult result = iter.next();
             // result timestamp is in microseconds
-            if (nowMs - result.timestamp / 1000 > MAX_SCAN_RESULT_AGE_MILLIS) {
+            if (nowMs - result.timestamp / 1000 > evictionTimeoutMillis) {
                 iter.remove();
             }
         }
@@ -840,6 +852,8 @@
                                 WifiManager.WIFI_STATE_UNKNOWN));
             } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
                 mStaleScanResults = false;
+                mLastScanSucceeded =
+                        intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, true);
 
                 fetchScansAndConfigsAndUpdateAccessPoints();
             } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action)
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 9c8e3f4..8e40271 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -41,6 +41,7 @@
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.net.wifi.WifiNetworkScoreCache;
 import android.net.wifi.WifiSsid;
 import android.net.wifi.hotspot2.OsuProvider;
@@ -53,6 +54,7 @@
 import android.text.SpannableString;
 import android.text.format.DateUtils;
 import android.util.ArraySet;
+import android.util.Pair;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -72,6 +74,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
@@ -95,9 +98,12 @@
 
     private Context mContext;
     private WifiInfo mWifiInfo;
+    @Mock private Context mMockContext;
+    @Mock private WifiManager mMockWifiManager;
     @Mock private RssiCurve mockBadgeCurve;
     @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache;
     @Mock private AccessPoint.AccessPointListener mMockAccessPointListener;
+    @Mock private WifiManager.ActionListener mMockConnectListener;
     private static final int NETWORK_ID = 123;
     private static final int DEFAULT_RSSI = -55;
 
@@ -1360,6 +1366,9 @@
                 .isEqualTo(mContext.getString(R.string.tap_to_sign_up));
     }
 
+    /**
+     * Verifies that the summary of an OSU entry updates based on provisioning status.
+     */
     @Test
     public void testOsuAccessPointSummary_showsProvisioningUpdates() {
         AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(),
@@ -1411,4 +1420,82 @@
         assertThat(osuAccessPoint.getSummary())
                 .isEqualTo(mContext.getString(R.string.osu_sign_up_complete));
     }
+
+    /**
+     * Verifies that after provisioning through an OSU provider, we connect to the freshly
+     * provisioned network.
+     */
+    @Test
+    public void testOsuAccessPoint_connectsAfterProvisioning() {
+        // Set up mock for WifiManager.getAllMatchingWifiConfigs
+        WifiConfiguration config = new WifiConfiguration();
+        config.FQDN = "fqdn";
+        Map<Integer, List<ScanResult>> scanMapping = new HashMap<>();
+        scanMapping.put(WifiManager.PASSPOINT_HOME_NETWORK, mScanResults);
+        Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> configMapPair =
+                new Pair<>(config, scanMapping);
+        List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingWifiConfig =
+                new ArrayList<>();
+        matchingWifiConfig.add(configMapPair);
+        when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(matchingWifiConfig);
+
+        // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders
+        OsuProvider provider = createOsuProvider();
+        PasspointConfiguration passpointConfig = new PasspointConfiguration();
+        HomeSp homeSp = new HomeSp();
+        homeSp.setFqdn("fqdn");
+        homeSp.setFriendlyName("Test Provider");
+        passpointConfig.setHomeSp(homeSp);
+        Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>();
+        osuProviderConfigMap.put(provider, passpointConfig);
+        when(mMockWifiManager
+                .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider)))
+                .thenReturn(osuProviderConfigMap);
+
+        when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);
+
+        AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults);
+        osuAccessPoint.setListener(mMockAccessPointListener);
+
+        AccessPoint.AccessPointProvisioningCallback provisioningCallback =
+                osuAccessPoint.new AccessPointProvisioningCallback();
+        provisioningCallback.onProvisioningComplete();
+
+        verify(mMockWifiManager).connect(any(), any());
+    }
+
+    /**
+     * Verifies that after provisioning through an OSU provider, we call the connect listener's
+     * onFailure() method if we cannot find the network we just provisioned.
+     */
+    @Test
+    public void testOsuAccessPoint_noMatchingConfigsAfterProvisioning_callsOnFailure() {
+        // Set up mock for WifiManager.getAllMatchingWifiConfigs
+        when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(new ArrayList<>());
+
+        // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders
+        OsuProvider provider = createOsuProvider();
+        PasspointConfiguration passpointConfig = new PasspointConfiguration();
+        HomeSp homeSp = new HomeSp();
+        homeSp.setFqdn("fqdn");
+        homeSp.setFriendlyName("Test Provider");
+        passpointConfig.setHomeSp(homeSp);
+        Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>();
+        osuProviderConfigMap.put(provider, passpointConfig);
+        when(mMockWifiManager
+                .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider)))
+                .thenReturn(osuProviderConfigMap);
+
+        when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);
+
+        AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults);
+        osuAccessPoint.setListener(mMockAccessPointListener);
+        osuAccessPoint.startOsuProvisioning(mMockConnectListener);
+
+        AccessPoint.AccessPointProvisioningCallback provisioningCallback =
+                osuAccessPoint.new AccessPointProvisioningCallback();
+        provisioningCallback.onProvisioningComplete();
+
+        verify(mMockConnectListener).onFailure(anyInt());
+    }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index edf414d..683ec8b 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -270,7 +270,7 @@
                 SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */);
     }
 
-    private static ScanResult buildStaleScanResult() {
+    private static ScanResult buildScanResultWithTimestamp(long timestampMillis) {
         return new ScanResult(
                 WifiSsid.createFromAsciiEncoded(SSID_3),
                 BSSID_3,
@@ -280,7 +280,7 @@
                 "", // capabilities
                 RSSI_3,
                 0, // frequency
-                0 /* microsecond timestamp */);
+                timestampMillis * 1000 /* microsecond timestamp */);
     }
 
     private static WifiConfiguration buildPasspointConfiguration(String fqdn, String friendlyName) {
@@ -379,6 +379,12 @@
         tracker.mReceiver.onReceive(mContext, i);
     }
 
+    private void sendFailedScanResults(WifiTracker tracker) throws InterruptedException {
+        Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        i.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);
+        tracker.mReceiver.onReceive(mContext, i);
+    }
+
     private void sendUpdatedScores() throws InterruptedException {
         Bundle attr1 = new Bundle();
         attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve1);
@@ -982,8 +988,8 @@
 
     @Test
     public void onStart_updateScanResults_evictOldScanResult() {
-        when(mockWifiManager.getScanResults()).thenReturn(
-                Arrays.asList(buildScanResult1(), buildScanResult2(), buildStaleScanResult()));
+        when(mockWifiManager.getScanResults()).thenReturn(Arrays.asList(
+                buildScanResult1(), buildScanResult2(), buildScanResultWithTimestamp(0)));
         WifiTracker tracker = createMockedWifiTracker();
 
         tracker.forceUpdate();
@@ -995,6 +1001,33 @@
     }
 
     /**
+     * Verifies that a failed scan reported on SCAN_RESULTS_AVAILABLE_ACTION should increase the
+     * ScanResult eviction timeout to twice the default.
+     */
+    @Test
+    public void failedScan_increasesEvictionTimeout() throws InterruptedException {
+        when(mockWifiManager.getScanResults()).thenReturn(Arrays.asList(
+                buildScanResult1(), buildScanResult2(), buildScanResultWithTimestamp(
+                        SystemClock.elapsedRealtime() - WifiTracker.MAX_SCAN_RESULT_AGE_MILLIS)));
+        WifiTracker tracker = createMockedWifiTracker();
+
+        sendFailedScanResults(tracker);
+
+        // Failed scan increases timeout window to include the stale scan
+        assertThat(tracker.getAccessPoints()).hasSize(3);
+        assertThat(tracker.getAccessPoints().get(0).getBssid()).isEqualTo(BSSID_1);
+        assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2);
+        assertThat(tracker.getAccessPoints().get(2).getBssid()).isEqualTo(BSSID_3);
+
+        sendScanResults(tracker);
+
+        // Successful scan resets the timeout window to remove the stale scan
+        assertThat(tracker.getAccessPoints()).hasSize(2);
+        assertThat(tracker.getAccessPoints().get(0).getBssid()).isEqualTo(BSSID_1);
+        assertThat(tracker.getAccessPoints().get(1).getBssid()).isEqualTo(BSSID_2);
+    }
+
+    /**
      * Verifies that updatePasspointAccessPoints will only return AccessPoints whose
      * isPasspoint() evaluates as true.
      */
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
index b713e08..b228cf7 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
@@ -15,15 +15,20 @@
  */
 package com.android.settingslib.bluetooth;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.util.Pair;
 
+import com.android.settingslib.widget.AdaptiveIcon;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -38,6 +43,9 @@
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private CachedBluetoothDevice mCachedBluetoothDevice;
+    @Mock
+    private BluetoothDevice mBluetoothDevice;
+
     private Context mContext;
 
     @Before
@@ -66,4 +74,16 @@
 
         verify(mContext).getDrawable(com.android.internal.R.drawable.ic_bt_laptop);
     }
+
+    @Test
+    public void getBtRainbowDrawableWithDescription_normalHeadset_returnAdaptiveIcon() {
+        when(mBluetoothDevice.getMetadata(
+                BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)).thenReturn("false");
+        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+        when(mCachedBluetoothDevice.getAddress()).thenReturn("1f:aa:bb");
+
+        assertThat(BluetoothUtils.getBtRainbowDrawableWithDescription(
+                RuntimeEnvironment.application,
+                mCachedBluetoothDevice).first).isInstanceOf(AdaptiveIcon.class);
+    }
 }
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
index bfda888..d0d1e58 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
@@ -116,16 +116,11 @@
     }
 
     @Test
-    public void isIconTintable_noMetadata_shouldReturnPackageNameCheck() {
-        final Tile tile1 = new Tile(mActivityInfo, "category");
-        assertThat(tile1.isIconTintable(RuntimeEnvironment.application)).isFalse();
+    public void isIconTintable_noTintableMetadata_shouldReturnFalse() {
+        final Tile tile = new Tile(mActivityInfo, "category");
+        mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON, android.R.drawable.ic_info);
 
-        final ActivityInfo activityInfo = new ActivityInfo();
-        activityInfo.packageName = "blah";
-        activityInfo.name = "abc";
-
-        final Tile tile2 = new Tile(activityInfo, "category");
-        assertThat(tile2.isIconTintable(RuntimeEnvironment.application)).isTrue();
+        assertThat(tile.isIconTintable(RuntimeEnvironment.application)).isFalse();
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index c892711..aa1ac4e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -205,10 +205,6 @@
                 null /* defaultCategory */, outTiles, false /* usePriority */);
         assertThat(outTiles.size()).isEqualTo(1);
         assertThat(outTiles.get(0).getTitle(mContext)).isEqualTo("my localized title");
-
-        // Icon should be tintable because the tile is not from settings package, and
-        // "forceTintExternalIcon" is set
-        assertThat(outTiles.get(0).isIconTintable(mContext)).isTrue();
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
index bbf807d2..44ee423 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
@@ -118,6 +118,7 @@
         ShadowSmsApplication.setDefaultSmsApplication(new ComponentName(testSms, "receiver"));
 
         assertThat(mPowerWhitelistBackend.isWhitelisted(testSms)).isTrue();
+        assertThat(mPowerWhitelistBackend.isDefaultActiveApp(testSms)).isTrue();
     }
 
     @Test
@@ -126,6 +127,7 @@
         ShadowDefaultDialerManager.setDefaultDialerApplication(testDialer);
 
         assertThat(mPowerWhitelistBackend.isWhitelisted(testDialer)).isTrue();
+        assertThat(mPowerWhitelistBackend.isDefaultActiveApp(testDialer)).isTrue();
     }
 
     @Test
@@ -133,6 +135,7 @@
         doReturn(true).when(mDevicePolicyManager).packageHasActiveAdmins(PACKAGE_ONE);
 
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
+        assertThat(mPowerWhitelistBackend.isDefaultActiveApp(PACKAGE_ONE)).isTrue();
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java
index c1c5fa9..5d2a0d1d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAccessesTest.java
@@ -16,9 +16,10 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
-
 import android.util.LongSparseLongArray;
+
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -83,6 +84,7 @@
     }
 
     @Test
+    @Ignore
     public void testGetAppList_shouldFilterRecentAccesses() {
         List<RecentLocationAccesses.Access> requests = mRecentLocationAccesses.getAppList();
         // Only two of the apps have requested location within 15 min.
@@ -95,6 +97,7 @@
     }
 
     @Test
+    @Ignore
     public void testGetAppList_shouldNotShowAndroidOS() throws NameNotFoundException {
         // Add android OS to the list of apps.
         PackageOps androidSystemPackageOps =
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java
new file mode 100644
index 0000000..ed6b9b0
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.widget;
+
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Icon;
+import android.graphics.drawable.ShapeDrawable;
+import android.os.Bundle;
+
+import com.android.settingslib.R;
+import com.android.settingslib.drawer.CategoryKey;
+import com.android.settingslib.drawer.Tile;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class AdaptiveIconTest {
+
+    private Context mContext;
+    private ActivityInfo mActivityInfo;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mActivityInfo = new ActivityInfo();
+        mActivityInfo.packageName = mContext.getPackageName();
+        mActivityInfo.name = "class";
+        mActivityInfo.metaData = new Bundle();
+    }
+
+    @Test
+    public void createIcon_shouldSetBackgroundAndInset() {
+        final AdaptiveIcon icon =
+                new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
+
+        assertThat(icon.getNumberOfLayers()).isEqualTo(2);
+        assertThat(icon.getDrawable(0)).isInstanceOf(AdaptiveIconShapeDrawable.class);
+    }
+
+    @Test
+    public void setBackgroundColor_shouldUpdateColorFilter() {
+        final AdaptiveIcon icon =
+                spy(new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)));
+        final ShapeDrawable background = mock(ShapeDrawable.class);
+        when(icon.getDrawable(0)).thenReturn(background);
+
+        icon.setBackgroundColor(Color.BLUE);
+
+        verify(background).setColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP);
+    }
+
+    @Test
+    public void setBackgroundColor_externalTileWithBackgroundColorRawValue_shouldUpdateIcon() {
+        final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
+        mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000);
+        doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
+                .when(tile).getIcon(mContext);
+        final AdaptiveIcon icon =
+                new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
+
+        icon.setBackgroundColor(mContext, tile);
+        assertThat(icon.mBackgroundColor).isEqualTo(0xff0000);
+    }
+
+    @Test
+    public void setBackgroundColor_tileWithoutBackgroundColor_shouldSetDefaultBackgroundColor() {
+        final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
+        doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
+            .when(tile).getIcon(mContext);
+        final AdaptiveIcon icon = new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
+
+        icon.setBackgroundColor(mContext, tile);
+
+        assertThat(icon.mBackgroundColor)
+                .isEqualTo(mContext.getColor(R.color.homepage_generic_icon_background));
+    }
+
+    @Test
+    public void onBindTile_externalTileWithBackgroundColorHint_shouldUpdateIcon() {
+        final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
+        mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
+                R.color.bt_outline_color);
+        doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
+                .when(tile).getIcon(mContext);
+
+        final AdaptiveIcon icon =
+                new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
+        icon.setBackgroundColor(mContext, tile);
+
+        assertThat(icon.mBackgroundColor)
+                .isEqualTo(mContext.getColor(R.color.bt_outline_color));
+    }
+
+    @Test
+    public void getConstantState_returnCorrectState() {
+        final AdaptiveIcon icon =
+                new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
+        icon.setBackgroundColor(Color.YELLOW);
+
+        final AdaptiveIcon.AdaptiveConstantState state =
+                (AdaptiveIcon.AdaptiveConstantState) icon.getConstantState();
+
+        assertThat(state.mColor).isEqualTo(Color.YELLOW);
+        assertThat(state.mContext).isEqualTo(mContext);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java
new file mode 100644
index 0000000..71d55bc
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.res.Resources;
+import android.graphics.Paint;
+
+import com.android.settingslib.R;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class AdaptiveOutlineDrawableTest {
+
+    @Test
+    public void constructor_initPaint() {
+        final Resources resources = RuntimeEnvironment.application.getResources();
+        final AdaptiveOutlineDrawable drawable = new AdaptiveOutlineDrawable(resources, null);
+
+        assertThat(drawable.mOutlinePaint.getStyle()).isEqualTo(Paint.Style.STROKE);
+        assertThat(drawable.mOutlinePaint.getStrokeWidth()).isWithin(0.01f).of(
+                resources.getDimension(R.dimen.adaptive_outline_stroke));
+    }
+
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartInfoTest.java
index 2b27248..7faac7a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartInfoTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartInfoTest.java
@@ -39,6 +39,8 @@
     private final int mDetails = 0x22222222;
     @StringRes
     private final int mEmptyText = 0x33333333;
+    private final CharSequence mTitleStr = "title";
+    private final CharSequence mSummaryStr = "summary";
     private final View.OnClickListener mClickListener = v -> {
     };
 
@@ -72,7 +74,8 @@
         final BarViewInfo barViewInfo = new BarViewInfo(
                 null /* icon */,
                 50,
-                mTitle,
+                mTitleStr,
+                mSummaryStr,
                 null);
 
         final BarChartInfo mBarChartInfo = new BarChartInfo.Builder()
@@ -92,7 +95,8 @@
         final BarViewInfo barViewInfo = new BarViewInfo(
                 null /* icon */,
                 50,
-                mTitle,
+                mTitleStr,
+                mSummaryStr,
                 null);
         final BarChartInfo mBarChartInfo = new BarChartInfo.Builder()
                 .setTitle(mTitle)
@@ -115,7 +119,8 @@
         final BarViewInfo barViewInfo = new BarViewInfo(
                 null /* icon */,
                 50,
-                mTitle,
+                mTitleStr,
+                mSummaryStr,
                 null);
         new BarChartInfo.Builder()
                 .setTitle(mTitle)
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java
index 266554b..567d90f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java
@@ -39,6 +39,8 @@
 
     @Rule
     public final ExpectedException thrown = ExpectedException.none();
+    private final CharSequence mTitleStr = "title";
+    private final CharSequence mSummaryStr = "summary";
 
     private Context mContext;
     private View mBarChartView;
@@ -114,7 +116,9 @@
                 .setTitle(R.string.debug_app)
                 .setDetails(R.string.debug_app)
                 .addBarViewInfo(
-                        new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null))
+                        new BarViewInfo(mIcon, 10, null /* title */,
+                                mContext.getText(R.string.debug_app) /* summary */,
+                                null /* contentDescription */))
                 .build();
 
         mPreference.initializeBarChart(barChartInfo);
@@ -130,7 +134,9 @@
         final BarChartInfo barChartInfo = new BarChartInfo.Builder()
                 .setTitle(R.string.debug_app)
                 .addBarViewInfo(
-                        new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null))
+                        new BarViewInfo(mIcon, 10, null /* title */,
+                                mContext.getText(R.string.debug_app) /* summary */,
+                                null /* contentDescription */))
                 .build();
 
         mPreference.initializeBarChart(barChartInfo);
@@ -147,7 +153,9 @@
                 .setDetailsOnClickListener(v -> {
                 })
                 .addBarViewInfo(
-                        new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null))
+                        new BarViewInfo(mIcon, 10, null /* title */,
+                                mContext.getText(R.string.debug_app) /* summary */,
+                                null /* contentDescription */))
                 .build();
 
         mPreference.initializeBarChart(barChartInfo);
@@ -160,7 +168,7 @@
     @Test
     public void setBarViewInfos_oneBarViewInfoSet_shouldShowOneBarView() {
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
-                new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null)
+                new BarViewInfo(mIcon, 10, mTitleStr, mSummaryStr, null /* contentDescription */)
         };
 
         mPreference.initializeBarChart(mBarChartInfo);
@@ -168,7 +176,7 @@
         mPreference.onBindViewHolder(mHolder);
 
         assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView1.getTitle()).isEqualTo("10");
+        assertThat(mBarView1.getTitle()).isEqualTo(mTitleStr);
 
         assertThat(mBarView2.getVisibility()).isEqualTo(View.GONE);
         assertThat(mBarView3.getVisibility()).isEqualTo(View.GONE);
@@ -178,8 +186,8 @@
     @Test
     public void setBarViewInfos_twoBarViewInfosSet_shouldShowTwoBarViews() {
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
-                new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null)
+                new BarViewInfo(mIcon, 20, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 10, mTitleStr, mSummaryStr, null /* contentDescription */),
         };
 
         mPreference.initializeBarChart(mBarChartInfo);
@@ -187,9 +195,9 @@
         mPreference.onBindViewHolder(mHolder);
 
         assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView1.getTitle()).isEqualTo("20");
+        assertThat(mBarView1.getTitle()).isEqualTo(mTitleStr);
         assertThat(mBarView2.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView2.getTitle()).isEqualTo("10");
+        assertThat(mBarView2.getTitle()).isEqualTo(mTitleStr);
 
         assertThat(mBarView3.getVisibility()).isEqualTo(View.GONE);
         assertThat(mBarView4.getVisibility()).isEqualTo(View.GONE);
@@ -198,9 +206,9 @@
     @Test
     public void setBarViewInfos_threeBarViewInfosSet_shouldShowThreeBarViews() {
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
-                new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app, null)
+                new BarViewInfo(mIcon, 20, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 10, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 5, mTitleStr, mSummaryStr, null /* contentDescription */)
         };
 
         mPreference.initializeBarChart(mBarChartInfo);
@@ -208,11 +216,11 @@
         mPreference.onBindViewHolder(mHolder);
 
         assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView1.getTitle()).isEqualTo("20");
+        assertThat(mBarView1.getTitle()).isEqualTo(mTitleStr);
         assertThat(mBarView2.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView2.getTitle()).isEqualTo("10");
+        assertThat(mBarView2.getTitle()).isEqualTo(mTitleStr);
         assertThat(mBarView3.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView3.getTitle()).isEqualTo("5");
+        assertThat(mBarView3.getTitle()).isEqualTo(mTitleStr);
 
         assertThat(mBarView4.getVisibility()).isEqualTo(View.GONE);
     }
@@ -220,10 +228,10 @@
     @Test
     public void setBarViewInfos_fourBarViewInfosSet_shouldShowFourBarViews() {
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
-                new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 2 /* barNumber */, R.string.debug_app, null),
+                new BarViewInfo(mIcon, 20, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 10, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 5, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 2, mTitleStr, mSummaryStr, null /* contentDescription */)
         };
 
         mPreference.initializeBarChart(mBarChartInfo);
@@ -231,13 +239,13 @@
         mPreference.onBindViewHolder(mHolder);
 
         assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView1.getTitle()).isEqualTo("20");
+        assertThat(mBarView1.getTitle()).isEqualTo(mTitleStr);
         assertThat(mBarView2.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView2.getTitle()).isEqualTo("10");
+        assertThat(mBarView2.getTitle()).isEqualTo(mTitleStr);
         assertThat(mBarView3.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView3.getTitle()).isEqualTo("5");
+        assertThat(mBarView3.getTitle()).isEqualTo(mTitleStr);
         assertThat(mBarView4.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView4.getTitle()).isEqualTo("2");
+        assertThat(mBarView4.getTitle()).isEqualTo(mTitleStr);
     }
 
     @Test
@@ -245,11 +253,11 @@
         thrown.expect(IllegalStateException.class);
 
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
-                new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 50 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 70 /* barNumber */, R.string.debug_app, null),
+                new BarViewInfo(mIcon, 30, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 50, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 5, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 10, mTitleStr, mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 70, mTitleStr, mSummaryStr, null /* contentDescription */),
         };
 
         mPreference.setBarViewInfos(barViewsInfo);
@@ -258,10 +266,10 @@
     @Test
     public void setBarViewInfos_barViewInfosSet_shouldBeSortedInDescending() {
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
-                new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 50 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app, null),
-                new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
+                new BarViewInfo(mIcon, 30, "30", mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 50, "50", mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 5, "5", mSummaryStr, null /* contentDescription */),
+                new BarViewInfo(mIcon, 10, "10", mSummaryStr, null /* contentDescription */)
         };
 
         mPreference.initializeBarChart(mBarChartInfo);
@@ -281,7 +289,7 @@
     @Test
     public void setBarViewInfos_validBarViewSummarySet_barViewShouldShowSummary() {
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
-                new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
+                new BarViewInfo(mIcon, 10, mTitleStr, mSummaryStr, null /* contentDescription */)
         };
 
         mPreference.initializeBarChart(mBarChartInfo);
@@ -289,13 +297,27 @@
         mPreference.onBindViewHolder(mHolder);
 
         assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mBarView1.getSummary()).isEqualTo(mContext.getText(R.string.debug_app));
+        assertThat(mBarView1.getSummary()).isEqualTo(mSummaryStr);
+    }
+
+    @Test
+    public void setBarViewInfos_validBarViewTitleSet_barViewShouldShowTitle() {
+        final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
+                new BarViewInfo(mIcon, 10, mTitleStr, mSummaryStr, null /* contentDescription */)
+        };
+
+        mPreference.initializeBarChart(mBarChartInfo);
+        mPreference.setBarViewInfos(barViewsInfo);
+        mPreference.onBindViewHolder(mHolder);
+
+        assertThat(mBarView1.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mBarView1.getTitle()).isEqualTo(mTitleStr);
     }
 
     @Test
     public void setBarViewInfos_clickListenerForBarViewSet_barViewShouldHaveClickListener() {
-        final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app,
-                null);
+        final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30, mTitleStr, mSummaryStr,
+                null /* contentDescription */);
         viewInfo.setClickListener(v -> {
         });
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{viewInfo};
@@ -310,8 +332,8 @@
 
     @Test
     public void onBindViewHolder_loadingStateIsTrue_shouldHideAllViews() {
-        final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app,
-                null);
+        final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30, mTitleStr, mSummaryStr,
+                null /* contentDescription */);
         viewInfo.setClickListener(v -> {
         });
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{viewInfo};
@@ -327,8 +349,8 @@
 
     @Test
     public void onBindViewHolder_loadingStateIsFalse_shouldInitAnyView() {
-        final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app,
-                null);
+        final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30, mTitleStr, mSummaryStr,
+                null /* contentDescription */);
         viewInfo.setClickListener(v -> {
         });
         final BarViewInfo[] barViewsInfo = new BarViewInfo[]{viewInfo};
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index e374db3..f597a1a 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -686,6 +686,9 @@
                 Settings.Global.GPU_DEBUG_LAYERS,
                 GlobalSettingsProto.Gpu.DEBUG_LAYERS);
         dumpSetting(s, p,
+                Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE,
+                GlobalSettingsProto.Gpu.ANGLE_DEBUG_PACKAGE);
+        dumpSetting(s, p,
                 Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE,
                 GlobalSettingsProto.Gpu.ANGLE_GL_DRIVER_ALL_ANGLE);
         dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 4b342b3..296f7a1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.providers.settings;
 
+import static android.os.Process.INVALID_UID;
 import static android.os.Process.ROOT_UID;
 import static android.os.Process.SHELL_UID;
 import static android.os.Process.SYSTEM_UID;
@@ -2777,7 +2778,7 @@
                         boolean someSettingChanged = false;
                         Setting setting = settingsState.getSettingLocked(name);
                         if (!SettingsState.isSystemPackage(getContext(),
-                                setting.getPackageName())) {
+                                setting.getPackageName(), INVALID_UID, userId)) {
                             if (prefix != null && !setting.getName().startsWith(prefix)) {
                                 continue;
                             }
@@ -2797,7 +2798,7 @@
                         boolean someSettingChanged = false;
                         Setting setting = settingsState.getSettingLocked(name);
                         if (!SettingsState.isSystemPackage(getContext(),
-                                setting.getPackageName())) {
+                                setting.getPackageName(), INVALID_UID, userId)) {
                             if (prefix != null && !setting.getName().startsWith(prefix)) {
                                 continue;
                             }
@@ -4410,7 +4411,7 @@
                 }
                 try {
                     final boolean systemSet = SettingsState.isSystemPackage(getContext(),
-                            setting.getPackageName(), callingUid);
+                            setting.getPackageName(), callingUid, userId);
                     if (systemSet) {
                         settings.insertSettingLocked(name, setting.getValue(),
                                 setting.getTag(), true, setting.getPackageName());
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 521163f..c05c4cd 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -17,6 +17,7 @@
 package com.android.providers.settings;
 
 import static android.os.Process.FIRST_APPLICATION_UID;
+import static android.os.Process.INVALID_UID;
 
 import android.annotation.NonNull;
 import android.content.Context;
@@ -1124,11 +1125,16 @@
         return sb.toString();
     }
 
+    // Check if a specific package belonging to the caller is part of the system package.
     public static boolean isSystemPackage(Context context, String packageName) {
-        return isSystemPackage(context, packageName, Binder.getCallingUid());
+        final int callingUid = Binder.getCallingUid();
+        final int callingUserId = UserHandle.getUserId(callingUid);
+        return isSystemPackage(context, packageName, callingUid, callingUserId);
     }
 
-    public static boolean isSystemPackage(Context context, String packageName, int callingUid) {
+    // Check if a specific package, uid, and user ID are part of the system package.
+    public static boolean isSystemPackage(Context context, String packageName, int uid,
+            int userId) {
         synchronized (sLock) {
             if (SYSTEM_PACKAGE_NAME.equals(packageName)) {
                 return true;
@@ -1140,26 +1146,19 @@
                 return false;
             }
 
-            // Native services running as a special UID get a pass
-            final int callingAppId = UserHandle.getAppId(callingUid);
-            if (callingAppId < FIRST_APPLICATION_UID) {
-                sSystemUids.put(callingAppId, callingAppId);
-                return true;
+            if (uid != INVALID_UID) {
+                // Native services running as a special UID get a pass
+                final int callingAppId = UserHandle.getAppId(uid);
+                if (callingAppId < FIRST_APPLICATION_UID) {
+                    sSystemUids.put(callingAppId, callingAppId);
+                    return true;
+                }
             }
 
-            // While some callers may have permissions to manipulate cross user
-            // settings or some settings are stored in the parent of a managed
-            // profile for the purpose of determining whether the other end is a
-            // system component we need to use the user id of the caller for
-            // pulling information about the caller from the package manager.
-            final int callingUserId = UserHandle.getUserId(callingUid);
-
             final long identity = Binder.clearCallingIdentity();
             try {
-                final int uid;
                 try {
-                    uid = context.getPackageManager().getPackageUidAsUser(packageName, 0,
-                            callingUserId);
+                    uid = context.getPackageManager().getPackageUidAsUser(packageName, 0, userId);
                 } catch (PackageManager.NameNotFoundException e) {
                     return false;
                 }
@@ -1187,7 +1186,7 @@
                 PackageInfo packageInfo;
                 try {
                     packageInfo = context.getPackageManager().getPackageInfoAsUser(
-                            packageName, PackageManager.GET_SIGNATURES, callingUserId);
+                            packageName, PackageManager.GET_SIGNATURES, userId);
                     if ((packageInfo.applicationInfo.flags
                             & ApplicationInfo.FLAG_PERSISTENT) != 0
                             && (packageInfo.applicationInfo.flags
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index d6e61eb..2a9456d 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -125,6 +125,8 @@
     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
     <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" />
     <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+    <!-- Shell only holds android.permission.NETWORK_SCAN in order to to enable CTS testing -->
+    <uses-permission android:name="android.permission.NETWORK_SCAN" />
     <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" />
     <uses-permission android:name="android.permission.REGISTER_CONNECTION_MANAGER" />
     <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" />
@@ -166,6 +168,9 @@
     <uses-permission android:name="android.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED" />
     <uses-permission android:name="android.permission.MANAGE_WIFI_WHEN_WIRELESS_CONSENT_REQUIRED" />
     <uses-permission android:name="android.permission.WATCH_APPOPS" />
+    <!-- Permission needed to invoke DynamicSystem (AOT) -->
+    <uses-permission android:name="android.permission.INSTALL_DYNAMIC_SYSTEM" />
+
 
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
     <uses-permission android:name="android.permission.SUSPEND_APPS" />
@@ -178,6 +183,8 @@
 
     <!-- Permission needed to run network tests in CTS -->
     <uses-permission android:name="android.permission.MANAGE_TEST_NETWORKS" />
+    <!-- Permission needed to test tcp keepalive offload. -->
+    <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
 
     <!-- Permission needed to run keyguard manager tests in CTS -->
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" />
diff --git a/packages/Shell/tests/Android.mk b/packages/Shell/tests/Android.mk
index b93ddde..44ff338 100644
--- a/packages/Shell/tests/Android.mk
+++ b/packages/Shell/tests/Android.mk
@@ -9,7 +9,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-test \
+    androidx.test.rules \
     mockito-target-minus-junit4 \
     ub-uiautomator \
     junit \
diff --git a/packages/Shell/tests/AndroidManifest.xml b/packages/Shell/tests/AndroidManifest.xml
index 6d564c6..e845ef9 100644
--- a/packages/Shell/tests/AndroidManifest.xml
+++ b/packages/Shell/tests/AndroidManifest.xml
@@ -36,7 +36,7 @@
         </activity>
     </application>
 
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
         android:targetPackage="com.android.shell"
         android:label="Tests for Shell" />
 
diff --git a/packages/Shell/tests/AndroidTest.xml b/packages/Shell/tests/AndroidTest.xml
index e592d82..e03b68a 100644
--- a/packages/Shell/tests/AndroidTest.xml
+++ b/packages/Shell/tests/AndroidTest.xml
@@ -22,7 +22,7 @@
     <option name="test-tag" value="ShellTests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.shell.tests" />
-        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
         <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java b/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java
index cef74ae..433eca2 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportProgressServiceTest.java
@@ -20,7 +20,6 @@
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNull;
 
-import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
 
@@ -29,12 +28,12 @@
 import android.content.Context;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
 import android.test.mock.MockContext;
 import android.util.Pair;
 
-import org.junit.Before;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index e69b0a8..3a71632 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -42,6 +42,40 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningServiceInfo;
+import android.app.Instrumentation;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.service.notification.StatusBarNotification;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMultipleListener;
+
+import libcore.io.Streams;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+
 import java.io.BufferedOutputStream;
 import java.io.BufferedWriter;
 import java.io.ByteArrayOutputStream;
@@ -60,40 +94,6 @@
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
 
-import libcore.io.Streams;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.Instrumentation;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.service.notification.StatusBarNotification;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.Log;
-
-import com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMultipleListener;
-
 /**
  * Integration tests for {@link BugreportReceiver}.
  * <p>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index d654f5a..fcf9200 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -33,8 +33,10 @@
         android:protectionLevel="signature" />
 
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+
+    <!-- Used to read wallpaper -->
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
     <!-- Used to read storage for all users -->
     <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
@@ -110,6 +112,7 @@
     <uses-permission android:name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS" />
     <uses-permission android:name="android.permission.SET_ORIENTATION" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.MONITOR_INPUT" />
 
     <!-- DreamManager -->
     <uses-permission android:name="android.permission.READ_DREAM_STATE" />
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
index 7b7657a..58d50ea 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
@@ -28,7 +28,7 @@
 public interface ClockPlugin extends Plugin {
 
     String ACTION = "com.android.systemui.action.PLUGIN_CLOCK";
-    int VERSION = 2;
+    int VERSION = 4;
 
     /**
      * Get the name of the clock face.
@@ -48,6 +48,17 @@
     Bitmap getThumbnail();
 
     /**
+     * Get preview images of clock face to be shown in the picker app.
+     *
+     * Preview image should be realistic and show what the clock face will look like on AOD and lock
+     * screen.
+     *
+     * @param width width of the preview image, should be the same as device width in pixels.
+     * @param height height of the preview image, should be the same as device height in pixels.
+     */
+    Bitmap getPreview(int width, int height);
+
+    /**
      * Get clock view.
      * @return clock view from plugin.
      */
@@ -61,6 +72,14 @@
     }
 
     /**
+     * Allows the plugin to clean up resources when no longer needed.
+     *
+     * Called when the view previously created by {@link ClockPlugin#getView()} has been detached
+     * from the view hierarchy.
+     */
+    void onDestroyView();
+
+    /**
      * Set clock paint style.
      * @param style The new style to set in the paint.
      */
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_left_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_left_animation.xml
deleted file mode 100644
index d6054c4..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_left_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="250"
-        android:propertyName="scaleX"
-        android:valueFrom="1.0"
-        android:valueTo="1.8"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_mask_1_animation.xml
deleted file mode 100644
index 282170c..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_mask_1_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="pathData"
-            android:valueFrom="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
-            android:valueTo="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="250"
-            android:propertyName="pathData"
-            android:valueFrom="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
-            android:valueTo="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_2" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_animation.xml
deleted file mode 100644
index b59c664..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="pathData"
-            android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="pathData"
-            android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_position_animation.xml
deleted file mode 100644
index 60d2396..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_3_position_animation.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="250"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M 0.0,0.0 c 0.0,4.16667 0.0,20.83333 0.0,25.0"
-        android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_animation.xml
deleted file mode 100644
index ef442e9..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyName="pathData"
-            android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="pathData"
-            android:valueFrom="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_position_animation.xml
deleted file mode 100644
index 97782be..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_rectangle_path_4_position_animation.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="233"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M 0.0,0.0 c 0.0,-4.16667 0.0,-20.83333 0.0,-25.0"
-        android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_right_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_right_animation.xml
deleted file mode 100644
index d6054c4..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_right_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="250"
-        android:propertyName="scaleX"
-        android:valueFrom="1.0"
-        android:valueTo="1.8"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/linear" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_stick_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stick_animation.xml
deleted file mode 100644
index 573205f..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_stick_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="250"
-        android:propertyName="scaleY"
-        android:valueFrom="0.0"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_3" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_stickito_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_stickito_animation.xml
deleted file mode 100644
index 4b038b9..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_stickito_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="333"
-        android:propertyName="alpha"
-        android:valueFrom="1.0"
-        android:valueTo="0.54"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_4" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_whole_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_whole_animation.xml
deleted file mode 100644
index 562985a8..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_disable_whole_animation.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.15667"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="scaleX"
-            android:valueFrom="1.15667"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.15667"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="scaleY"
-            android:valueFrom="1.15667"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_signal_workmode_disable_animation_interpolator_5" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
deleted file mode 100644
index 6c7e751..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
-        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="17"
-            android:propertyName="strokeAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
deleted file mode 100644
index c699fe2..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="0.5"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-        <objectAnimator
-            android:duration="350"
-            android:propertyName="alpha"
-            android:valueFrom="0.5"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
deleted file mode 100644
index 5595e5c..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="350"
-        android:propertyName="pathData"
-        android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_left_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_left_animation.xml
deleted file mode 100644
index 4614bfc..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_left_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.8"
-            android:valueTo="1.8"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="250"
-            android:propertyName="scaleX"
-            android:valueFrom="1.8"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_mask_1_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_mask_1_animation.xml
deleted file mode 100644
index f5cfcf9..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_mask_1_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="250"
-        android:propertyName="pathData"
-        android:valueFrom="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 480.0,480.0 480.0,480.0 c 0.0,0.0 -20.7500915527,20.75 -20.7500915527,20.75 c 0.0,0.0 -479.999908447,-480.000015259 -479.999908447,-480.000015259 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
-        android:valueTo="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z"
-        android:valueType="pathType"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_1" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_animation.xml
deleted file mode 100644
index 0b74b3a..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="pathData"
-            android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="133"
-            android:propertyName="pathData"
-            android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_position_animation.xml
deleted file mode 100644
index ba10224..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_3_position_animation.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="216"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M 0.0,25.0 c 0.0,-4.16667 0.0,-20.83333 0.0,-25.0"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_2" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_animation.xml
deleted file mode 100644
index 395bbf4..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="pathData"
-            android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueTo="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="199"
-            android:propertyName="pathData"
-            android:valueFrom="M -143.0,-65.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,66.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-66.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueTo="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_position_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_position_animation.xml
deleted file mode 100644
index 0115759..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_rectangle_path_4_position_animation.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="300"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M 0.0,-25.0 c 0.0,4.16667 0.0,20.83333 0.0,25.0"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_4" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_right_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_right_animation.xml
deleted file mode 100644
index 4614bfc..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_right_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.8"
-            android:valueTo="1.8"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="250"
-            android:propertyName="scaleX"
-            android:valueFrom="1.8"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_stick_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stick_animation.xml
deleted file mode 100644
index 6b182be..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_stick_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="250"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_stickito_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_stickito_animation.xml
deleted file mode 100644
index 828f7a2..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_stickito_animation.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="333"
-        android:propertyName="alpha"
-        android:valueFrom="0.54"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_3" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_whole_animation.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_whole_animation.xml
deleted file mode 100644
index 89ab580..0000000
--- a/packages/SystemUI/res/anim/ic_signal_workmode_enable_whole_animation.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="66"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="scaleX"
-            android:valueFrom="0.0"
-            android:valueTo="1.15667"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_5" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleX"
-            android:valueFrom="1.15667"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_0" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="66"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="scaleY"
-            android:valueFrom="0.0"
-            android:valueTo="1.15667"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_5" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="scaleY"
-            android:valueFrom="1.15667"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_signal_workmode_enable_animation_interpolator_0" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off_alpha.png
deleted file mode 100644
index 0a29157..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_on_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_on_alpha.png
deleted file mode 100644
index 9c1d8ef..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_on_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off_alpha.png
deleted file mode 100644
index 74df151..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_on_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_on_alpha.png
deleted file mode 100644
index 56add92..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_on_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/icon.xml b/packages/SystemUI/res/drawable-nodpi/icon.xml
index 48094c4..7a68c03 100644
--- a/packages/SystemUI/res/drawable-nodpi/icon.xml
+++ b/packages/SystemUI/res/drawable-nodpi/icon.xml
@@ -15,5 +15,5 @@
 -->
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
     <background android:drawable="@drawable/icon_bg"/>
-    <foreground android:drawable="@drawable/p"/>
+    <foreground android:drawable="@drawable/q"/>
 </adaptive-icon>
diff --git a/packages/SystemUI/res/drawable-nodpi/icon_bg.xml b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
index 31ecf7e..2a54dfa 100644
--- a/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
+++ b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
@@ -14,5 +14,5 @@
     limitations under the License.
 -->
 <color xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="#C5E1A5" />
+    android:color="#77C360" />
 
diff --git a/packages/SystemUI/res/drawable-nodpi/p.xml b/packages/SystemUI/res/drawable-nodpi/p.xml
deleted file mode 100644
index 596b782..0000000
--- a/packages/SystemUI/res/drawable-nodpi/p.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-Copyright (C) 2018 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="108dp"
-    android:height="108dp"
-    android:viewportWidth="108"
-    android:viewportHeight="108">
-  <path
-      android:pathData="M49,65L54,65C60.075,65 65,60.075 65,54C65,47.925 60.075,43 54,43C47.925,43 43,47.925 43,54L43,108"
-      android:strokeWidth="16"
-      android:fillColor="#00000000"
-      android:strokeColor="#7CB342"
-      android:fillType="evenOdd"/>
-  <path
-      android:pathData="M51,65L54,65C60.075,65 65,60.075 65,54C65,47.925 60.075,43 54,43C47.925,43 43,47.925 43,54L43,108"
-      android:strokeWidth="8"
-      android:fillColor="#00000000"
-      android:strokeColor="#FFFFFF"
-      android:fillType="evenOdd"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable-nodpi/q.xml b/packages/SystemUI/res/drawable-nodpi/q.xml
new file mode 100644
index 0000000..0f42d2e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/q.xml
@@ -0,0 +1,40 @@
+<!--
+Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="108dp"
+        android:height="108dp"
+        android:viewportWidth="108.0"
+        android:viewportHeight="108.0">
+    <group
+        android:name="scale"
+        android:pivotX="54" android:pivotY="54"
+        android:scaleX="0.9"
+        android:scaleY="0.9">
+        <group
+            android:name="nudge"
+            android:translateX="24"
+            android:translateY="23.5">
+            <path
+                android:name="tail"
+                android:fillColor="#FFFFFF"
+                android:pathData="M21.749674,34.122784l-9.431964,9.529709l-6.31771,-6.2529106l15.736504,-15.899582l64.765724,65.16436l-6.3046494,6.266083z"/>
+            <path
+                android:name="counter"
+                android:fillColor="#FFFFFF"
+                android:pathData="M30,9.32352941 C41.6954418,9.32352941 51.1764706,18.8045582 51.1764706,30.5 C51.1764706,42.1954418 41.6954418,51.6764706 30,51.6764706 C18.3045582,51.6764706 8.82352941,42.1954418 8.82352941,30.5 C8.82352941,18.8045582 18.3045582,9.32352941 30,9.32352941 L30,9.32352941 Z M30,0.5 C13.4314575,0.5 -5.53805368e-15,13.9314575 -7.10542736e-15,30.5 C-1.02401747e-14,47.0685425 13.4314575,60.5 30,60.5 C46.5685425,60.5 60,47.0685425 60,30.5 C59.9805514,13.9395201 46.5604799,0.519448617 30,0.5 Z"/>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_off_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_off_alpha.png
deleted file mode 100644
index 37d7ac7..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_off_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on_alpha.png
deleted file mode 100644
index 626e283..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_off_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_off_alpha.png
deleted file mode 100644
index 2697b5a..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_off_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_on_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_on_alpha.png
deleted file mode 100644
index b6443fa..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_on_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/bubble_flyout.xml b/packages/SystemUI/res/drawable/bubble_flyout.xml
new file mode 100644
index 0000000..5406aaa
--- /dev/null
+++ b/packages/SystemUI/res/drawable/bubble_flyout.xml
@@ -0,0 +1,29 @@
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+    <!-- TODO: Add the triangle pointing to the bubble stack. -->
+    <item>
+        <shape android:shape="rectangle">
+            <solid android:color="?android:attr/colorBackgroundFloating" />
+            <corners
+                android:bottomLeftRadius="?android:attr/dialogCornerRadius"
+                android:topLeftRadius="?android:attr/dialogCornerRadius"
+                android:bottomRightRadius="?android:attr/dialogCornerRadius"
+                android:topRightRadius="?android:attr/dialogCornerRadius"
+            />
+        </shape>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_alarm.xml b/packages/SystemUI/res/drawable/ic_alarm.xml
new file mode 100644
index 0000000..1c1adcd
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_alarm.xml
@@ -0,0 +1,25 @@
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="17dp"
+    android:width="17dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24">
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M13,8h-2v5.41l3.79,3.8 1.42,-1.42 -3.21,-3.2zM12,4c-4.97,0 -9,4.03 -9,9s4.03,9 9,9 9,-4.03 9,-9 -4.03,-9 -9,-9zM12,20c-3.86,0 -7,-3.14 -7,-7s3.14,-7 7,-7 7,3.14 7,7 -3.14,7 -7,7zM16.056,3.346l1.282,-1.535 4.607,3.85 -1.28,1.54zM2.056,5.654L6.663,1.81l1.28,1.536L3.338,7.19z"/>
+
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_alarm_dim.xml b/packages/SystemUI/res/drawable/ic_alarm_dim.xml
new file mode 100644
index 0000000..37ab873
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_alarm_dim.xml
@@ -0,0 +1,26 @@
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="17dp"
+    android:width="17dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24">
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillAlpha="0.3"
+        android:pathData="M13,8h-2v5.41l3.79,3.8 1.42,-1.42 -3.21,-3.2zM12,4c-4.97,0 -9,4.03 -9,9s4.03,9 9,9 9,-4.03 9,-9 -4.03,-9 -9,-9zM12,20c-3.86,0 -7,-3.14 -7,-7s3.14,-7 7,-7 7,3.14 7,7 -3.14,7 -7,7zM16.056,3.346l1.282,-1.535 4.607,3.85 -1.28,1.54zM2.056,5.654L6.663,1.81l1.28,1.536L3.338,7.19z"/>
+
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_bluetooth_connected.xml b/packages/SystemUI/res/drawable/ic_bluetooth_connected.xml
new file mode 100644
index 0000000..125082c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_bluetooth_connected.xml
@@ -0,0 +1,30 @@
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="17dp"
+    android:height="17dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 11,14.41L11,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z"/>
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M19,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_camera.xml b/packages/SystemUI/res/drawable/ic_camera.xml
new file mode 100644
index 0000000..b330875
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_camera.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="17dp"
+        android:height="17dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFF"
+        android:pathData="M20,5h-3.17L15,3H9L7.17,5H4C2.9,5 2,5.9 2,7v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V7C22,5.9 21.1,5 20,5zM20,19H4V7h16V19zM12,9c-2.21,0 -4,1.79 -4,4c0,2.21 1.79,4 4,4s4,-1.79 4,-4C16,10.79 14.21,9 12,9z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_cast.xml b/packages/SystemUI/res/drawable/ic_cast.xml
new file mode 100644
index 0000000..a2c2eb2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_cast.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM1,18v3h3c0,-1.66 -1.34,-3 -3,-3zM1,14v2c2.76,0 5,2.24 5,5h2c0,-3.87 -3.13,-7 -7,-7zM1,10v2c4.97,0 9,4.03 9,9h2c0,-6.08 -4.93,-11 -11,-11z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_cast_connected.xml b/packages/SystemUI/res/drawable/ic_cast_connected.xml
new file mode 100644
index 0000000..995fd49
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_cast_connected.xml
@@ -0,0 +1,26 @@
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="17dp"
+        android:height="17dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M1,18v3h3C4,19.34 2.66,18 1,18zM1,14v2c2.76,0 5,2.24 5,5h2C8,17.13 4.87,14 1,14zM19,7H5v1.63c3.96,1.28 7.09,4.41 8.37,8.37H19V7zM1,10v2c4.97,0 9,4.03 9,9h2C12,14.92 7.07,10 1,10zM21,3H3C1.9,3 1,3.9 1,5v3h2V5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2V5C23,3.9 22.1,3 21,3"/>
+
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver.xml b/packages/SystemUI/res/drawable/ic_data_saver.xml
index 0f027ee..cc3f539 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver.xml
@@ -14,15 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
+    android:width="18dp"
+    android:height="18dp"
     android:viewportWidth="24.0"
-    android:viewportHeight="24.0"
-    android:tint="?android:attr/colorControlNormal">
+    android:viewportHeight="24.0">
     <path
-        android:pathData="M16,12c0,0.55 -0.45,1 -1,1h-2v2c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1v-2L9,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h2L11,9c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v2h2c0.55,0 1,0.45 1,1zM17.69,16.87a7.437,7.437 0,0 1,-5.93 2.63c-3.82,-0.12 -7.03,-3.25 -7.25,-7.07 -0.21,-3.84 2.48,-7.1 6.07,-7.79 0.24,-0.04 0.42,-0.24 0.42,-0.48L11,2.62c0,-0.3 -0.27,-0.55 -0.57,-0.5A10.02,10.02 0,0 0,2.09 13.4c0.59,4.4 4.16,7.94 8.56,8.52a9.99,9.99 0,0 0,9.14 -3.65,0.5 0.5,0 0,0 -0.15,-0.74l-1.32,-0.76a0.469,0.469 0,0 0,-0.63 0.1z"
+        android:pathData="M11,8v3L8,11v2h3v3h2v-3h3v-2h-3L13,8zM13,2.05v3.03c3.39,0.49 6,3.39 6,6.92 0,0.9 -0.18,1.75 -0.48,2.54l2.6,1.53c0.56,-1.24 0.88,-2.62 0.88,-4.07 0,-5.18 -3.95,-9.45 -9,-9.95zM12,19c-3.87,0 -7,-3.13 -7,-7 0,-3.53 2.61,-6.43 6,-6.92L11,2.05c-5.06,0.5 -9,4.76 -9,9.95 0,5.52 4.47,10 9.99,10 3.31,0 6.24,-1.61 8.06,-4.09l-2.6,-1.53C16.17,17.98 14.21,19 12,19z"
         android:fillColor="#FFFFFFFF"/>
-    <path
-        android:pathData="M13.41,4.64a0.493,0.493 0,0 1,-0.41 -0.48L13,2.62c0,-0.3 0.27,-0.55 0.57,-0.5C18.35,2.88 22,7.01 22,12c0,1.23 -0.23,2.41 -0.64,3.5 -0.11,0.28 -0.45,0.4 -0.72,0.24l-1.33,-0.77a0.484,0.484 0,0 1,-0.21 -0.59c0.25,-0.75 0.39,-1.55 0.39,-2.38 0.01,-3.65 -2.62,-6.69 -6.08,-7.36z"
-        android:fillColor="#54FFFFFF" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver_off.xml b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
index 29e6c91..d8e9bc4 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver_off.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
@@ -17,9 +17,8 @@
         android:width="24.0dp"
         android:height="24.0dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0"
-        android:tint="?android:attr/colorControlNormal">
+        android:viewportHeight="24.0">
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M18.32,16.75l1.32,0.76c0.26,0.15 0.34,0.51 0.15,0.74 -2.09,2.6 -5.44,4.14 -9.14,3.65 -4.4,-0.58 -7.96,-4.12 -8.56,-8.52C1.34,7.8 5.21,2.95 10.43,2.12c0.3,-0.05 0.57,0.2 0.57,0.5v1.53c0,0.24 -0.18,0.44 -0.41,0.49 -3.6,0.69 -6.29,3.95 -6.07,7.79 0.21,3.82 3.43,6.95 7.25,7.07 2.37,0.08 4.51,-0.96 5.93,-2.63a0.48,0.48 0,0 1,0.62 -0.12zM19.5,12c0,0.83 -0.14,1.63 -0.39,2.38 -0.08,0.23 0.01,0.47 0.21,0.59l1.33,0.77c0.26,0.15 0.61,0.04 0.72,-0.24 0.4,-1.09 0.63,-2.27 0.63,-3.5 0,-4.99 -3.65,-9.12 -8.43,-9.88 -0.3,-0.04 -0.57,0.2 -0.57,0.5v1.53c0,0.24 0.18,0.44 0.41,0.48 3.46,0.68 6.09,3.72 6.09,7.37z" />
+        android:pathData="M13,2.05v3.03c3.39,0.49 6,3.39 6,6.92 0,0.9 -0.18,1.75 -0.48,2.54l2.6,1.53c0.56,-1.24 0.88,-2.62 0.88,-4.07 0,-5.18 -3.95,-9.45 -9,-9.95zM12,19c-3.87,0 -7,-3.13 -7,-7 0,-3.53 2.61,-6.43 6,-6.92V2.05c-5.06,0.5 -9,4.76 -9,9.95 0,5.52 4.47,10 9.99,10 3.31,0 6.24,-1.61 8.06,-4.09l-2.6,-1.53C16.17,17.98 14.21,19 12,19z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_headset.xml b/packages/SystemUI/res/drawable/ic_headset.xml
index 27efe80..797a80a 100644
--- a/packages/SystemUI/res/drawable/ic_headset.xml
+++ b/packages/SystemUI/res/drawable/ic_headset.xml
@@ -13,19 +13,12 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
-    <vector
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-        <group
-            android:translateY="-1">
-            <path
-                android:fillColor="#FFFFFFFF"
-                android:pathData="M19,15v3c0,0.55 -0.45,1 -1,1h-1v-4H19M7,15v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7M12,2c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h3c1.66,0 3,-1.34 3,-3v-7C21,6.03 16.97,2 12,2L12,2z"/>
-        </group>
-    </vector>
-</inset>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="17.0dp"
+    android:height="17.0dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19,15v3c0,0.55 -0.45,1 -1,1h-1v-4h2M7,15v4H6c-0.55,0 -1,-0.45 -1,-1v-3h2m5,-13c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-2c0,-3.87 3.13,-7 7,-7s7,3.13 7,7v2h-4v8h3c1.66,0 3,-1.34 3,-3v-7c0,-4.97 -4.03,-9 -9,-9z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_headset_mic.xml b/packages/SystemUI/res/drawable/ic_headset_mic.xml
index 1260e0f..b3f006d 100644
--- a/packages/SystemUI/res/drawable/ic_headset_mic.xml
+++ b/packages/SystemUI/res/drawable/ic_headset_mic.xml
@@ -13,16 +13,12 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
-    <vector
-        android:width="17.0dp"
-        android:height="17.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-1.71C5,6.45 7.96,3.11 11.79,3C15.76,2.89 19,6.06 19,10v2h-4v8h4v1h-6v2h6c1.1,0 2,-0.9 2,-2V10C21,5.03 16.97,1 12,1zM7,14v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7zM19,18h-2v-4h2V18z"/>
-    </vector>
-</inset>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="17.0dp"
+    android:height="17.0dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12,1c-4.97,0 -9,4.03 -9,9v7c0,1.66 1.34,3 3,3h3v-8H5v-1.71C5,6.45 7.96,3.11 11.79,3C15.76,2.89 19,6.06 19,10v2h-4v8h4v1h-6v2h6c1.1,0 2,-0.9 2,-2V10C21,5.03 16.97,1 12,1zM7,14v4H6c-0.55,0 -1,-0.45 -1,-1v-3H7zM19,18h-2v-4h2V18z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot.xml b/packages/SystemUI/res/drawable/ic_hotspot.xml
index 8450bf6..b6fa798 100644
--- a/packages/SystemUI/res/drawable/ic_hotspot.xml
+++ b/packages/SystemUI/res/drawable/ic_hotspot.xml
@@ -15,14 +15,12 @@
      limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="48dp"
-    android:height="48dp"
+    android:width="18dp"
+    android:height="18dp"
     android:viewportWidth="24.0"
     android:viewportHeight="24.0">
-    <group
-        android:translateY="-0.32">
-        <path
-            android:pathData="M12,11c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,13a6,6 0,0 0,-6.75 -5.95c-2.62,0.32 -4.78,2.41 -5.18,5.02 -0.32,2.14 0.49,4.11 1.92,5.39 0.48,0.43 1.24,0.33 1.56,-0.23 0.24,-0.42 0.14,-0.94 -0.22,-1.26a3.99,3.99 0,0 1,-1.22 -3.94,3.954 3.954,0 0,1 2.9,-2.91A4.007,4.007 0,0 1,16 13c0,1.18 -0.51,2.23 -1.33,2.96 -0.36,0.33 -0.47,0.85 -0.23,1.27 0.31,0.54 1.04,0.69 1.5,0.28A5.97,5.97 0,0 0,18 13zM10.83,3.07c-4.62,0.52 -8.35,4.33 -8.78,8.96a9.966,9.966 0,0 0,4.02 9.01c0.48,0.35 1.16,0.2 1.46,-0.31 0.25,-0.43 0.14,-0.99 -0.26,-1.29 -2.28,-1.69 -3.65,-4.55 -3.16,-7.7 0.54,-3.5 3.46,-6.29 6.98,-6.68C15.91,4.51 20,8.28 20,13c0,2.65 -1.29,4.98 -3.27,6.44 -0.4,0.3 -0.51,0.85 -0.26,1.29 0.3,0.52 0.98,0.66 1.46,0.31A9.96,9.96 0,0 0,22 13c0,-5.91 -5.13,-10.62 -11.17,-9.93z"
-            android:fillColor="#FFFFFFFF"/>
-    </group>
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M12,7c-3.31,0 -6,2.69 -6,6 0,1.66 0.68,3.15 1.76,4.24l1.42,-1.42C8.45,15.1 8,14.11 8,13c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,1.11 -0.45,2.1 -1.18,2.82l1.42,1.42C17.32,16.15 18,14.66 18,13c0,-3.31 -2.69,-6 -6,-6zM12,3C6.48,3 2,7.48 2,13c0,2.76 1.12,5.26 2.93,7.07l1.41,-1.41C4.9,17.21 4,15.21 4,13c0,-4.42 3.58,-8 8,-8s8,3.58 8,8c0,2.21 -0.9,4.2 -2.35,5.65l1.41,1.41C20.88,18.26 22,15.76 22,13c0,-5.52 -4.48,-10 -10,-10zM12,11c-1.1,0 -2,0.9 -2,2 0,0.55 0.23,1.05 0.59,1.41 0.36,0.36 0.86,0.59 1.41,0.59s1.05,-0.23 1.41,-0.59c0.36,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2z" />
+
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_unavailable.xml b/packages/SystemUI/res/drawable/ic_hotspot_unavailable.xml
deleted file mode 100644
index 7641998..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_unavailable.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="root"
-    android:height="48dp"
-    android:width="48dp"
-    android:viewportHeight="48"
-    android:viewportWidth="48" >
-    <group
-        android:name="ic_hotspot"
-        android:translateX="23.97354"
-        android:translateY="24.26306" >
-        <group
-            android:name="ic_hotspot_pivot"
-            android:translateX="-23.21545"
-            android:translateY="-18.86649" >
-            <clip-path
-                android:name="mask"
-                android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 43.1884765625,43.515335083 43.1884765625,43.515335083 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -42.9885101318,-43.0112609863 -42.9885101318,-43.0112609863 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 13.0984039307,13.025604248 13.0984039307,13.025604248 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 16.571762085,22.0471801758 16.571762085,22.0471801758 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
-            <group
-                android:name="cross" >
-                <path
-                    android:name="cross_1"
-                    android:pathData="M 4.44044494629,2.24310302734 c 0.0,0.0 35.4000396729,35.3999633789 35.4000396729,35.3999633789 "
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeAlpha="1"
-                    android:strokeWidth="3.5"
-                    android:fillColor="#00000000" />
-            </group>
-            <group
-                android:name="hotspot"
-                android:translateX="23.481"
-                android:translateY="18.71151" >
-                <group
-                    android:name="circles"
-                    android:translateX="-0.23909"
-                    android:translateY="-0.10807" >
-                    <path
-                        android:name="circle_3"
-                        android:pathData="M 0.0843505859375,-2.93901062012 c -2.30102539062,0.0 -4.16702270508,1.86602783203 -4.16702270508,4.16702270508 c 0.0,2.29898071289 1.86599731445,4.16598510742 4.16702270508,4.16598510742 c 2.29998779297,0.0 4.16598510742,-1.86700439453 4.16598510742,-4.16598510742 c 0.0,-2.30099487305 -1.86599731445,-4.16702270508 -4.16598510742,-4.16702270508 Z M 11.1185302734,5.83390808105 c 0.0,0.0 0.0009765625,0.00100708007812 0.0009765625,0.00100708007812 c 0.14501953125,-0.356994628906 0.27099609375,-0.725006103516 0.382995605469,-1.09799194336 c 0.0570068359375,-0.195007324219 0.101013183594,-0.394989013672 0.149017333984,-0.595001220703 c 0.0690002441406,-0.281005859375 0.126983642578,-0.563995361328 0.175994873047,-0.851989746094 c 0.0270080566406,-0.169006347656 0.0559997558594,-0.337005615234 0.0759887695313,-0.509002685547 c 0.0580139160156,-0.468017578125 0.0970153808594,-0.942993164062 0.0970153808593,-1.4280090332 c 0.0,0.0 0.0,-0.00100708007812 0.0,-0.00100708007812 c 0.0,-5.03900146484 -3.11099243164,-9.3450012207 -7.5119934082,-11.1229858398 c -0.00601196289062,-0.00299072265625 -0.0130004882812,-0.0050048828125 -0.0190124511719,-0.00701904296875 c -0.686004638672,-0.275970458984 -1.39999389648,-0.492980957031 -2.14099121094,-0.638977050781 c -0.072998046875,-0.0150146484375 -0.149017333984,-0.02099609375 -0.222991943359,-0.0339965820313 c -0.302001953125,-0.0540161132812 -0.605010986328,-0.106018066406 -0.916015625,-0.136016845703 c -0.389984130859,-0.0390014648438 -0.786987304688,-0.0599975585938 -1.18899536133,-0.0599975585937 c -0.402008056641,0.0 -0.799011230469,0.02099609375 -1.19000244141,0.0599975585937 c -0.304992675781,0.0299987792969 -0.602996826172,0.0809936523438 -0.901000976563,0.132995605469 c -0.0790100097656,0.0150146484375 -0.160003662109,0.02099609375 -0.238006591797,0.0370178222656 c -0.368988037109,0.0719909667969 -0.730987548828,0.164001464844 -1.08700561523,0.269989013672 c -0.00299072265625,0.00100708007812 -0.0059814453125,0.00201416015625 -0.00900268554687,0.0020141601562 c -0.351989746094,0.10498046875 -0.694000244141,0.226989746094 -1.0309753418,0.361999511719 c -0.0110168457031,0.00399780273438 -0.0220031738281,0.00698852539062 -0.0320129394531,0.0119934082031 c -4.40200805664,1.77798461914 -7.51098632812,6.083984375 -7.5119934082,11.1229858398 c 0.0,0.00799560546875 0.00198364257812,0.0160217285156 0.0019836425781,0.0240173339844 c 0.00100708007812,0.475006103516 0.0380249023438,0.940002441406 0.0950012207032,1.39898681641 c 0.02001953125,0.175994873047 0.0490112304688,0.348999023438 0.0780029296875,0.523010253906 c 0.0469970703125,0.281982421875 0.105010986328,0.557983398438 0.171997070312,0.833984375 c 0.0480041503906,0.204010009766 0.093017578125,0.410003662109 0.152008056641,0.610015869141 c 0.110992431641,0.372009277344 0.238006591797,0.736999511719 0.382019042969,1.09298706055 c 0.0,0.0 0.0009765625,0.0 0.0009765625,0.0 c 1.00701904297,2.48400878906 2.81301879883,4.56100463867 5.11001586914,5.89501953125 c 0.0,0.0 2.01599121094,-3.48300170898 2.01599121094,-3.48300170898 c -2.03900146484,-1.18402099609 -3.5119934082,-3.22500610352 -3.89898681641,-5.63900756836 c 0.0,0.0 0.0009765625,-0.00100708007812 0.0009765625,-0.00100708007812 c -0.0220031738281,-0.130981445312 -0.0369873046875,-0.265991210938 -0.052978515625,-0.399993896484 c -0.0290222167969,-0.274993896484 -0.0570068359375,-0.552001953125 -0.0570068359375,-0.834991455078 c 0.0,0.0 0.0,-0.0190124511719 0.0,-0.0190124511719 c 0.0,-3.98999023438 2.92498779297,-7.28900146484 6.74398803711,-7.89199829102 c 0.0,0.0 0.0180053710938,0.0169982910156 0.0180053710938,0.0169982910156 c 0.404998779297,-0.0639953613281 0.81298828125,-0.125 1.23599243164,-0.125 c 0.0,0.0 0.00201416015625,0.0 0.00201416015624,0.0 c 0.0,0.0 0.00299072265625,0.0 0.00299072265626,0.0 c 0.423004150391,0.0 0.830017089844,0.0610046386719 1.23501586914,0.125 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c 3.81997680664,0.60400390625 6.74499511719,3.90301513672 6.74499511719,7.89199829102 c 0.0,0.292999267578 -0.0280151367188,0.578002929688 -0.0589904785156,0.861999511719 c -0.0150146484375,0.132019042969 -0.0290222167969,0.264007568359 -0.051025390625,0.393005371094 c -0.385986328125,2.41500854492 -1.85897827148,4.45599365234 -3.89797973633,5.64001464844 c 0.0,0.0 2.01599121094,3.48300170898 2.01599121094,3.48300170898 c 2.29699707031,-1.33401489258 4.10299682617,-3.41101074219 5.11001586914,-5.89602661133 Z M 19.9300231934,2.95698547363 c 0.0059814453125,-0.0659790039062 0.0159912109375,-0.130981445312 0.02099609375,-0.196990966797 c 0.031982421875,-0.462005615234 0.0479736328125,-0.928009033203 0.0489807128906,-1.39700317383 c 0,0.0 0,-0.00997924804688 0,-0.00997924804687 c 0,0.0 0,-0.00100708007812 0,-0.00100708007813 c 0,-7.22500610352 -3.84399414062,-13.5360107422 -9.58599853516,-17.0500183105 c -1.06500244141,-0.652984619141 -2.19299316406,-1.20599365234 -3.37799072266,-1.65197753906 c -0.157989501953,-0.0599975585938 -0.317016601562,-0.118011474609 -0.476989746094,-0.174011230469 c -0.317016601562,-0.110992431641 -0.634002685547,-0.218994140625 -0.9580078125,-0.31298828125 c -0.470001220703,-0.139007568359 -0.944000244141,-0.264007568359 -1.4280090332,-0.368011474609 c -0.186004638672,-0.0390014648438 -0.376983642578,-0.0669860839844 -0.565002441406,-0.101013183594 c -0.414001464844,-0.0759887695312 -0.832000732422,-0.140991210938 -1.25500488281,-0.190979003906 c -0.184997558594,-0.0220031738281 -0.369995117188,-0.0429992675781 -0.556976318359,-0.0599975585937 c -0.592010498047,-0.0530090332031 -1.18801879883,-0.0899963378906 -1.79602050781,-0.0899963378907 c -0.605987548828,0.0 -1.20300292969,0.0369873046875 -1.79598999023,0.0899963378907 c -0.186004638672,0.0169982910156 -0.371002197266,0.0379943847656 -0.555999755859,0.0599975585937 c -0.423004150391,0.0499877929688 -0.842010498047,0.114990234375 -1.25601196289,0.190979003906 c -0.18798828125,0.0350036621094 -0.377990722656,0.06201171875 -0.563995361328,0.101013183594 c -0.483001708984,0.10400390625 -0.959991455078,0.22900390625 -1.42999267578,0.368011474609 c -0.321990966797,0.093994140625 -0.638000488281,0.201995849609 -0.953002929688,0.311981201172 c -0.162994384766,0.0570068359375 -0.324005126953,0.115997314453 -0.484985351562,0.177001953125 c -1.18099975586,0.445007324219 -2.30599975586,0.997009277344 -3.36801147461,1.64700317383 c -0.00201416015625,0.00100708007812 -0.00399780273438,0.00201416015625 -0.0060119628907,0.0029907226562 c -5.74099731445,3.51400756836 -9.58499145508,9.82501220703 -9.58599853516,17.0500183105 c 0,0.0 0,0.00100708007812 0,0.00100708007813 c 0,0.0059814453125 0.00100708007812,0.0130004882812 0.0010070800781,0.0199890136719 c 0.0,0.466003417969 0.0169982910156,0.928009033203 0.0490112304688,1.38598632812 c 0.0050048828125,0.0690002441406 0.0159912109375,0.136016845703 0.02099609375,0.206024169922 c 0.031982421875,0.401000976562 0.0719909667969,0.799987792969 0.127990722656,1.19400024414 c 0.00201416015625,0.0189819335938 0.00701904296875,0.0369873046875 0.010009765625,0.0569763183594 c 0.888000488281,6.17202758789 4.59799194336,11.4250183105 9.7799987793,14.4309997559 c 0.0,0.0 2.00198364258,-3.458984375 2.00198364258,-3.458984375 c -2.58599853516,-1.5 -4.708984375,-3.70401000977 -6.11697387695,-6.34399414063 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c -0.890014648438,-1.67098999023 -1.50601196289,-3.5110168457 -1.76000976562,-5.46499633789 c -0.00698852539062,-0.0500183105469 -0.010009765625,-0.102020263672 -0.0159912109375,-0.152008056641 c -0.0330200195312,-0.273010253906 -0.0610046386719,-0.545989990234 -0.0800170898437,-0.821990966797 c -0.0220031738281,-0.343017578125 -0.0350036621094,-0.68701171875 -0.0350036621094,-1.03500366211 c 0,-6.53701782227 3.92599487305,-12.1480102539 9.54299926758,-14.6310119629 c 0.157012939453,-0.0700073242188 0.313995361328,-0.135986328125 0.472015380859,-0.199981689453 c 0.373992919922,-0.151000976562 0.751983642578,-0.294006347656 1.13900756836,-0.417022705078 c 0.108978271484,-0.0350036621094 0.221984863281,-0.0619812011719 0.332000732422,-0.0950012207031 c 0.349975585938,-0.102996826172 0.705993652344,-0.194976806641 1.06597900391,-0.273986816406 c 0.114013671875,-0.0249938964844 0.227996826172,-0.052001953125 0.342010498047,-0.0750122070313 c 0.440002441406,-0.0869750976562 0.885986328125,-0.154998779297 1.33700561523,-0.203979492188 c 0.10400390625,-0.0120239257812 0.209991455078,-0.02001953125 0.315002441406,-0.0299987792969 c 0.47998046875,-0.0429992675781 0.963989257812,-0.072998046875 1.45397949219,-0.072998046875 c 0.492004394531,0.0 0.975006103516,0.0299987792969 1.45401000977,0.072998046875 c 0.105987548828,0.00997924804688 0.212005615234,0.0179748535156 0.316986083984,0.0299987792969 c 0.450012207031,0.0489807128906 0.89501953125,0.117004394531 1.33502197266,0.203002929688 c 0.115997314453,0.0239868164062 0.22998046875,0.0509948730469 0.345001220703,0.0769958496094 c 0.358001708984,0.0780029296875 0.710998535156,0.169982910156 1.06097412109,0.272003173828 c 0.111022949219,0.0329895019531 0.226013183594,0.0609741210938 0.336029052734,0.0969848632813 c 0.385986328125,0.123016357422 0.761993408203,0.265014648438 1.13497924805,0.415008544922 c 0.160003662109,0.0650024414062 0.319000244141,0.131988525391 0.477020263672,0.201995849609 c 5.61599731445,2.48400878906 9.53997802734,8.09399414062 9.53997802734,14.6310119629 c 0,0.346984863281 -0.0130004882812,0.690979003906 -0.0350036621094,1.03399658203 c -0.0179748535156,0.274993896484 -0.0469970703125,0.548004150391 -0.0789794921875,0.819000244141 c -0.00601196289062,0.052001953125 -0.010009765625,0.10498046875 -0.0160217285156,0.154998779297 c -0.252990722656,1.95498657227 -0.871002197266,3.79400634766 -1.75997924805,5.46499633789 c 0.0,0.0 0.0169982910156,0.0180053710938 0.0169982910156,0.0180053710938 c -1.40802001953,2.63998413086 -3.53100585938,4.84399414062 -6.11700439453,6.34399414063 c 0.0,0.0 2.00198364258,3.458984375 2.00198364258,3.458984375 c 5.18402099609,-3.00698852539 8.89501953125,-8.26300048828 9.78100585938,-14.4379882813 c 0.00201416015625,-0.0169982910156 0.00601196289062,-0.0320129394531 0.0079956054688,-0.0490112304688 c 0.0570068359375,-0.39697265625 0.0970153808594,-0.798980712891 0.129028320312,-1.20300292969 Z"
-                        android:fillColor="#FFFFFFFF"
-                        android:fillAlpha="1" />
-                </group>
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_location.xml b/packages/SystemUI/res/drawable/ic_location.xml
new file mode 100644
index 0000000..50ba523
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_location.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="17dp"
+    android:height="17dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
deleted file mode 100644
index dd124b7..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<!--
-Copyright (C) 2017 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24"
-        android:tint="?android:attr/colorControlNormal">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L11,14.41V22h1l5.71-5.71L13.41,12L17.71,7.71z M13,5.83 l1.88,1.88L13,9.59V5.83z M14.88,16.29L13,18.17v-3.76L14.88,16.29z" />
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M 5 10.5 C 5.82842712475 10.5 6.5 11.1715728753 6.5 12 C 6.5 12.8284271247 5.82842712475 13.5 5 13.5 C 4.17157287525 13.5 3.5 12.8284271247 3.5 12 C 3.5 11.1715728753 4.17157287525 10.5 5 10.5 Z" />
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M 19 10.5 C 19.8284271247 10.5 20.5 11.1715728753 20.5 12 C 20.5 12.8284271247 19.8284271247 13.5 19 13.5 C 18.1715728753 13.5 17.5 12.8284271247 17.5 12 C 17.5 11.1715728753 18.1715728753 10.5 19 10.5 Z" />
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
index 220c63c..1c86706 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
@@ -14,13 +14,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24"
-        android:tint="?android:attr/colorControlNormal">
-
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L11,14.41V22h1l5.71-5.71L13.41,12L17.71,7.71z M13,5.83 l1.88,1.88L13,9.59V5.83z M14.88,16.29L13,18.17v-3.76L14.88,16.29z" />
-</vector>
+        android:fillColor="@android:color/white"
+        android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 11,14.41L11,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM13,5.83l1.88,1.88L13,9.59L13,5.83zM14.88,16.29L13,18.17v-3.76l1.88,1.88z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_branded_vpn.xml b/packages/SystemUI/res/drawable/ic_qs_branded_vpn.xml
deleted file mode 100644
index b20e158..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_branded_vpn.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="12.0dp"
-        android:height="12.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M12.09,9C11.11,7.5 9.43,6.5 7.5,6.5C4.46,6.5 2,8.96 2,12c0,3.04 2.46,5.5 5.5,5.5c1.93,0 3.61,-1 4.59,-2.5H14v3h6v-3h2V9H12.09zM20,13h-2v3h-2v-3h-5.16c-0.43,1.44 -1.76,2.5 -3.34,2.5C5.57,15.5 4,13.93 4,12c0,-1.93 1.57,-3.5 3.5,-3.5c1.58,0 2.9,1.06 3.34,2.5H20V13z"/>
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M7.5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
deleted file mode 100644
index aaebc77..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_qs_brightness_auto_off_alpha"
-    android:tint="?android:attr/colorControlNormal" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml
deleted file mode 100644
index e17b533..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_qs_brightness_auto_on_alpha"
-    android:tint="?android:attr/colorControlNormal" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml b/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
deleted file mode 100644
index 9e57577..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--
-Copyright (C) 2017 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="64dp"
-    android:height="64dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
-    <path
-        android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z"
-        android:fillColor="#FFFFFFFF" />
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
deleted file mode 100644
index 3dda87c..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2017 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="64dp"
-        android:height="64dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM19,7L5,7v1.63c3.96,1.28 7.09,4.41 8.37,8.37L19,17L19,7zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z" />
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_vpn.xml b/packages/SystemUI/res/drawable/ic_qs_vpn.xml
deleted file mode 100644
index 6567d12..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_vpn.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="12.0dp"
-        android:height="12.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M12.09,9C11.11,7.5 9.43,6.5 7.5,6.5C4.46,6.5 2,8.96 2,12c0,3.04 2.46,5.5 5.5,5.5c1.93,0 3.61,-1 4.59,-2.5H14v3h6v-3h2V9H12.09zM20,13h-2v3h-2v-3h-5.16c-0.43,1.44 -1.76,2.5 -3.34,2.5C5.57,15.5 4,13.93 4,12c0,-1.93 1.57,-3.5 3.5,-3.5c1.58,0 2.9,1.06 3.34,2.5H20V13z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M7.5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml
deleted file mode 100644
index 96d8484..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<vector
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:name="ic_signal_workmode_disable"
-    android:width="42dp"
-    android:viewportWidth="42"
-    android:height="42dp"
-    android:viewportHeight="42" >
-    <group
-        android:name="suitcase"
-        android:translateX="21"
-        android:translateY="36.9375"
-        android:scaleX="0.1"
-        android:scaleY="0.1" >
-        <group
-            android:name="suitcase_pivot"
-            android:translateY="-158" >
-            <clip-path
-                android:name="mask_1"
-                android:pathData="M 366.5,-269.5 c 0.0,0.0 -578.0,2.0 -578.0,2.0 c 0.0,0.0 65.7498321533,68.2501220703 65.7498321533,68.2501220703 c 0.0,0.0 -20.7500457764,20.7500610352 -20.7500457764,20.7500610352 c 0.0,0.0 -65.749786377,-68.2501983643 -65.749786377,-68.2501983643 c 0.0,0.0 -7.25,539.250015259 -7.25,539.250015259 c 0.0,0.0 606.0,0.0 606.0,0.0 c 0.0,0.0 0.0,-562.0 0.0,-562.0 Z" />
-            <group
-                android:name="whole"
-                android:translateX="-1.11523"
-                android:translateY="32.0918" >
-                <path
-                    android:name="rectangle_path_1"
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeWidth="65"
-                    android:pathData="M 0.0,-66.5 l 0.0,0.0 c 36.7269358617,0.0 66.5,29.7730641383 66.5,66.5 l 0.0,0.0 c 0.0,36.7269358617 -29.7730641383,66.5 -66.5,66.5 l 0.0,0.0 c -36.7269358617,0.0 -66.5,-29.7730641383 -66.5,-66.5 l 0.0,0.0 c 0.0,-36.7269358617 29.7730641383,-66.5 66.5,-66.5 Z" />
-            </group>
-            <group
-                android:name="handle"
-                android:translateY="-100" >
-                <path
-                    android:name="rectangle_path_2"
-                    android:strokeColor="#FFFFFFFF"
-                    android:strokeWidth="35"
-                    android:pathData="M -34.0,-50.0 l 68.0,0.0 c 8.8365559968,0.0 16.0,7.1634440032 16.0,16.0 l 0.0,68.0 c 0.0,8.8365559968 -7.1634440032,16.0 -16.0,16.0 l -68.0,0.0 c -8.8365559968,0.0 -16.0,-7.1634440032 -16.0,-16.0 l 0.0,-68.0 c 0.0,-8.8365559968 7.1634440032,-16.0 16.0,-16.0 Z" />
-            </group>
-            <group
-                android:name="case"
-                android:translateY="32.68518" >
-                <group
-                    android:name="case_pivot"
-                    android:translateY="-32.68518" >
-                    <group
-                        android:name="bottom"
-                        android:translateY="-97.62964" >
-                        <group
-                            android:name="bottom_pivot"
-                            android:translateY="40" >
-                            <group
-                                android:name="rectangle_path_3_position" >
-                                <path
-                                    android:name="rectangle_path_3"
-                                    android:fillColor="#FFFFFFFF"
-                                    android:pathData="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" />
-                            </group>
-                        </group>
-                    </group>
-                    <group
-                        android:name="top"
-                        android:translateY="163" >
-                        <group
-                            android:name="top_pivot"
-                            android:translateY="-40" >
-                            <group
-                                android:name="rectangle_path_4_position" >
-                                <path
-                                    android:name="rectangle_path_4"
-                                    android:fillColor="#FFFFFFFF"
-                                    android:pathData="M -143.0,-40.0 l 286.0,0.0 c 17.6731119936,0.0 32.0,14.3268880064 32.0,32.0 l 0.0,16.0 c 0.0,17.6731119936 -14.3268880064,32.0 -32.0,32.0 l -286.0,0.0 c -17.6731119936,0.0 -32.0,-14.3268880064 -32.0,-32.0 l 0.0,-16.0 c 0.0,-17.6731119936 14.3268880064,-32.0 32.0,-32.0 Z" />
-                            </group>
-                        </group>
-                    </group>
-                    <group
-                        android:name="left"
-                        android:translateX="-175.00635"
-                        android:translateY="30" >
-                        <group
-                            android:name="left_pivot"
-                            android:translateX="50.00635" >
-                            <path
-                                android:name="rectangle_path_5"
-                                android:fillColor="#FFFFFFFF"
-                                android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                        </group>
-                    </group>
-                    <group
-                        android:name="right"
-                        android:translateX="174.97778"
-                        android:translateY="30" >
-                        <group
-                            android:name="right_pivot"
-                            android:translateX="-49.97778" >
-                            <path
-                                android:name="rectangle_path_6"
-                                android:fillColor="#FFFFFFFF"
-                                android:pathData="M -50.0,-88.0 l 100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l -100.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-176.0 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group
-                android:name="stick"
-                android:translateX="-166.59082"
-                android:translateY="-156.51367"
-                android:scaleY="0"
-                android:rotation="-45" >
-                <group
-                    android:name="stick_pivot"
-                    android:translateX="0.18161"
-                    android:translateY="243.8158" >
-                    <path
-                        android:name="stickito"
-                        android:fillColor="#FFFFFFFF"
-                        android:pathData="M -16.5,-243.999885 l 33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 l -33.0,0.0 c 0.0,0.0 0.0,0.0 0.0,0.0 l 0.0,-487.99977 c 0.0,0.0 0.0,0.0 0.0,0.0 Z" />
-                </group>
-            </group>
-        </group>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm.xml b/packages/SystemUI/res/drawable/ic_volume_alarm.xml
index 996e488..771b466 100644
--- a/packages/SystemUI/res/drawable/ic_volume_alarm.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_alarm.xml
@@ -14,14 +14,12 @@
      limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="24.0dp"
-    android:viewportHeight="24.0"
-    android:viewportWidth="24.0"
-    android:width="24.0dp"
-    android:tint="?android:attr/colorControlNormal">
-
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24">
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M2.7,6.5c-0.4,-0.4 -0.3,-1 0.1,-1.4l3,-2.6c0.4,-0.4 1,-0.3 1.4,0.1C7.6,3 7.5,3.7 7.1,4l-3,2.6C3.6,7 3,6.9 2.7,6.5zM21.3,5.1l-3.1,-2.6c-0.4,-0.4 -0.99,-0.31 -1.4,0.1c-0.4,0.4 -0.3,1 0.1,1.4L20,6.6c0.41,0.37 1,0.3 1.4,-0.1C21.73,6.12 21.7,5.4 21.3,5.1zM21,13c0,5 -4,9 -9,9s-9,-4 -9,-9s4,-9 9,-9S21,8 21,13zM19.1,13c0,-3.9 -3.2,-7.1 -7.1,-7.1S4.9,9.1 4.9,13s3.2,7.1 7.1,7.1S19.1,16.9 19.1,13zM11.75,8C11.34,8 11,8.34 11,8.75V14l4.14,2.48c0.34,0.21 0.77,0.1 0.98,-0.24s0.09,-0.79 -0.25,-0.99l-3.37,-2v-4.5C12.5,8.34 12.16,8 11.75,8z"/>
+        android:pathData="M13,8h-2v5.41l3.79,3.8 1.42,-1.42 -3.21,-3.2zM12,4c-4.97,0 -9,4.03 -9,9s4.03,9 9,9 9,-4.03 9,-9 -4.03,-9 -9,-9zM12,20c-3.86,0 -7,-3.14 -7,-7s3.14,-7 7,-7 7,3.14 7,7 -3.14,7 -7,7zM16.056,3.346l1.282,-1.535 4.607,3.85 -1.28,1.54zM2.056,5.654L6.663,1.81l1.28,1.536L3.338,7.19z"/>
 
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
index 02fb1e7..18e2736 100644
--- a/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_alarm_mute.xml
@@ -22,6 +22,6 @@
 
     <path
         android:fillColor="#FFFFFF"
-        android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM20.72,20.09a0.9,0.9 0,0 1,0 1.27,0.9 0.9,0 0,1 -1.27,0l-1.57,-1.57A8.875,8.875 0,0 1,12 22c-4.98,0 -9,-4.03 -9,-9 0,-2.25 0.83,-4.31 2.2,-5.89l-0.8,-0.8 -0.41,0.35a1,1 0,0 1,-1.35 -0.06,1 1,0 0,1 0.07,-1.47l0.27,-0.23 -0.7,-0.7a0.9,0.9 0,0 1,0 -1.27c0.35,-0.35 0.93,-0.35 1.28,0l17.16,17.16zM16.54,18.45L6.55,8.46A7.041,7.041 0,0 0,4.9 13c0,3.91 3.19,7.1 7.1,7.1 1.73,0 3.31,-0.62 4.54,-1.65zM7.17,3.98A0.997,0.997 0,1 0,5.9 2.44l-0.16,0.13 1.42,1.42 0.01,-0.01zM12,4c-1.41,0 -2.73,0.33 -3.92,0.91l1.45,1.45c0.77,-0.29 1.6,-0.46 2.47,-0.46 3.91,0 7.1,3.18 7.1,7.1 0,0.87 -0.17,1.7 -0.45,2.47l1.44,1.44c0.58,-1.18 0.91,-2.5 0.91,-3.91a9,9 0,0 0,-9 -9z"/>
+        android:pathData="M16.056,3.346l1.282,-1.535 4.607,3.85 -1.28,1.54zM9.35,6.52C10.17,6.19 11.06,6 12,6c3.86,0 7,3.14 7,7 0,0.94 -0.19,1.83 -0.52,2.65l1.5,1.5C20.63,15.91 21,14.5 21,13c0,-4.97 -4.03,-9 -9,-9 -1.5,0 -2.91,0.37 -4.15,1.02l1.5,1.5zM17.42,17.42L7.58,7.58 6.16,6.16l-0.72,-0.72 -1.42,-1.42 -1.21,-1.21 -1.42,1.41L2.48,5.3l-0.42,0.35 1.28,1.54 0.56,-0.47 0.9,0.9C3.67,9.12 3,10.98 3,13c0,4.97 4.03,9 9,9 2.02,0 3.88,-0.67 5.38,-1.79l2.4,2.4 1.41,-1.41 -2.35,-2.35 -1.42,-1.43zM12,20c-3.86,0 -7,-3.14 -7,-7 0,-1.46 0.46,-2.82 1.23,-3.94l9.71,9.71C14.82,19.54 13.46,20 12,20zM7.94,3.35L6.66,1.81l-1.1,0.92 1.42,1.42z"/>
 
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
index aa13f1e..314e06c 100644
--- a/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_ringer_vibrate.xml
@@ -14,11 +14,10 @@
      limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="24dp"
+    android:height="19dp"
+    android:width="19dp"
     android:viewportHeight="24.0"
-    android:viewportWidth="24.0"
-    android:width="24dp"
-    android:tint="?android:attr/colorControlNormal" >
+    android:viewportWidth="24.0">
 
     <path
         android:fillColor="#FFFFFFFF"
diff --git a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
index 2655bcd..0f8c571 100644
--- a/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_airplane_mode.xml
@@ -16,16 +16,5 @@
 ** limitations under the License.
 */
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="17.25dp"
-    android:height="18dp"
-    android:viewportWidth="19.65"
-    android:viewportHeight="20.5">
-    <group
-        android:translateX="1.3"
-        android:translateY="1.7">
-        <path
-            android:pathData="M16.01,9.87l-6.24,-3.9v-4.7C9.77,0.57 9.21,0 8.5,0S7.23,0.57 7.23,1.28v4.7L0.99,9.88c-0.37,0.23 -0.6,0.64 -0.6,1.08v0.41c0,0.29 0.29,0.5 0.55,0.41l6.27,-1.97v4.7l-1.37,1.02c-0.21,0.16 -0.34,0.41 -0.34,0.68v0.57c0,0.15 0.12,0.23 0.27,0.2 1.67,-0.47 1.12,-0.31 2.73,-0.78 1.03,0.3 1.7,0.49 2.72,0.78 0.15,0.03 0.27,-0.06 0.27,-0.2v-0.57c0,-0.27 -0.13,-0.52 -0.34,-0.68l-1.37,-1.02v-4.7l6.27,1.97c0.28,0.09 0.55,-0.12 0.55,-0.41v-0.41c0.01,-0.45 -0.23,-0.87 -0.59,-1.09z"
-            android:fillColor="#FFF"/>
-    </group>
-</vector>
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@*android:drawable/ic_qs_airplane" />
diff --git a/packages/SystemUI/res/drawable/stat_sys_alarm.xml b/packages/SystemUI/res/drawable/stat_sys_alarm.xml
index 0e9319c..b9bebec 100644
--- a/packages/SystemUI/res/drawable/stat_sys_alarm.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_alarm.xml
@@ -1,35 +1,21 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-**
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
+ *
+ * Copyright 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
 */
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
-    <vector
-        android:width="17dp"
-        android:height="17dp"
-        android:viewportWidth="19.3"
-        android:viewportHeight="19.3">
-        <group
-            android:translateX="1.2"
-            android:translateY="1.2">
-            <path
-                android:pathData="M0.97,3.97c-0.32,-0.33 -0.24,-0.81 0.08,-1.13L3.47,0.74C3.79,0.42 4.28,0.5 4.6,0.82s0.24,0.89 -0.08,1.13L2.1,4.05c-0.4,0.32 -0.89,0.24 -1.13,-0.08zM15.97,2.84l-2.5,-2.1c-0.32,-0.32 -0.8,-0.25 -1.13,0.08 -0.32,0.32 -0.24,0.81 0.08,1.13l2.5,2.1c0.33,0.3 0.81,0.24 1.13,-0.08 0.27,-0.31 0.25,-0.89 -0.08,-1.13zM15.73,9.21c0,4.03 -3.23,7.26 -7.26,7.26s-7.26,-3.23 -7.26,-7.26 3.23,-7.26 7.26,-7.26 7.26,3.23 7.26,7.26zM14.2,9.21c0,-3.15 -2.58,-5.73 -5.73,-5.73S2.74,6.06 2.74,9.21s2.58,5.73 5.73,5.73 5.73,-2.59 5.73,-5.73zM8.27,5.18c-0.33,0 -0.6,0.27 -0.6,0.6v4.23l3.34,2c0.27,0.17 0.62,0.08 0.79,-0.19s0.07,-0.64 -0.2,-0.8L8.87,9.41L8.87,5.78c0,-0.33 -0.27,-0.6 -0.6,-0.6z"
-                android:fillColor="#FFF"/>
-        </group>
-    </vector>
-</inset>
+    android:insetRight="2.5dp"
+    android:drawable="@drawable/ic_alarm" />
diff --git a/packages/SystemUI/res/drawable/stat_sys_alarm_dim.xml b/packages/SystemUI/res/drawable/stat_sys_alarm_dim.xml
index c8e2ac1..cf1119d 100644
--- a/packages/SystemUI/res/drawable/stat_sys_alarm_dim.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_alarm_dim.xml
@@ -15,18 +15,5 @@
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
-
-    <vector
-        android:width="17dp"
-        android:height="17dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-        <path
-            android:fillColor="#4dffffff"
-            android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
-
-    </vector>
-
-</inset>
\ No newline at end of file
+    android:insetRight="2.5dp"
+    android:drawable="@drawable/ic_alarm_dim" />
diff --git a/packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml b/packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml
index bfae857..5913cdf 100644
--- a/packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_branded_vpn.xml
@@ -13,6 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+<!-- This icon is statically overlayed - do not remove.-->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
         android:width="17.0dp"
         android:height="17.0dp"
diff --git a/packages/SystemUI/res/drawable/stat_sys_camera.xml b/packages/SystemUI/res/drawable/stat_sys_camera.xml
index eb3e963..c914262 100644
--- a/packages/SystemUI/res/drawable/stat_sys_camera.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_camera.xml
@@ -18,14 +18,5 @@
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="3dp"
-    android:insetRight="3dp">
-    <vector
-            android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="24.0"
-            android:viewportHeight="24.0">
-        <path
-            android:fillColor="#FFF"
-            android:pathData="M20,5h-3.17L15,3H9L7.17,5H4C2.9,5 2,5.9 2,7v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V7C22,5.9 21.1,5 20,5zM20,19H4V7h16V19zM12,9c-2.21,0 -4,1.79 -4,4c0,2.21 1.79,4 4,4s4,-1.79 4,-4C16,10.79 14.21,9 12,9z"/>
-    </vector>
-</inset>
+    android:insetRight="3dp"
+    android:drawable="@drawable/ic_camera" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_cast.xml b/packages/SystemUI/res/drawable/stat_sys_cast.xml
index 5228085..de7ec9d 100644
--- a/packages/SystemUI/res/drawable/stat_sys_cast.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_cast.xml
@@ -15,14 +15,5 @@
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
-    <vector android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="17.0"
-            android:viewportHeight="17.0">
-
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M0.71,12.75v1.42c0,0.39 0.32,0.71 0.71,0.71h1.42C2.83,13.7 1.88,12.75 0.71,12.75zM0.69,10.67c-0.01,0.36 0.25,0.66 0.6,0.72c1.47,0.26 2.65,1.42 2.9,2.89c0.06,0.34 0.35,0.6 0.7,0.6c0.43,0 0.77,-0.38 0.71,-0.81c-0.34,-2.11 -2,-3.76 -4.11,-4.09C1.08,9.91 0.7,10.24 0.69,10.67zM13.46,4.96H3.54v1.15c2.81,0.91 5.02,3.12 5.93,5.93h3.99V4.96zM0.69,7.81C0.68,8.18 0.95,8.49 1.31,8.53c3.02,0.3 5.44,2.71 5.74,5.72c0.04,0.35 0.34,0.62 0.7,0.62c0.42,0 0.75,-0.36 0.71,-0.78c-0.37,-3.69 -3.3,-6.62 -6.99,-6.98C1.06,7.08 0.7,7.4 0.69,7.81zM14.88,2.12H2.12c-0.78,0 -1.42,0.64 -1.42,1.42v2.12h1.42V3.54h12.75v9.92H9.92v1.42h4.96c0.78,0 1.42,-0.64 1.42,-1.42V3.54C16.29,2.76 15.65,2.12 14.88,2.12z" />
-    </vector>
-</inset>
+    android:insetRight="2.5dp"
+    android:drawable="@drawable/ic_cast_connected" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
deleted file mode 100644
index 4dc0e4b..0000000
--- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17dp"
-        android:height="17dp"
-        android:viewportWidth="17.0"
-        android:viewportHeight="17.0">
-    <group
-        android:translateY="0.5"
-        android:translateX="0.5" >
-        <path
-            android:pathData="M8.84,8l2.62,-2.62c0.29,-0.29 0.29,-0.75 0,-1.04L8.33,1.22L8.31,1.2c-0.3,-0.28 -0.76,-0.26 -1.03,0.04c-0.13,0.13 -0.2,0.31 -0.2,0.5v4.51L4.24,3.4c-0.29,-0.29 -0.74,-0.29 -1.03,0s-0.29,0.74 0,1.03L6.78,8l-3.56,3.56c-0.29,0.29 -0.29,0.74 0,1.03s0.74,0.29 1.03,0l2.83,-2.83v4.51c0,0.4 0.33,0.73 0.73,0.73c0.18,0 0.36,-0.07 0.5,-0.2l0.03,-0.03l3.12,-3.12c0.29,-0.29 0.29,-0.75 0,-1.04L8.84,8zM8.47,6.37V3.36l1.5,1.5L8.47,6.37zM8.47,12.63V9.62l1.5,1.5L8.47,12.63z"
-            android:fillColor="#FFFFFF"/>
-    </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
index c8a4440..8d9e561 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected.xml
@@ -1,31 +1,17 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-**
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+Copyright (C) 2017 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="17dp"
-        android:height="17dp"
-        android:viewportWidth="18.0"
-        android:viewportHeight="18.0">
-    <group
-        android:translateY="0.5"
-        android:translateX="0.5" >
-        <path
-            android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
-            android:fillColor="#FFFFFF"/>
-    </group>
-</vector>
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_bluetooth_connected" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
index fed7cae..0223501 100644
--- a/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_data_saver.xml
@@ -18,26 +18,5 @@
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp" >
-    <vector
-        android:width="18dp"
-        android:height="18dp"
-        android:viewportWidth="19.0"
-        android:viewportHeight="19.0">
-        <group
-            android:translateX="1.0"
-            android:translateY="1.0">
-            <path
-                android:pathData="M11.5,8.5c0,0.41 -0.34,0.74 -0.74,0.74L9.24,9.24v1.5c0,0.41 -0.34,0.74 -0.74,0.74s-0.74,-0.34 -0.74,-0.74v-1.5h-1.5c-0.41,0 -0.74,-0.34 -0.74,-0.74s0.34,-0.74 0.74,-0.74h1.5v-1.5c0,-0.41 0.34,-0.74 0.74,-0.74s0.74,0.34 0.74,0.74v1.5h1.5c0.42,-0.01 0.76,0.33 0.76,0.74z"
-                android:fillColor="#FFF"/>
-            <path
-                android:pathData="M13.23,12.05l0.99,0.57c0.19,0.12 0.25,0.38 0.12,0.55A7.452,7.452 0,0 1,7.5 15.9c-3.29,-0.44 -5.96,-3.08 -6.41,-6.38 -0.57,-4.17 2.33,-7.8 6.23,-8.42 0.23,-0.04 0.44,0.15 0.44,0.37v1.15c0,0.18 -0.14,0.33 -0.31,0.37 -2.7,0.52 -4.71,2.96 -4.55,5.83 0.16,2.86 2.57,5.21 5.43,5.29 1.77,0.06 3.38,-0.72 4.44,-1.97 0.11,-0.14 0.31,-0.18 0.46,-0.09z"
-                android:fillColor="#FFF" />
-            <path
-                android:pathData="M14.11,8.5c0,0.62 -0.11,1.22 -0.29,1.78 -0.06,0.17 0.01,0.35 0.16,0.45l1,0.57c0.19,0.12 0.46,0.03 0.54,-0.18 0.3,-0.82 0.47,-1.7 0.47,-2.62 0,-3.73 -2.73,-6.82 -6.31,-7.39a0.377,0.377 0,0 0,-0.44 0.37v1.15c0,0.18 0.14,0.33 0.31,0.36 2.59,0.51 4.56,2.78 4.56,5.51z"
-                android:fillAlpha="0.3"
-                android:fillColor="#FFF" />
-
-        </group>
-    </vector>
-</inset>
+    android:insetRight="2.5dp"
+    android:drawable="@drawable/ic_data_saver" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd.xml b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
index 68a06d0..aa352b4 100644
--- a/packages/SystemUI/res/drawable/stat_sys_dnd.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
@@ -18,17 +18,5 @@
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp" >
-    <vector
-        android:width="17dp"
-        android:height="17dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,16.41 16.41,20 12,20z"/>
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M7,11h10v2h-10z"/>
-    </vector>
-</inset>
+    android:insetRight="2.5dp"
+    android:drawable="@*android:drawable/ic_qs_dnd" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_headset.xml b/packages/SystemUI/res/drawable/stat_sys_headset.xml
new file mode 100644
index 0000000..361c665
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_headset.xml
@@ -0,0 +1,19 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp"
+    android:drawable="@drawable/ic_headset" />
diff --git a/packages/SystemUI/res/drawable/stat_sys_headset_mic.xml b/packages/SystemUI/res/drawable/stat_sys_headset_mic.xml
new file mode 100644
index 0000000..b424caa
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_headset_mic.xml
@@ -0,0 +1,19 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp"
+    android:drawable="@drawable/ic_headset_mic" />
diff --git a/packages/SystemUI/res/drawable/stat_sys_hotspot.xml b/packages/SystemUI/res/drawable/stat_sys_hotspot.xml
index 4f52777..361b00a 100644
--- a/packages/SystemUI/res/drawable/stat_sys_hotspot.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_hotspot.xml
@@ -15,18 +15,5 @@
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
-    <vector
-        android:width="18.0dp"
-        android:height="18.0dp"
-        android:viewportWidth="18.0"
-        android:viewportHeight="18.0">
-      <group
-          android:translateX="0.5"
-          android:translateY="0.5" >
-          <path
-              android:pathData="M8.5,7.79c-0.78,0 -1.42,0.64 -1.42,1.42c0,0.78 0.64,1.42 1.42,1.42s1.42,-0.64 1.42,-1.42C9.92,8.43 9.28,7.79 8.5,7.79zM12.75,9.21c0,-2.35 -1.9,-4.25 -4.25,-4.25c-0.18,0 -0.35,0.01 -0.53,0.03C6.11,5.22 4.58,6.7 4.3,8.55c-0.23,1.52 0.35,2.91 1.36,3.82C6,12.67 6.54,12.6 6.76,12.2c0.17,-0.3 0.1,-0.67 -0.16,-0.89c-0.78,-0.7 -1.12,-1.77 -0.86,-2.79C5.99,7.5 6.78,6.71 7.8,6.46C9.32,6.08 10.86,7 11.25,8.52c0.06,0.23 0.09,0.46 0.09,0.69c0,0.84 -0.36,1.58 -0.94,2.1c-0.25,0.23 -0.33,0.6 -0.16,0.9c0.22,0.38 0.74,0.49 1.06,0.2C12.22,11.6 12.75,10.43 12.75,9.21zM7.63,1.85C4.19,2.24 1.42,5.07 1.1,8.52c-0.26,2.61 0.88,5.15 2.99,6.7c0.36,0.26 0.86,0.15 1.09,-0.23c0.19,-0.32 0.1,-0.74 -0.19,-0.96c-1.7,-1.26 -2.71,-3.38 -2.35,-5.73c0.4,-2.6 2.57,-4.68 5.19,-4.97c3.59,-0.41 6.63,2.4 6.63,5.91c0,1.97 -0.96,3.7 -2.43,4.79c-0.3,0.22 -0.38,0.63 -0.19,0.96c0.22,0.39 0.73,0.49 1.09,0.23c1.9,-1.4 3.03,-3.62 3.03,-5.98C15.94,4.84 12.12,1.34 7.63,1.85z"
-              android:fillColor="#FFFFFFFF"/>
-      </group>
-    </vector>
-</inset>
+    android:insetRight="2.5dp"
+    android:drawable="@drawable/ic_hotspot" />
diff --git a/packages/SystemUI/res/drawable/stat_sys_location.xml b/packages/SystemUI/res/drawable/stat_sys_location.xml
index bdb0b0c..7a5aeb9 100644
--- a/packages/SystemUI/res/drawable/stat_sys_location.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_location.xml
@@ -14,18 +14,6 @@
   ~ limitations under the License
   -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="1.5dp"
-    android:insetRight="1.5dp">
-        <vector
-            android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="24.0"
-            android:viewportHeight="24.0">
-                <path
-                    android:fillColor="#FFFFFFFF"
-                    android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
-                <path
-                    android:fillColor="#FFFFFFFF"
-                    android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
-        </vector>
-</inset>
\ No newline at end of file
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp"
+    android:drawable="@drawable/ic_location" />
diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
index 0b72f75..21a4c17 100644
--- a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
@@ -1,36 +1,19 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-**
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
 <inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
-    <vector
-        android:width="19dp"
-        android:height="19dp"
-        android:viewportWidth="23.0"
-        android:viewportHeight="23.0">
-        <group
-            android:translateX="-0.5"
-            android:translateY="-0.5">
-            <path
-                android:fillColor="#F00"
-                android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/>
-
-        </group>
-    </vector>
-</inset>
+    android:insetRight="2.5dp"
+    android:drawable="@drawable/ic_volume_ringer_vibrate" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_zen_important.xml b/packages/SystemUI/res/drawable/stat_sys_zen_important.xml
deleted file mode 100644
index 1262617..0000000
--- a/packages/SystemUI/res/drawable/stat_sys_zen_important.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
-    <vector android:width="18dp"
-            android:height="18dp"
-            android:viewportWidth="24.0"
-            android:viewportHeight="24.0">
-
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M12.0,17.273l6.1800003,3.7269993 -1.6350002,-7.0290003 5.455,-4.7269993 -7.191,-0.6170006 -2.809,-6.627 -2.809,6.627 -7.191,0.6170006 5.455,4.7269993 -1.6349998,7.0290003z"/>
-    </vector>
-</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_zen_none.xml b/packages/SystemUI/res/drawable/stat_sys_zen_none.xml
deleted file mode 100644
index 92914a8..0000000
--- a/packages/SystemUI/res/drawable/stat_sys_zen_none.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:insetLeft="2.5dp"
-    android:insetRight="2.5dp">
-    <vector android:width="17dp"
-            android:height="17dp"
-            android:viewportWidth="48.0"
-            android:viewportHeight="48.0">
-
-        <path
-            android:fillColor="#FFFFFFFF"
-            android:pathData="M24.0,4.0C13.0,4.0 4.0,13.0 4.0,24.0c0.0,11.0 9.0,20.0 20.0,20.0c11.0,0.0 20.0,-9.0 20.0,-20.0C44.0,13.0 35.0,4.0 24.0,4.0zM24.0,40.0c-8.8,0.0 -16.0,-7.2 -16.0,-16.0c0.0,-3.7 1.3,-7.1 3.4,-9.8l22.4,22.4C31.1,38.7 27.7,40.0 24.0,40.0zM36.6,33.8L14.2,11.4C16.9,9.3 20.3,8.0 24.0,8.0c8.8,0.0 16.0,7.2 16.0,16.0C40.0,27.7 38.7,31.1 36.6,33.8z"/>
-    </vector>
-</inset>
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_0.xml
deleted file mode 100644
index 5009c6b..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_0.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 0.144628099174,0.0 l 0.855371900826,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_1.xml
deleted file mode 100644
index 678b90b..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_1.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 0.534759358289,0.0 l 0.465240641711,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_2.xml
deleted file mode 100644
index 6c6df60..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_2.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.313385868073,0.330828523695 0.125984191895,0.661170632677 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_3.xml
deleted file mode 100644
index b1eec48..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_3.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.0 0.2,0.2 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_4.xml
deleted file mode 100644
index 17ff65a..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_4.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.4 0.2,0.2 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_5.xml
deleted file mode 100644
index aee48dc..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_animation_interpolator_5.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.66666667,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_0.xml
deleted file mode 100644
index 4a5fde9..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_0.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.33333333,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_1.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_1.xml
deleted file mode 100644
index 0f35e5d..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_1.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.714960628748,0.0 0.678740215302,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_2.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_2.xml
deleted file mode 100644
index 626f9ef..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_2.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 0.392038600724,0.0 l 0.607961399276,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_3.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_3.xml
deleted file mode 100644
index 17ff65a..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_3.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.4,0.4 0.2,0.2 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_4.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_4.xml
deleted file mode 100644
index 96bdb48..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_4.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 l 0.337078651685,0.0 l 0.662921348315,1.0 L 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_5.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_5.xml
deleted file mode 100644
index a91610d..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_animation_interpolator_5.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.66666667,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
deleted file mode 100644
index a0118d70..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
deleted file mode 100644
index 1820bab..0000000
--- a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:pathData="M 0,0 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml
index c1e74ef..c420117 100644
--- a/packages/SystemUI/res/layout-land/volume_dialog.xml
+++ b/packages/SystemUI/res/layout-land/volume_dialog.xml
@@ -15,6 +15,7 @@
   -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:sysui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/volume_dialog_container"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
@@ -53,6 +54,8 @@
                 android:background="@drawable/rounded_ripple"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
+                android:scaleType="fitCenter"
+                android:padding="@dimen/volume_dialog_ringer_icon_padding"
                 android:tint="@color/accent_tint_color_selector"
                 android:layout_gravity="center"
                 android:soundEffectsEnabled="false" />
@@ -116,16 +119,17 @@
             android:clipToPadding="false"
             android:translationZ="@dimen/volume_dialog_elevation"
             android:background="@drawable/rounded_bg_full">
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.systemui.volume.CaptionsToggleImageButton
                 android:id="@+id/odi_captions_icon"
                 android:src="@drawable/ic_volume_odi_captions_disabled"
                 style="@style/VolumeButtons"
                 android:background="@drawable/rounded_ripple"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:tint="@color/accent_tint_color_selector"
+                android:tint="@color/caption_tint_color_selector"
                 android:layout_gravity="center"
-                android:soundEffectsEnabled="false" />
+                android:soundEffectsEnabled="false"
+                sysui:optedOut="false"/>
         </FrameLayout>
 
         <ViewStub
diff --git a/packages/SystemUI/res/layout/biometric_dialog.xml b/packages/SystemUI/res/layout/biometric_dialog.xml
index 8f7a45f..c452855 100644
--- a/packages/SystemUI/res/layout/biometric_dialog.xml
+++ b/packages/SystemUI/res/layout/biometric_dialog.xml
@@ -76,10 +76,6 @@
                             android:layout_marginTop="24dp"
                             android:gravity="@integer/biometric_dialog_text_gravity"
                             android:textSize="20sp"
-                            android:maxLines="1"
-                            android:singleLine="true"
-                            android:ellipsize="marquee"
-                            android:marqueeRepeatLimit="marquee_forever"
                             android:textColor="?android:attr/textColorPrimary"/>
 
                         <TextView
@@ -91,10 +87,6 @@
                             android:layout_marginEnd="24dp"
                             android:gravity="@integer/biometric_dialog_text_gravity"
                             android:textSize="16sp"
-                            android:maxLines="1"
-                            android:singleLine="true"
-                            android:ellipsize="marquee"
-                            android:marqueeRepeatLimit="marquee_forever"
                             android:textColor="?android:attr/textColorPrimary"/>
 
                         <TextView
@@ -106,7 +98,6 @@
                             android:gravity="@integer/biometric_dialog_text_gravity"
                             android:paddingTop="8dp"
                             android:textSize="16sp"
-                            android:maxLines="4"
                             android:textColor="?android:attr/textColorPrimary"/>
 
                         <ImageView
diff --git a/packages/SystemUI/res/layout/bubble_expanded_view.xml b/packages/SystemUI/res/layout/bubble_expanded_view.xml
index 56a3cd5..bdc4ebd 100644
--- a/packages/SystemUI/res/layout/bubble_expanded_view.xml
+++ b/packages/SystemUI/res/layout/bubble_expanded_view.xml
@@ -33,35 +33,13 @@
         android:layout_height="wrap_content"
         android:animateLayoutChanges="true">
 
-        <LinearLayout
-            android:id="@+id/header_layout"
-            android:layout_height="@dimen/bubble_expanded_header_height"
-            android:layout_width="match_parent"
-            android:animateLayoutChanges="true"
-            android:gravity="end|center_vertical"
-            android:orientation="horizontal">
-
-            <ImageButton
-                android:id="@+id/deep_link_button"
-                android:layout_width="@dimen/bubble_header_icon_size"
-                android:layout_height="@dimen/bubble_header_icon_size"
-                android:src="@drawable/ic_open_in_new"
-                android:scaleType="center"
-                android:tint="?android:attr/colorForeground"
-                android:background="?android:attr/selectableItemBackground"
-            />
-
-            <ImageButton
-                android:id="@id/settings_button"
-                android:layout_width="@dimen/bubble_header_icon_size"
-                android:layout_height="@dimen/bubble_header_icon_size"
-                android:src="@drawable/ic_settings"
-                android:scaleType="center"
-                android:tint="?android:attr/colorForeground"
-                android:background="?android:attr/selectableItemBackground"
-            />
-
-        </LinearLayout>
+        <ImageView
+            android:id="@+id/settings_button"
+            android:layout_width="@dimen/bubble_header_icon_size"
+            android:layout_height="@dimen/bubble_header_icon_size"
+            android:src="@drawable/ic_settings"
+            android:scaleType="center"
+            android:layout_gravity="end"/>
 
         <include layout="@layout/bubble_permission_view"
                  android:id="@+id/permission_layout"
diff --git a/packages/SystemUI/res/layout/bubble_flyout.xml b/packages/SystemUI/res/layout/bubble_flyout.xml
new file mode 100644
index 0000000..74c6c12
--- /dev/null
+++ b/packages/SystemUI/res/layout/bubble_flyout.xml
@@ -0,0 +1,33 @@
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/bubble_flyout"
+    android:layout_height="wrap_content"
+    android:layout_width="wrap_content"
+    android:background="@drawable/bubble_flyout"
+    android:padding="@dimen/bubble_flyout_padding"
+    android:translationZ="@dimen/bubble_flyout_elevation">
+
+    <TextView
+        android:id="@+id/bubble_flyout_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:maxLines="2"
+        android:maxWidth="@dimen/bubble_flyout_maxwidth"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title" />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/bubble_view.xml b/packages/SystemUI/res/layout/bubble_view.xml
index 13186fc..a8eb2914 100644
--- a/packages/SystemUI/res/layout/bubble_view.xml
+++ b/packages/SystemUI/res/layout/bubble_view.xml
@@ -27,12 +27,4 @@
         android:padding="@dimen/bubble_view_padding"
         android:clipToPadding="false"/>
 
-    <TextView
-        android:id="@+id/message_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:minWidth="@dimen/bubble_message_min_width"
-        android:maxWidth="@dimen/bubble_message_max_width"
-        android:padding="@dimen/bubble_message_padding"/>
-
 </com.android.systemui.bubbles.BubbleView>
diff --git a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
index d49aff9..3786812 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
@@ -39,7 +39,7 @@
             android:layout_height="wrap_content"
             android:paddingEnd="12dp"
             android:paddingBottom="4dp"
-            android:textColor="@color/ksh_keyword_color"
+            android:textColor="?android:attr/textColorPrimary"
             android:textSize="16sp"
             android:maxLines="5"
             android:singleLine="false"
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index adc0b41..636b929 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -77,15 +77,20 @@
         android:contentDescription="@string/accessibility_phone_button"
         android:tint="?attr/wallpaperTextColor" />
 
-    <com.android.systemui.statusbar.phone.LockIcon
-        android:id="@+id/lock_icon"
+    <FrameLayout
+        android:id="@+id/lock_icon_container"
         android:layout_width="@dimen/keyguard_lock_width"
         android:layout_height="@dimen/keyguard_lock_height"
         android:layout_gravity="bottom|center_horizontal"
-        android:layout_marginBottom="@dimen/keyguard_lock_padding"
-        android:src="@*android:drawable/ic_lock"
-        android:contentDescription="@string/accessibility_unlock_button"
-        android:scaleType="center" />
+        android:layout_marginBottom="@dimen/keyguard_lock_padding">
+        <com.android.systemui.statusbar.phone.LockIcon
+            android:id="@+id/lock_icon"
+            android:layout_width="@dimen/keyguard_lock_width"
+            android:layout_height="@dimen/keyguard_lock_height"
+            android:src="@*android:drawable/ic_lock"
+            android:contentDescription="@string/accessibility_unlock_button"
+            android:scaleType="center" />
+    </FrameLayout>
 
     <FrameLayout
         android:id="@+id/overlay_container"
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_dialog_content.xml b/packages/SystemUI/res/layout/ongoing_privacy_dialog_content.xml
deleted file mode 100644
index 665fc3f..0000000
--- a/packages/SystemUI/res/layout/ongoing_privacy_dialog_content.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-            android:id="@+id/container"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:fillViewport ="true"
-            android:orientation="vertical">
-
-    <LinearLayout
-        android:id="@+id/dialog_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical" >
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            android:textDirection="locale"
-            android:textAppearance="@style/TextAppearance.AppOpsDialog.Title"
-            android:textColor="@*android:color/text_color_primary"
-            android:layout_marginStart="@dimen/ongoing_appops_dialog_title_margin_sides"
-            android:layout_marginEnd="@dimen/ongoing_appops_dialog_title_margin_sides"
-            android:layout_marginBottom="@dimen/ongoing_appops_dialog_title_margin_top_bottom"
-            android:layout_marginTop="@dimen/ongoing_appops_dialog_title_margin_top_bottom"
-        />
-
-        <LinearLayout
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginBottom="@dimen/ongoing_appops_dialog_items_bottom_margin" >
-
-            <LinearLayout
-                android:id="@+id/items_container"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:gravity="start"
-            />
-        </LinearLayout>
-
-    </LinearLayout>
-
-</ScrollView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_dialog_item.xml b/packages/SystemUI/res/layout/ongoing_privacy_dialog_item.xml
deleted file mode 100644
index c8e0845..0000000
--- a/packages/SystemUI/res/layout/ongoing_privacy_dialog_item.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/ongoing_appops_dialog_line_height"
-    android:layout_marginStart="@dimen/ongoing_appops_dialog_text_padding"
-    android:layout_marginEnd="@dimen/ongoing_appops_dialog_text_padding"
-    android:fillViewport="true"
-    android:orientation="horizontal"
-    android:focusable="true"
-    android:layout_gravity="center_vertical">
-
-    <FrameLayout
-        android:layout_height="@dimen/ongoing_appops_dialog_app_icon_size"
-        android:layout_width="@dimen/ongoing_appops_dialog_app_icon_size"
-        android:layout_gravity="start|center_vertical">
-
-        <ImageView
-            android:id="@+id/app_icon"
-            android:layout_height="@dimen/ongoing_appops_dialog_app_icon_size"
-            android:layout_width="@dimen/ongoing_appops_dialog_app_icon_size"
-            android:layout_gravity="center"
-            />
-    </FrameLayout>
-
-    <TextView
-        android:id="@+id/app_name"
-        android:layout_height="match_parent"
-        android:layout_width="0dp"
-        android:layout_weight="1"
-        android:gravity="start|center_vertical"
-        android:textDirection="locale"
-        android:textAppearance="@style/TextAppearance.AppOpsDialog.Item"
-        android:textColor="@*android:color/text_color_primary"
-        android:layout_marginStart="@dimen/ongoing_appops_dialog_text_padding"
-    />
-
-    <LinearLayout
-        android:id="@+id/icons"
-        android:layout_height="match_parent"
-        android:layout_width="wrap_content"
-        android:gravity="end"
-        android:layout_gravity="end|center_vertical"
-        android:visibility="gone"
-    />
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index 2efae71..2867224 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -22,16 +22,6 @@
     android:paddingRight="16dp"
     style="@style/BrightnessDialogContainer">
 
-    <ImageView
-        android:id="@+id/brightness_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:layout_marginEnd="8dp"
-        android:src="@drawable/ic_qs_brightness_auto_off"
-        android:contentDescription="@null"
-        android:visibility="gone" />
-
     <com.android.systemui.settings.ToggleSliderView
         android:id="@+id/brightness_slider"
         android:layout_width="0dp"
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index d1c80c4..a90b1eb 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -56,6 +56,8 @@
                 android:background="@drawable/rounded_ripple"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
+                android:scaleType="fitCenter"
+                android:padding="@dimen/volume_dialog_ringer_icon_padding"
                 android:tint="@color/accent_tint_color_selector"
                 android:layout_gravity="center"
                 android:soundEffectsEnabled="false" />
diff --git a/packages/SystemUI/res/layout/volume_dnd_icon.xml b/packages/SystemUI/res/layout/volume_dnd_icon.xml
index 037d143..10c1472 100644
--- a/packages/SystemUI/res/layout/volume_dnd_icon.xml
+++ b/packages/SystemUI/res/layout/volume_dnd_icon.xml
@@ -24,6 +24,6 @@
         android:layout_width="14dp"
         android:layout_height="14dp"
         android:layout_gravity="right|top"
-        android:src="@drawable/ic_dnd"
+        android:src="@*android:drawable/ic_qs_dnd"
         android:tint="?android:attr/textColorTertiary"/>
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index b82c250..290d75b 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -129,7 +129,6 @@
 
     <!-- Keyboard shortcuts colors -->
     <color name="ksh_application_group_color">#fff44336</color>
-    <color name="ksh_keyword_color">#d9000000</color>
     <color name="ksh_key_item_color">@color/material_grey_600</color>
     <color name="ksh_key_item_background">@color/material_grey_100</color>
 
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index f8295eb..b0afe75 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -109,12 +109,12 @@
 
     <!-- The default tiles to display in QuickSettings -->
     <string name="quick_settings_tiles_default" translatable="false">
-        wifi,bt,dnd,flashlight,rotation,battery,cell,airplane,cast,sensorprivacy
+        wifi,bt,dnd,flashlight,rotation,battery,cell,airplane,cast
     </string>
 
     <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
     <string name="quick_settings_tiles_stock" translatable="false">
-        wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,work,cast,night,sensorprivacy
+        wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,work,cast,night
     </string>
 
     <!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/config_car.xml b/packages/SystemUI/res/values/config_car.xml
deleted file mode 100644
index 2c549bc..0000000
--- a/packages/SystemUI/res/values/config_car.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2016, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<resources>
-    <!-- These next two work together, if you enable this first one you need to provide an intent
-         uri that will be launched into the docked window. -->
-    <bool name="config_enablePersistentDockedActivity">false</bool>
-    <string name="config_persistentDockedActivityIntentUri" translatable="false"></string>
-
-    <!-- configure which system ui bars should be displayed -->
-    <bool name="config_enableLeftNavigationBar">false</bool>
-    <bool name="config_enableRightNavigationBar">false</bool>
-    <bool name="config_enableBottomNavigationBar">true</bool>
-    <bool name="config_hideNavWhenKeyguardBouncerShown">true</bool>
-</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1da1405..bea0365 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -23,8 +23,6 @@
     <dimen name="navigation_bar_size">@*android:dimen/navigation_bar_height</dimen>
     <!-- Minimum swipe distance to catch the swipe gestures to invoke assist or switch tasks. -->
     <dimen name="navigation_bar_min_swipe_distance">48dp</dimen>
-    <!-- The default distance from a side of the device to start an edge swipe from -->
-    <dimen name="navigation_bar_default_edge_width">48dp</dimen>
     <dimen name="navigation_bar_default_edge_height">500dp</dimen>
 
     <!-- thickness (height) of the dead zone at the top of the navigation bar,
@@ -37,7 +35,21 @@
     <dimen name="navigation_handle_radius">1dp</dimen>
     <dimen name="navigation_handle_bottom">6dp</dimen>
     <dimen name="navigation_handle_horizontal_margin">30dp</dimen>
-    <dimen name="navigation_home_handle_width">280dp</dimen>
+    <dimen name="navigation_handle_sample_horizontal_margin">10dp</dimen>
+    <dimen name="navigation_home_handle_width">72dp</dimen>
+
+
+    <!-- Size of the nav bar edge panels, should be greater to the
+         edge sensitivity + the drag threshold -->
+    <dimen name="navigation_edge_panel_width">52dp</dimen>
+    <dimen name="navigation_edge_panel_height">52dp</dimen>
+    <!-- The threshold to drag to trigger the edge action -->
+    <dimen name="navigation_edge_action_drag_threshold">16dp</dimen>
+
+    <!-- Luminance threshold to determine black/white contrast for the navigation affordances -->
+    <item name="navigation_luminance_threshold" type="dimen" format="float">0.5</item>
+    <!-- Luminance change threshold that allows applying new value if difference was exceeded -->
+    <item name="navigation_luminance_change_threshold" type="dimen" format="float">0.05</item>
 
     <!-- Height of notification icons in the status bar -->
     <dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
@@ -335,6 +347,8 @@
 
     <dimen name="volume_dialog_ringer_size">64dp</dimen>
 
+    <dimen name="volume_dialog_ringer_icon_padding">20dp</dimen>
+
     <dimen name="volume_dialog_caption_size">64dp</dimen>
 
     <dimen name="volume_dialog_tap_target_size">48dp</dimen>
@@ -977,10 +991,6 @@
     <!-- How much into a DisplayCutout's bounds we can go, on each side -->
     <dimen name="display_cutout_margin_consumption">0px</dimen>
 
-    <!-- How much we expand the touchable region of the status bar below the notch to catch touches
-         that just start below the notch. -->
-    <dimen name="display_cutout_touchable_region_size">12dp</dimen>
-
     <!-- Padding below Ongoing App Ops dialog title -->
     <dimen name="ongoing_appops_dialog_sep">16dp</dimen>
     <!--Padding around text items in Ongoing App Ops dialog -->
@@ -1023,8 +1033,14 @@
     <dimen name="ongoing_appops_chip_bg_corner_radius">16dp</dimen>
 
 
-    <!-- How much a bubble is elevated -->
-    <dimen name="bubble_elevation">8dp</dimen>
+    <!-- How much each bubble is elevated. -->
+    <dimen name="bubble_elevation">1dp</dimen>
+    <!-- How much the bubble flyout text container is elevated. -->
+    <dimen name="bubble_flyout_elevation">4dp</dimen>
+    <!-- How much padding is around the flyout text. -->
+    <dimen name="bubble_flyout_padding">16dp</dimen>
+    <!-- The maximum width of a bubble flyout. -->
+    <dimen name="bubble_flyout_maxwidth">200dp</dimen>
     <!-- Padding around a collapsed bubble -->
     <dimen name="bubble_view_padding">0dp</dimen>
     <!-- Padding between bubbles when displayed in expanded state -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index aca99e3..cd286fc 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -79,6 +79,9 @@
     <!-- Battery saver confirmation dialog title [CHAR LIMIT=NONE]-->
     <string name="battery_saver_confirmation_title">Turn on Battery Saver?</string>
 
+    <!-- The more generic version of the battery saver confirmation dialog title [CHAR LIMIT=NONE] -->
+    <string name="battery_saver_confirmation_title_generic">About Battery Saver</string>
+
     <!-- Battery saver confirmation dialog ok text [CHAR LIMIT=40]-->
     <string name="battery_saver_confirmation_ok">Turn on</string>
 
@@ -667,6 +670,9 @@
         <item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> more notifications inside.</item>
     </plurals>
 
+    <!-- Format to use to summarize a message from a contact in a single line of text. For example: "Julia: How's it going?". [CHAR LIMIT=NONE] -->
+    <string name="notification_summary_message_format"><xliff:g id="contact_name" example="Julia">%1$s</xliff:g>: <xliff:g id="message_content" example="How is it going?">%2$s</xliff:g></string>
+
     <!-- Content description of button in notification inspector for system settings relating to
          notifications from this application [CHAR LIMIT=NONE] -->
     <string name="status_bar_notification_inspect_item_title">Notification settings</string>
@@ -2234,6 +2240,9 @@
     <!-- Quick settings tile secondary label format combining roaming with the mobile data type. [CHAR LIMIT=NONE] -->
     <string name="mobile_data_text_format"><xliff:g name="roaming_status" example="Roaming">%1$s</xliff:g> \u2014 <xliff:g name="mobile_data_type" example="LTE">%2$s</xliff:g></string>
 
+    <!-- Quick settings tile secondary label format combining carrier name with the mobile data tye. [CHAR LIMIT=NONE] -->
+    <string name="mobile_carrier_text_format"><xliff:g id="carrier_name" example="Test">%1$s</xliff:g>, <xliff:g id="mobile_data_type" example="LTE">%2$s</xliff:g></string>
+
     <!-- Label for when wifi is off in QS detail panel [CHAR LIMIT=NONE] -->
     <string name="wifi_is_off">Wi-Fi is off</string>
 
@@ -2339,18 +2348,6 @@
     <!-- Content description for ongoing privacy chip. Use with multiple apps [CHAR LIMIT=NONE]-->
     <string name="ongoing_privacy_chip_content_multiple_apps">Applications are using your <xliff:g id="types_list" example="camera, location">%s</xliff:g>.</string>
 
-    <!-- Action for accepting the Ongoing privacy dialog [CHAR LIMIT=10]-->
-    <string name="ongoing_privacy_dialog_ok">Got it</string>
-
-    <!-- Action on Ongoing Privacy Dialog to open privacy hub [CHAR LIMIT=23]-->
-    <string name="ongoing_privacy_dialog_open_settings">Privacy settings</string>
-
-    <!-- Text for item in Ongoing Privacy Dialog title when only one app is using app ops [CHAR LIMIT=NONE] -->
-    <string name="ongoing_privacy_dialog_single_app_title">App using your <xliff:g id="types_list" example="camera( and location)">%s</xliff:g></string>
-
-    <!-- Text for item in Ongoing Privacy Dialog title when multiple apps is using app ops [CHAR LIMIT=NONE] -->
-    <string name="ongoing_privacy_dialog_multiple_apps_title">Apps using your <xliff:g id="types_list" example="camera( and location)">%s</xliff:g></string>
-
     <!-- Separator for types. Include spaces before and after if needed [CHAR LIMIT=10] -->
     <string name="ongoing_privacy_dialog_separator">,\u0020</string>
 
@@ -2407,5 +2404,4 @@
     <string name="bubble_accessibility_action_move_bottom_left">Move bottom left</string>
     <!-- Action in accessibility menu to move the stack of bubbles to the bottom right of the screen. [CHAR LIMIT=30]-->
     <string name="bubble_accessibility_action_move_bottom_right">Move bottom right</string>
-
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index a6a6e6b..7c123ef 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -316,6 +316,7 @@
     <style name="qs_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
         <item name="lightIconTheme">@style/QSIconTheme</item>
         <item name="darkIconTheme">@style/QSIconTheme</item>
+        <item name="android:colorError">@*android:color/error_color_material_dark</item>
         <item name="android:windowIsFloating">true</item>
     </style>
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
index ce615b6..0075327 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
@@ -119,4 +119,8 @@
      */
     void onAssistantAvailable(boolean available) = 13;
 
+    /**
+     * Sent when the assistant changes how visible it is to the user.
+     */
+    void onAssistantVisibilityChanged(float visibility) = 14;
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index 953816e..5764fe8 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -92,4 +92,9 @@
      * Start the assistant.
      */
     void startAssistant(in Bundle bundle) = 13;
+
+    /**
+     * Creates a new gesture monitor
+     */
+    Bundle monitorGestureInput(String name, int displayId) = 14;
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputMonitorCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputMonitorCompat.java
new file mode 100644
index 0000000..ddca723
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputMonitorCompat.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.shared.system;
+
+import android.os.Bundle;
+import android.os.Looper;
+import android.view.Choreographer;
+import android.view.InputMonitor;
+
+import com.android.systemui.shared.system.InputChannelCompat.InputEventListener;
+import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
+
+/**
+ * @see android.view.InputMonitor
+ */
+public class InputMonitorCompat {
+
+    private final InputMonitor mInputMonitor;
+
+    private InputMonitorCompat(InputMonitor monitor) {
+        mInputMonitor = monitor;
+    }
+
+    /**
+     * @see InputMonitor#pilferPointers()
+     */
+    public void pilferPointers() {
+        mInputMonitor.pilferPointers();
+    }
+
+    /**
+     * @see InputMonitor#dispose()
+     */
+    public void dispose() {
+        mInputMonitor.dispose();
+    }
+
+    /**
+     * @see InputMonitor#getInputChannel()
+     */
+    public InputEventReceiver getInputReceiver(Looper looper, Choreographer choreographer,
+            InputEventListener listener) {
+        return new InputEventReceiver(mInputMonitor.getInputChannel(), looper, choreographer,
+                listener);
+    }
+
+    /**
+     * Gets the input monitor stored in a bundle
+     */
+    public static InputMonitorCompat fromBundle(Bundle bundle, String key) {
+        return new InputMonitorCompat((InputMonitor) bundle.getParcelable(key));
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index 46f4c86..1076e73 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -24,6 +24,8 @@
 import android.content.res.Resources;
 import android.view.WindowManagerPolicyConstants;
 
+import com.android.internal.policy.ScreenDecorationsUtils;
+
 /**
  * Various shared constants between Launcher and SysUI as part of quickstep
  */
@@ -31,6 +33,7 @@
 
     public static final String KEY_EXTRA_SYSUI_PROXY = "extra_sysui_proxy";
     public static final String KEY_EXTRA_INPUT_CHANNEL = "extra_input_channel";
+    public static final String KEY_EXTRA_INPUT_MONITOR = "extra_input_monitor";
     public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius";
     public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners";
 
@@ -112,4 +115,36 @@
         return context.getResources().getInteger(
                 com.android.internal.R.integer.config_navBarInteractionMode);
     }
+
+    /**
+     * @return {@code true} if the navbar can be clicked through
+     */
+    public static boolean isNavBarClickThrough(Context context) {
+        return context.getResources().getBoolean(
+                com.android.internal.R.bool.config_navBarTapThrough);
+    }
+
+    /**
+     * @return the edge sensitivity width in px
+     */
+    public static int getEdgeSensitivityWidth(Context context) {
+        return context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.config_backGestureInset);
+    }
+
+    /**
+     * Corner radius that should be used on windows in order to cover the display.
+     * These values are expressed in pixels because they should not respect display or font
+     * scaling, this means that we don't have to reload them on config changes.
+     */
+    public static float getWindowCornerRadius(Resources resources) {
+        return ScreenDecorationsUtils.getWindowCornerRadius(resources);
+    }
+
+    /**
+     * If live rounded corners are supported on windows.
+     */
+    public static boolean supportsRoundedCornersOnWindows(Resources resources) {
+        return ScreenDecorationsUtils.supportsRoundedCornersOnWindows(resources);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index fd92e9e..b738b57 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -187,6 +187,7 @@
                 mBigClockContainer.removeAllViews();
                 updateBigClockVisibility();
             }
+            mClockPlugin.onDestroyView();
             mClockPlugin = null;
         }
         if (plugin == null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index c0ec405..fb4fe81 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -99,13 +99,7 @@
         esimButton.setVisibility(isEsimLocked ? View.VISIBLE : View.GONE);
     }
 
-    private void showDefaultMessage() {
-        if (mRemainingAttempts >= 0) {
-            mSecurityMessageDisplay.setMessage(getPinPasswordErrorMessage(
-                    mRemainingAttempts, true));
-            return;
-        }
-
+    private void setLockedSimMessage() {
         boolean isEsimLocked = KeyguardEsimArea.isEsimLocked(mContext, mSubId);
         int count = TelephonyManager.getDefault().getSimCount();
         Resources rez = getResources();
@@ -122,13 +116,20 @@
                 color = info.getIconTint();
             }
         }
-
         if (isEsimLocked) {
             msg = rez.getString(R.string.kg_sim_lock_esim_instructions, msg);
         }
 
         mSecurityMessageDisplay.setMessage(msg);
         mSimImageView.setImageTintList(ColorStateList.valueOf(color));
+    }
+
+    private void showDefaultMessage() {
+        setLockedSimMessage();
+        if (mRemainingAttempts >= 0) {
+            return;
+        }
+
 
         // Sending empty PIN here to query the number of remaining PIN attempts
         new CheckSimPin("", mSubId) {
@@ -137,8 +138,7 @@
                         " attemptsRemaining=" + attemptsRemaining);
                 if (attemptsRemaining >= 0) {
                     mRemainingAttempts = attemptsRemaining;
-                    mSecurityMessageDisplay.setMessage(
-                            getPinPasswordErrorMessage(attemptsRemaining, true));
+                    setLockedSimMessage();
                 }
             }
         }.start();
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index 32c1242..d30f45f 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -15,15 +15,19 @@
  */
 package com.android.keyguard.clock;
 
+import android.app.WallpaperManager;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Color;
 import android.graphics.Paint.Style;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.TextClock;
 
+import com.android.internal.colorextraction.ColorExtractor;
 import com.android.keyguard.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ClockPlugin;
 
 import java.util.TimeZone;
@@ -44,6 +48,16 @@
     private final LayoutInflater mLayoutInflater;
 
     /**
+     * Extracts accent color from wallpaper.
+     */
+    private final SysuiColorExtractor mColorExtractor;
+
+    /**
+     * Renders preview from clock view.
+     */
+    private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+    /**
      * Custom clock shown on AOD screen and behind stack scroller on lock.
      */
     private View mView;
@@ -64,11 +78,15 @@
     /**
      * Create a BubbleClockController instance.
      *
-     * @param layoutInflater Inflater used to inflate custom clock views.
+     * @param res Resources contains title and thumbnail.
+     * @param inflater Inflater used to inflate custom clock views.
+     * @param colorExtractor Extracts accent color from wallpaper.
      */
-    public BubbleClockController(Resources res, LayoutInflater inflater) {
+    public BubbleClockController(Resources res, LayoutInflater inflater,
+            SysuiColorExtractor colorExtractor) {
         mResources = res;
         mLayoutInflater = inflater;
+        mColorExtractor = colorExtractor;
     }
 
     private void createViews() {
@@ -84,6 +102,16 @@
     }
 
     @Override
+    public void onDestroyView() {
+        mView = null;
+        mDigitalClock = null;
+        mAnalogClock = null;
+        mLockClockContainer = null;
+        mLockClock = null;
+        mDarkController = null;
+    }
+
+    @Override
     public String getName() {
         return "bubble";
     }
@@ -99,6 +127,23 @@
     }
 
     @Override
+    public Bitmap getPreview(int width, int height) {
+
+        // Use the big clock view for the preview
+        View view = getBigClockView();
+
+        // Initialize state of plugin before generating preview.
+        setDarkAmount(1f);
+        setTextColor(Color.WHITE);
+        ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+                WallpaperManager.FLAG_LOCK, true);
+        setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+        onTimeTick();
+
+        return mRenderer.createPreview(view, width, height);
+    }
+
+    @Override
     public View getView() {
         if (mLockClockContainer == null) {
             createViews();
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
index 294c725..64e56f9 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
@@ -16,29 +16,20 @@
 package com.android.keyguard.clock;
 
 import android.annotation.Nullable;
-import android.app.WallpaperManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
 import android.database.ContentObserver;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-import android.graphics.Color;
 import android.os.Handler;
 import android.os.Looper;
 import android.provider.Settings;
 import android.util.ArrayMap;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.MeasureSpec;
-import android.view.ViewGroup;
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManager.DockEventListener;
@@ -50,8 +41,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.FutureTask;
+import java.util.function.Supplier;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -63,15 +53,11 @@
 public final class ClockManager {
 
     private static final String TAG = "ClockOptsProvider";
-    private static final String DEFAULT_CLOCK_ID = "default";
 
-    private final List<ClockInfo> mClockInfos = new ArrayList<>();
-    /**
-     * Map from expected value stored in settings to supplier of custom clock face.
-     */
-    private final Map<String, ClockPlugin> mClocks = new ArrayMap<>();
-    @Nullable private ClockPlugin mCurrentClock;
+    private final AvailableClocks mPreviewClocks;
+    private final List<Supplier<ClockPlugin>> mBuiltinClocks = new ArrayList<>();
 
+    private final Context mContext;
     private final ContentResolver mContentResolver;
     private final SettingsWrapper mSettingsWrapper;
     private final Handler mMainHandler = new Handler(Looper.getMainLooper());
@@ -88,21 +74,6 @@
                 }
             };
 
-    private final PluginListener<ClockPlugin> mClockPluginListener =
-            new PluginListener<ClockPlugin>() {
-                @Override
-                public void onPluginConnected(ClockPlugin plugin, Context pluginContext) {
-                    addClockPlugin(plugin);
-                    reload();
-                }
-
-                @Override
-                public void onPluginDisconnected(ClockPlugin plugin) {
-                    removeClockPlugin(plugin);
-                    reload();
-                }
-            };
-
     private final PluginManager mPluginManager;
 
     /**
@@ -117,44 +88,51 @@
                     reload();
                 }
             };
-    @Nullable private final DockManager mDockManager;
+    @Nullable private DockManager mDockManager;
+
     /**
      * When docked, the DOCKED_CLOCK_FACE setting will be checked for the custom clock face
      * to show.
      */
     private boolean mIsDocked;
 
-    private final List<ClockChangedListener> mListeners = new ArrayList<>();
+    /**
+     * Listeners for onClockChanged event.
+     *
+     * Each listener must receive a separate clock plugin instance. Otherwise, there could be
+     * problems like attempting to attach a view that already has a parent. To deal with this issue,
+     * each listener is associated with a collection of available clocks. When onClockChanged is
+     * fired the current clock plugin instance is retrieved from that listeners available clocks.
+     */
+    private final Map<ClockChangedListener, AvailableClocks> mListeners = new ArrayMap<>();
 
-    private final SysuiColorExtractor mColorExtractor;
     private final int mWidth;
     private final int mHeight;
 
     @Inject
     public ClockManager(Context context, InjectionInflationController injectionInflater,
-            PluginManager pluginManager, @Nullable DockManager dockManager,
-            SysuiColorExtractor colorExtractor) {
-        this(context, injectionInflater, pluginManager, dockManager, colorExtractor,
+            PluginManager pluginManager, SysuiColorExtractor colorExtractor) {
+        this(context, injectionInflater, pluginManager, colorExtractor,
                 context.getContentResolver(), new SettingsWrapper(context.getContentResolver()));
     }
 
     ClockManager(Context context, InjectionInflationController injectionInflater,
-            PluginManager pluginManager, @Nullable DockManager dockManager,
-            SysuiColorExtractor colorExtractor, ContentResolver contentResolver,
-            SettingsWrapper settingsWrapper) {
+            PluginManager pluginManager, SysuiColorExtractor colorExtractor,
+            ContentResolver contentResolver, SettingsWrapper settingsWrapper) {
+        mContext = context;
         mPluginManager = pluginManager;
-        mDockManager = dockManager;
-        mColorExtractor = colorExtractor;
         mContentResolver = contentResolver;
         mSettingsWrapper = settingsWrapper;
+        mPreviewClocks = new AvailableClocks();
 
         Resources res = context.getResources();
         LayoutInflater layoutInflater = injectionInflater.injectable(LayoutInflater.from(context));
 
-        addClockPlugin(new DefaultClockController(res, layoutInflater));
-        addClockPlugin(new BubbleClockController(res, layoutInflater));
-        addClockPlugin(new StretchAnalogClockController(res, layoutInflater));
-        addClockPlugin(new TypeClockController(res, layoutInflater));
+        addBuiltinClock(() -> new DefaultClockController(res, layoutInflater, colorExtractor));
+        addBuiltinClock(() -> new BubbleClockController(res, layoutInflater, colorExtractor));
+        addBuiltinClock(() -> new StretchAnalogClockController(res, layoutInflater,
+                colorExtractor));
+        addBuiltinClock(() -> new TypeClockController(res, layoutInflater, colorExtractor));
 
         // Store the size of the display for generation of clock preview.
         DisplayMetrics dm = res.getDisplayMetrics();
@@ -169,7 +147,12 @@
         if (mListeners.isEmpty()) {
             register();
         }
-        mListeners.add(listener);
+        AvailableClocks availableClocks = new AvailableClocks();
+        for (int i = 0; i < mBuiltinClocks.size(); i++) {
+            availableClocks.addClockPlugin(mBuiltinClocks.get(i).get());
+        }
+        mListeners.put(listener, availableClocks);
+        mPluginManager.addPluginListener(availableClocks, ClockPlugin.class, true);
         reload();
     }
 
@@ -177,7 +160,8 @@
      * Remove listener added with {@link addOnClockChangedListener}.
      */
     public void removeOnClockChangedListener(ClockChangedListener listener) {
-        mListeners.remove(listener);
+        AvailableClocks availableClocks = mListeners.remove(listener);
+        mPluginManager.removePluginListener(availableClocks);
         if (mListeners.isEmpty()) {
             unregister();
         }
@@ -187,16 +171,16 @@
      * Get information about available clock faces.
      */
     List<ClockInfo> getClockInfos() {
-        return mClockInfos;
+        return mPreviewClocks.getInfo();
     }
 
     /**
      * Get the current clock.
-     * @returns current custom clock or null for default.
+     * @return current custom clock or null for default.
      */
     @Nullable
     ClockPlugin getCurrentClock() {
-        return mCurrentClock;
+        return mPreviewClocks.getCurrentClock();
     }
 
     @VisibleForTesting
@@ -209,127 +193,30 @@
         return mContentObserver;
     }
 
-    private void addClockPlugin(ClockPlugin plugin) {
-        final String id = plugin.getClass().getName();
-        mClocks.put(plugin.getClass().getName(), plugin);
-        mClockInfos.add(ClockInfo.builder()
-                .setName(plugin.getName())
-                .setTitle(plugin.getTitle())
-                .setId(id)
-                .setThumbnail(() -> plugin.getThumbnail())
-                .setPreview(() -> getClockPreview(id))
-                .build());
-    }
-
-    private void removeClockPlugin(ClockPlugin plugin) {
-        final String id = plugin.getClass().getName();
-        mClocks.remove(id);
-        for (int i = 0; i < mClockInfos.size(); i++) {
-            if (id.equals(mClockInfos.get(i).getId())) {
-                mClockInfos.remove(i);
-                break;
-            }
-        }
-    }
-
-    /**
-     * Generate a realistic preview of a clock face.
-     * @param clockId ID of clock to use for preview, should be obtained from {@link getClockInfos}.
-     *        Returns null if clockId is not found.
-     */
-    @Nullable
-    private Bitmap getClockPreview(String clockId) {
-        FutureTask<Bitmap> task = new FutureTask<>(new Callable<Bitmap>() {
-            @Override
-            public Bitmap call() {
-                Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);
-                ClockPlugin plugin = mClocks.get(clockId);
-                if (plugin == null) {
-                    return null;
-                }
-
-                // Use the big clock view for the preview
-                View clockView = plugin.getBigClockView();
-                if (clockView == null) {
-                    return null;
-                }
-
-                // Initialize state of plugin before generating preview.
-                plugin.setDarkAmount(1f);
-                plugin.setTextColor(Color.WHITE);
-
-                ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                        WallpaperManager.FLAG_LOCK, true);
-                plugin.setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
-                plugin.onTimeTick();
-
-                // Draw clock view hierarchy to canvas.
-                Canvas canvas = new Canvas(bitmap);
-                canvas.drawColor(Color.BLACK);
-                dispatchVisibilityAggregated(clockView, true);
-                clockView.measure(MeasureSpec.makeMeasureSpec(mWidth, MeasureSpec.EXACTLY),
-                        MeasureSpec.makeMeasureSpec(mHeight, MeasureSpec.EXACTLY));
-                clockView.layout(0, 0, mWidth, mHeight);
-                clockView.draw(canvas);
-                return bitmap;
-            }
-        });
-
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            task.run();
-        } else {
-            mMainHandler.post(task);
-        }
-
-        try {
-            return task.get();
-        } catch (Exception e) {
-            Log.e(TAG, "Error completing task", e);
-            return null;
-        }
-    }
-
-    private void dispatchVisibilityAggregated(View view, boolean isVisible) {
-        // Similar to View.dispatchVisibilityAggregated implementation.
-        final boolean thisVisible = view.getVisibility() == View.VISIBLE;
-        if (thisVisible || !isVisible) {
-            view.onVisibilityAggregated(isVisible);
-        }
-
-        if (view instanceof ViewGroup) {
-            isVisible = thisVisible && isVisible;
-            ViewGroup vg = (ViewGroup) view;
-            int count = vg.getChildCount();
-
-            for (int i = 0; i < count; i++) {
-                dispatchVisibilityAggregated(vg.getChildAt(i), isVisible);
-            }
-        }
-    }
-
-    private void notifyClockChanged(ClockPlugin plugin) {
-        for (int i = 0; i < mListeners.size(); i++) {
-            // It probably doesn't make sense to supply the same plugin instances to multiple
-            // listeners. This should be fine for now since there is only a single listener.
-            mListeners.get(i).onClockChanged(plugin);
-        }
+    private void addBuiltinClock(Supplier<ClockPlugin> pluginSupplier) {
+        ClockPlugin plugin = pluginSupplier.get();
+        mPreviewClocks.addClockPlugin(plugin);
+        mBuiltinClocks.add(pluginSupplier);
     }
 
     private void register() {
-        mPluginManager.addPluginListener(mClockPluginListener, ClockPlugin.class, true);
+        mPluginManager.addPluginListener(mPreviewClocks, ClockPlugin.class, true);
         mContentResolver.registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE),
                 false, mContentObserver);
         mContentResolver.registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.DOCKED_CLOCK_FACE),
                 false, mContentObserver);
+        if (mDockManager == null) {
+            mDockManager = SysUiServiceProvider.getComponent(mContext, DockManager.class);
+        }
         if (mDockManager != null) {
             mDockManager.addListener(mDockEventListener);
         }
     }
 
     private void unregister() {
-        mPluginManager.removePluginListener(mClockPluginListener);
+        mPluginManager.removePluginListener(mPreviewClocks);
         mContentResolver.unregisterContentObserver(mContentObserver);
         if (mDockManager != null) {
             mDockManager.removeListener(mDockEventListener);
@@ -337,30 +224,16 @@
     }
 
     private void reload() {
-        mCurrentClock = getClockPlugin();
-        if (mCurrentClock instanceof DefaultClockController) {
-            notifyClockChanged(null);
-        } else {
-            notifyClockChanged(mCurrentClock);
-        }
-    }
-
-    private ClockPlugin getClockPlugin() {
-        ClockPlugin plugin = null;
-        if (mIsDocked) {
-            final String name = mSettingsWrapper.getDockedClockFace();
-            if (name != null) {
-                plugin = mClocks.get(name);
-                if (plugin != null) {
-                    return plugin;
-                }
+        mPreviewClocks.reload();
+        mListeners.forEach((listener, clocks) -> {
+            clocks.reload();
+            ClockPlugin clock = clocks.getCurrentClock();
+            if (clock instanceof DefaultClockController) {
+                listener.onClockChanged(null);
+            } else {
+                listener.onClockChanged(clock);
             }
-        }
-        final String name = mSettingsWrapper.getLockScreenCustomClockFace();
-        if (name != null) {
-            plugin = mClocks.get(name);
-        }
-        return plugin;
+        });
     }
 
     /**
@@ -374,4 +247,106 @@
          */
         void onClockChanged(ClockPlugin clock);
     }
+
+    /**
+     * Collection of available clocks.
+     */
+    private final class AvailableClocks implements PluginListener<ClockPlugin> {
+
+        /**
+         * Map from expected value stored in settings to plugin for custom clock face.
+         */
+        private final Map<String, ClockPlugin> mClocks = new ArrayMap<>();
+
+        /**
+         * Metadata about available clocks, such as name and preview images.
+         */
+        private final List<ClockInfo> mClockInfo = new ArrayList<>();
+
+        /**
+         * Active ClockPlugin.
+         */
+        @Nullable private ClockPlugin mCurrentClock;
+
+        @Override
+        public void onPluginConnected(ClockPlugin plugin, Context pluginContext) {
+            addClockPlugin(plugin);
+            reload();
+        }
+
+        @Override
+        public void onPluginDisconnected(ClockPlugin plugin) {
+            removeClockPlugin(plugin);
+            reload();
+        }
+
+        /**
+         * Get the current clock.
+         * @return current custom clock or null for default.
+         */
+        @Nullable
+        ClockPlugin getCurrentClock() {
+            return mCurrentClock;
+        }
+
+        /**
+         * Get information about available clock faces.
+         */
+        List<ClockInfo> getInfo() {
+            return mClockInfo;
+        }
+
+        /**
+         * Adds a clock plugin to the collection of available clocks.
+         *
+         * @param plugin The plugin to add.
+         */
+        void addClockPlugin(ClockPlugin plugin) {
+            final String id = plugin.getClass().getName();
+            mClocks.put(plugin.getClass().getName(), plugin);
+            mClockInfo.add(ClockInfo.builder()
+                    .setName(plugin.getName())
+                    .setTitle(plugin.getTitle())
+                    .setId(id)
+                    .setThumbnail(plugin::getThumbnail)
+                    .setPreview(() -> plugin.getPreview(mWidth, mHeight))
+                    .build());
+        }
+
+        private void removeClockPlugin(ClockPlugin plugin) {
+            final String id = plugin.getClass().getName();
+            mClocks.remove(id);
+            for (int i = 0; i < mClockInfo.size(); i++) {
+                if (id.equals(mClockInfo.get(i).getId())) {
+                    mClockInfo.remove(i);
+                    break;
+                }
+            }
+        }
+
+        /**
+         * Update the current clock.
+         */
+        void reload() {
+            mCurrentClock = getClockPlugin();
+        }
+
+        private ClockPlugin getClockPlugin() {
+            ClockPlugin plugin = null;
+            if (ClockManager.this.isDocked()) {
+                final String name = mSettingsWrapper.getDockedClockFace();
+                if (name != null) {
+                    plugin = mClocks.get(name);
+                    if (plugin != null) {
+                        return plugin;
+                    }
+                }
+            }
+            final String name = mSettingsWrapper.getLockScreenCustomClockFace();
+            if (name != null) {
+                plugin = mClocks.get(name);
+            }
+            return plugin;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
index 8a6a4cd..488cb27 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
@@ -15,15 +15,19 @@
  */
 package com.android.keyguard.clock;
 
+import android.app.WallpaperManager;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Color;
 import android.graphics.Paint.Style;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.TextView;
 
+import com.android.internal.colorextraction.ColorExtractor;
 import com.android.keyguard.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ClockPlugin;
 
 import java.util.TimeZone;
@@ -44,6 +48,16 @@
     private final LayoutInflater mLayoutInflater;
 
     /**
+     * Extracts accent color from wallpaper.
+     */
+    private final SysuiColorExtractor mColorExtractor;
+
+    /**
+     * Renders preview from clock view.
+     */
+    private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+    /**
      * Root view of preview.
      */
     private View mView;
@@ -61,11 +75,15 @@
     /**
      * Create a DefaultClockController instance.
      *
+     * @param res Resources contains title and thumbnail.
      * @param inflater Inflater used to inflate custom clock views.
+     * @param colorExtractor Extracts accent color from wallpaper.
      */
-    public DefaultClockController(Resources res, LayoutInflater inflater) {
+    public DefaultClockController(Resources res, LayoutInflater inflater,
+            SysuiColorExtractor colorExtractor) {
         mResources = res;
         mLayoutInflater = inflater;
+        mColorExtractor = colorExtractor;
     }
 
     private void createViews() {
@@ -75,6 +93,13 @@
     }
 
     @Override
+    public void onDestroyView() {
+        mView = null;
+        mTextTime = null;
+        mTextDate = null;
+    }
+
+    @Override
     public String getName() {
         return "default";
     }
@@ -90,6 +115,23 @@
     }
 
     @Override
+    public Bitmap getPreview(int width, int height) {
+
+        // Use the big clock view for the preview
+        View view = getBigClockView();
+
+        // Initialize state of plugin before generating preview.
+        setDarkAmount(1f);
+        setTextColor(Color.WHITE);
+        ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+                WallpaperManager.FLAG_LOCK, true);
+        setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+        onTimeTick();
+
+        return mRenderer.createPreview(view, width, height);
+    }
+
+    @Override
     public View getView() {
         return null;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
index 34b2fd8..81b6a60 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
@@ -15,15 +15,19 @@
  */
 package com.android.keyguard.clock;
 
+import android.app.WallpaperManager;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Color;
 import android.graphics.Paint.Style;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.TextClock;
 
+import com.android.internal.colorextraction.ColorExtractor;
 import com.android.keyguard.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ClockPlugin;
 
 import java.util.TimeZone;
@@ -44,6 +48,16 @@
     private final LayoutInflater mLayoutInflater;
 
     /**
+     * Extracts accent color from wallpaper.
+     */
+    private final SysuiColorExtractor mColorExtractor;
+
+    /**
+     * Renders preview from clock view.
+     */
+    private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+    /**
      * Custom clock shown on AOD screen and behind stack scroller on lock.
      */
     private View mBigClockView;
@@ -64,11 +78,15 @@
     /**
      * Create a BubbleClockController instance.
      *
-     * @param layoutInflater Inflater used to inflate custom clock views.
+     * @param res Resources contains title and thumbnail.
+     * @param inflater Inflater used to inflate custom clock views.
+     * @param colorExtractor Extracts accent color from wallpaper.
      */
-    public StretchAnalogClockController(Resources res, LayoutInflater inflater) {
+    public StretchAnalogClockController(Resources res, LayoutInflater inflater,
+            SysuiColorExtractor colorExtractor) {
         mResources = res;
         mLayoutInflater = inflater;
+        mColorExtractor = colorExtractor;
     }
 
     private void createViews() {
@@ -83,6 +101,17 @@
         mDarkController = new CrossFadeDarkController(mDigitalClock, mLockClock);
     }
 
+
+    @Override
+    public void onDestroyView() {
+        mBigClockView = null;
+        mDigitalClock = null;
+        mAnalogClock = null;
+        mView = null;
+        mLockClock = null;
+        mDarkController = null;
+    }
+
     @Override
     public String getName() {
         return "stretch";
@@ -99,6 +128,23 @@
     }
 
     @Override
+    public Bitmap getPreview(int width, int height) {
+
+        // Use the big clock view for the preview
+        View view = getBigClockView();
+
+        // Initialize state of plugin before generating preview.
+        setDarkAmount(1f);
+        setTextColor(Color.WHITE);
+        ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+                WallpaperManager.FLAG_LOCK, true);
+        setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+        onTimeTick();
+
+        return mRenderer.createPreview(view, width, height);
+    }
+
+    @Override
     public View getView() {
         if (mView == null) {
             createViews();
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java
index 387f265..1c6b38b 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java
@@ -15,14 +15,18 @@
  */
 package com.android.keyguard.clock;
 
+import android.app.WallpaperManager;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Color;
 import android.graphics.Paint.Style;
 import android.view.LayoutInflater;
 import android.view.View;
 
+import com.android.internal.colorextraction.ColorExtractor;
 import com.android.keyguard.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ClockPlugin;
 
 import java.util.TimeZone;
@@ -43,6 +47,16 @@
     private final LayoutInflater mLayoutInflater;
 
     /**
+     * Extracts accent color from wallpaper.
+     */
+    private final SysuiColorExtractor mColorExtractor;
+
+    /**
+     * Renders preview from clock view.
+     */
+    private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+    /**
      * Custom clock shown on AOD screen and behind stack scroller on lock.
      */
     private View mView;
@@ -61,11 +75,15 @@
     /**
      * Create a TypeClockController instance.
      *
+     * @param res Resources contains title and thumbnail.
      * @param inflater Inflater used to inflate custom clock views.
+     * @param colorExtractor Extracts accent color from wallpaper.
      */
-    TypeClockController(Resources res, LayoutInflater inflater) {
+    TypeClockController(Resources res, LayoutInflater inflater,
+            SysuiColorExtractor colorExtractor) {
         mResources = res;
         mLayoutInflater = inflater;
+        mColorExtractor = colorExtractor;
     }
 
     private void createViews() {
@@ -81,6 +99,14 @@
     }
 
     @Override
+    public void onDestroyView() {
+        mView = null;
+        mTypeClock = null;
+        mLockClock = null;
+        mDarkController = null;
+    }
+
+    @Override
     public String getName() {
         return "type";
     }
@@ -96,6 +122,23 @@
     }
 
     @Override
+    public Bitmap getPreview(int width, int height) {
+
+        // Use the big clock view for the preview
+        View view = getBigClockView();
+
+        // Initialize state of plugin before generating preview.
+        setDarkAmount(1f);
+        setTextColor(Color.WHITE);
+        ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+                WallpaperManager.FLAG_LOCK, true);
+        setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+        onTimeTick();
+
+        return mRenderer.createPreview(view, width, height);
+    }
+
+    @Override
     public View getView() {
         if (mLockClock == null) {
             createViews();
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ViewPreviewer.java b/packages/SystemUI/src/com/android/keyguard/clock/ViewPreviewer.java
new file mode 100644
index 0000000..abd0dd2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ViewPreviewer.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.annotation.Nullable;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
+
+/**
+ * Creates a preview image ({@link Bitmap}) of a {@link View} for a custom clock face.
+ */
+final class ViewPreviewer {
+
+    private static final String TAG = "ViewPreviewer";
+
+    /**
+     * Handler used to run {@link View#draw(Canvas)} on the main thread.
+     */
+    private final Handler mMainHandler = new Handler(Looper.getMainLooper());
+
+    /**
+     * Generate a realistic preview of a clock face.
+     *
+     * @param view view is used to generate preview image.
+     * @param width width of the preview image, should be the same as device width in pixels.
+     * @param height height of the preview image, should be the same as device height in pixels.
+     * @return bitmap of view.
+     */
+    @Nullable
+    Bitmap createPreview(View view, int width, int height) {
+        if (view == null) {
+            return null;
+        }
+        FutureTask<Bitmap> task = new FutureTask<>(new Callable<Bitmap>() {
+            @Override
+            public Bitmap call() {
+                Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+
+                // Draw clock view hierarchy to canvas.
+                Canvas canvas = new Canvas(bitmap);
+                canvas.drawColor(Color.BLACK);
+                dispatchVisibilityAggregated(view, true);
+                view.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
+                        View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY));
+                view.layout(0, 0, width, height);
+                view.draw(canvas);
+
+                return bitmap;
+            }
+        });
+
+        if (Looper.myLooper() == Looper.getMainLooper()) {
+            task.run();
+        } else {
+            mMainHandler.post(task);
+        }
+
+        try {
+            return task.get();
+        } catch (Exception e) {
+            Log.e(TAG, "Error completing task", e);
+            return null;
+        }
+    }
+
+    private void dispatchVisibilityAggregated(View view, boolean isVisible) {
+        // Similar to View.dispatchVisibilityAggregated implementation.
+        final boolean thisVisible = view.getVisibility() == View.VISIBLE;
+        if (thisVisible || !isVisible) {
+            view.onVisibilityAggregated(isVisible);
+        }
+
+        if (view instanceof ViewGroup) {
+            isVisible = thisVisible && isVisible;
+            ViewGroup vg = (ViewGroup) view;
+            int count = vg.getChildCount();
+
+            for (int i = 0; i < count; i++) {
+                dispatchVisibilityAggregated(vg.getChildAt(i), isVisible);
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 6bb4fb5..47ad0c1 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -31,7 +31,6 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.classifier.FalsingManager;
-import com.android.systemui.dock.DockManager;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -220,16 +219,6 @@
         return SysUiServiceProvider.getComponent(context, StatusBar.class);
     }
 
-    /**
-     * Provides DockManager.
-     */
-    @Singleton
-    @Provides
-    @Nullable
-    public DockManager providesDockManager(Context context) {
-        return SysUiServiceProvider.getComponent(context, DockManager.class);
-    }
-
     @Module
     protected static class ContextHolder {
         private Context mContext;
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index ace086f..3fc6689 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -204,24 +204,59 @@
     }
 
     /**
-     * Does the app-op item refer to a user sensitive permission. Only user sensitive permission
-     * should be shown to the user by default.
+     * Does the app-op code refer to a user sensitive permission for the specified user id
+     * and package. Only user sensitive permission should be shown to the user by default.
      *
-     * @param item The item
+     * @param appOpCode The code of the app-op.
+     * @param uid The uid of the user.
+     * @param packageName The name of the package.
      *
      * @return {@code true} iff the app-op item is user sensitive
      */
-    private boolean isUserSensitive(AppOpItem item) {
-        String permission = AppOpsManager.opToPermission(item.getCode());
+    private boolean isUserSensitive(int appOpCode, int uid, String packageName) {
+        String permission = AppOpsManager.opToPermission(appOpCode);
         if (permission == null) {
             return false;
         }
         int permFlags = mContext.getPackageManager().getPermissionFlags(permission,
-                item.getPackageName(), UserHandle.getUserHandleForUid(item.getUid()));
+                packageName, UserHandle.getUserHandleForUid(uid));
         return (permFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0;
     }
 
     /**
+     * Does the app-op item refer to an operation that should be shown to the user.
+     * Only specficic ops (like SYSTEM_ALERT_WINDOW) or ops that refer to user sensitive
+     * permission should be shown to the user by default.
+     *
+     * @param item The item
+     *
+     * @return {@code true} iff the app-op item should be shown to the user
+     */
+    private boolean isUserVisible(AppOpItem item) {
+        return isUserVisible(item.getCode(), item.getUid(), item.getPackageName());
+    }
+
+
+    /**
+     * Does the app-op, uid and package name, refer to an operation that should be shown to the
+     * user. Only specficic ops (like {@link AppOpsManager.OP_SYSTEM_ALERT_WINDOW}) or
+     * ops that refer to user sensitive permission should be shown to the user by default.
+     *
+     * @param item The item
+     *
+     * @return {@code true} iff the app-op for should be shown to the user
+     */
+    private boolean isUserVisible(int appOpCode, int uid, String packageName) {
+        // currently OP_SYSTEM_ALERT_WINDOW does not correspond to a platform permission
+        // which may be user senstive, so for now always show it to the user.
+        if (appOpCode == AppOpsManager.OP_SYSTEM_ALERT_WINDOW) {
+            return true;
+        }
+
+        return isUserSensitive(appOpCode, uid, packageName);
+    }
+
+    /**
      * Returns a copy of the list containing all the active AppOps that the controller tracks.
      *
      * @return List of active AppOps information
@@ -245,7 +280,7 @@
             for (int i = 0; i < numActiveItems; i++) {
                 AppOpItem item = mActiveItems.get(i);
                 if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId)
-                        && isUserSensitive(item)) {
+                        && isUserVisible(item)) {
                     list.add(item);
                 }
             }
@@ -255,7 +290,7 @@
             for (int i = 0; i < numNotedItems; i++) {
                 AppOpItem item = mNotedItems.get(i);
                 if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId)
-                        && isUserSensitive(item)) {
+                        && isUserVisible(item)) {
                     list.add(item);
                 }
             }
@@ -281,7 +316,8 @@
     }
 
     private void notifySuscribers(int code, int uid, String packageName, boolean active) {
-        if (mCallbacksByCode.containsKey(code)) {
+        if (mCallbacksByCode.containsKey(code)
+                && isUserVisible(code, uid, packageName)) {
             for (Callback cb: mCallbacksByCode.get(code)) {
                 cb.onActiveStateChanged(code, uid, packageName, active);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
index 1154515..98f446d 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BadgedImageView.java
@@ -18,8 +18,6 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.AttributeSet;
@@ -36,11 +34,9 @@
     private int mIconSize;
     private Rect mTempBounds = new Rect();
     private Point mTempPoint = new Point();
-    private Path mClipPath = new Path();
 
     private float mDotScale = 0f;
     private int mUpdateDotColor;
-    private int mBubbleDefaultBgColor;
     private boolean mShowUpdateDot;
     private boolean mOnLeft;
 
@@ -59,32 +55,17 @@
     public BadgedImageView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        setScaleType(ScaleType.CENTER_CROP);
         mIconSize = getResources().getDimensionPixelSize(R.dimen.individual_bubble_size);
         mDotRenderer = new BadgeRenderer(mIconSize);
 
         TypedArray ta = context.obtainStyledAttributes(
                 new int[] {android.R.attr.colorBackgroundFloating});
-        mBubbleDefaultBgColor = ta.getColor(0, Color.WHITE);
         ta.recycle();
     }
 
-    // TODO: Clipping oval path isn't great: rerender image into a separate, rounded bitmap and
-    // then draw would be better
     @Override
     public void onDraw(Canvas canvas) {
-        canvas.save();
-        // Circle crop
-        mClipPath.addOval(getPaddingStart(), getPaddingTop(),
-                getWidth() - getPaddingEnd(), getHeight() - getPaddingBottom(), Path.Direction.CW);
-        canvas.clipPath(mClipPath);
-        canvas.drawColor(mBubbleDefaultBgColor);
         super.onDraw(canvas);
-
-        // After we've circle cropped what we're showing, restore so we don't clip the badge
-        canvas.restore();
-
-        // Draw the badge
         if (mShowUpdateDot) {
             getDrawingRect(mTempBounds);
             mTempPoint.set((getWidth() - mIconSize) / 2, getPaddingTop());
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 4a2731e..a5aed87 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -26,6 +26,7 @@
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityTaskManager;
 import android.app.IActivityTaskManager;
@@ -64,6 +65,7 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 
 import java.lang.annotation.Retention;
+import java.util.List;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -80,8 +82,6 @@
 
     private static final String TAG = "BubbleController";
 
-    private static final int MAX_BUBBLES = 5; // TODO: actually enforce this
-
     @Retention(SOURCE)
     @IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED,
             DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION})
@@ -94,6 +94,8 @@
     static final int DISMISS_NOTIF_CANCEL = 5;
     static final int DISMISS_ACCESSIBILITY_ACTION = 6;
 
+    static final int MAX_BUBBLES = 5; // TODO: actually enforce this
+
     // Enables some subset of notifs to automatically become bubbles
     private static final boolean DEBUG_ENABLE_AUTO_BUBBLE = false;
 
@@ -291,6 +293,17 @@
     }
 
     /**
+     * Request the stack expand if needed, then select the specified Bubble as current.
+     *
+     * @param notificationKey the notification key for the bubble to be selected
+     */
+    public void expandStackAndSelectBubble(String notificationKey) {
+        if (mStackView != null && mBubbleData.getBubble(notificationKey) != null) {
+            mStackView.setExpandedBubble(notificationKey);
+        }
+    }
+
+    /**
      * Tell the stack of bubbles to be dismissed, this will remove all of the bubbles in the stack.
      */
     void dismissStack(@DismissReason int reason) {
@@ -340,6 +353,9 @@
             // It's new
             mStackView.addBubble(notif);
         }
+        if (shouldAutoExpand(notif)) {
+            mStackView.setExpandedBubble(notif);
+        }
         updateVisibility();
     }
 
@@ -379,9 +395,10 @@
             }
             if (shouldAutoBubbleForFlags(mContext, entry) || shouldBubble(entry)) {
                 // TODO: handle group summaries
-                // It's a new notif, it shows in the shade and as a bubble
-                entry.setIsBubble(true);
-                entry.setShowInShadeWhenBubble(true);
+                boolean suppressNotification = entry.getBubbleMetadata() != null
+                        && entry.getBubbleMetadata().getSuppressInitialNotification()
+                        && isForegroundApp(entry.notification.getPackageName());
+                entry.setShowInShadeWhenBubble(!suppressNotification);
             }
         }
 
@@ -522,6 +539,23 @@
                 || autoBubbleAll;
     }
 
+    private boolean shouldAutoExpand(NotificationEntry entry) {
+        Notification.BubbleMetadata metadata = entry.getBubbleMetadata();
+        return metadata != null && metadata.getAutoExpandBubble()
+                && isForegroundApp(entry.notification.getPackageName());
+    }
+
+    /**
+     * Return true if the applications with the package name is running in foreground.
+     *
+     * @param pkgName application package name.
+     */
+    private boolean isForegroundApp(String pkgName) {
+        ActivityManager am = mContext.getSystemService(ActivityManager.class);
+        List<RunningTaskInfo> tasks = am.getRunningTasks(1 /* maxNum */);
+        return !tasks.isEmpty() && pkgName.equals(tasks.get(0).topActivity.getPackageName());
+    }
+
     /**
      * This task stack listener is responsible for responding to tasks moved to the front
      * which are on the default (main) display. When this happens, expanded bubbles must be
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 8e3afd8..6c2db76e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -38,8 +38,11 @@
 import android.graphics.Color;
 import android.graphics.Insets;
 import android.graphics.Point;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.InsetDrawable;
 import android.graphics.drawable.ShapeDrawable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -53,7 +56,6 @@
 import android.view.ViewGroup;
 import android.view.WindowInsets;
 import android.widget.FrameLayout;
-import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -80,10 +82,7 @@
     private View mPointerView;
     private int mPointerMargin;
 
-    // Header
-    private View mHeaderView;
-    private ImageButton mDeepLinkIcon;
-    private ImageButton mSettingsIcon;
+    private ImageView mSettingsIcon;
 
     // Permission view
     private View mPermissionView;
@@ -195,7 +194,6 @@
         mPointerView.setBackground(triangleDrawable);
 
         FrameLayout viewWrapper = findViewById(R.id.header_permission_wrapper);
-        viewWrapper.setBackground(createHeaderPermissionBackground(bgColor));
 
         LayoutTransition transition = new LayoutTransition();
         transition.setDuration(200);
@@ -212,18 +210,16 @@
         viewWrapper.setLayoutTransition(transition);
         viewWrapper.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
 
-
         mHeaderHeight = getContext().getResources().getDimensionPixelSize(
                 R.dimen.bubble_expanded_header_height);
         mPermissionHeight = getContext().getResources().getDimensionPixelSize(
                 R.dimen.bubble_permission_height);
-        mHeaderView = findViewById(R.id.header_layout);
-        mDeepLinkIcon = findViewById(R.id.deep_link_button);
-        mSettingsIcon = findViewById(R.id.settings_button);
-        mDeepLinkIcon.setOnClickListener(this);
-        mSettingsIcon.setOnClickListener(this);
 
         mPermissionView = findViewById(R.id.permission_layout);
+        mSettingsIcon = findViewById(R.id.settings_button);
+        mSettingsIcon.setOnClickListener(this);
+        updateHeaderColor();
+
         findViewById(R.id.no_bubbles_button).setOnClickListener(this);
         findViewById(R.id.yes_bubbles_button).setOnClickListener(this);
 
@@ -381,17 +377,31 @@
     }
 
     /**
-     * Update bubble expanded view header when user toggles dark mode.
+     * Update header color and icon shape when theme changes.
      */
     void updateHeaderColor() {
-        mHeaderView.setBackgroundColor(mContext.getColor(R.attr.colorAccent));
+        TypedArray ta = mContext.obtainStyledAttributes(
+                new int[] {android.R.attr.colorBackgroundFloating, android.R.attr.colorForeground});
+        int backgroundColor = ta.getColor(0, Color.WHITE /* default */);
+        int foregroundColor = ta.getColor(1, Color.BLACK /* default */);
+        ta.recycle();
+
+        mPermissionView.setBackground(createHeaderPermissionBackground(backgroundColor));
+
+        Drawable settingsIcon =  mSettingsIcon.getDrawable();
+        settingsIcon.setTint(foregroundColor);
+
+        int mIconInset = getResources().getDimensionPixelSize(R.dimen.bubble_icon_inset);
+        InsetDrawable foreground = new InsetDrawable(settingsIcon, mIconInset);
+        ColorDrawable background = new ColorDrawable(backgroundColor);
+        AdaptiveIconDrawable adaptiveIcon = new AdaptiveIconDrawable(background,
+                foreground);
+        mSettingsIcon.setImageDrawable(adaptiveIcon);
     }
 
     private void updateHeaderView() {
         mSettingsIcon.setContentDescription(getResources().getString(
                 R.string.bubbles_settings_button_description, mAppName));
-        mDeepLinkIcon.setContentDescription(getResources().getString(
-                R.string.bubbles_deep_link_button_description, mAppName));
     }
 
     private void updatePermissionView() {
@@ -404,16 +414,14 @@
             Log.w(TAG, e);
         }
         if (hasUserApprovedBubblesForPackage) {
-            mHeaderView.setVisibility(VISIBLE);
-            mPermissionView.setVisibility(GONE);
+            showSettingsIcon();
         } else {
-            mHeaderView.setVisibility(GONE);
-            mPermissionView.setVisibility(VISIBLE);
+            showPermissionView();
             ((ImageView) mPermissionView.findViewById(R.id.pkgicon)).setImageDrawable(mAppIcon);
             ((TextView) mPermissionView.findViewById(R.id.pkgname)).setText(mAppName);
             ((TextView) mPermissionView.findViewById(R.id.prompt)).setText(
                     getResources().getString(R.string.bubbles_prompt, mAppName));
-            logBubbleClickEvent(mEntry.notification,
+            logBubbleClickEvent(mEntry,
                     StatsLog.BUBBLE_UICHANGED__ACTION__PERMISSION_DIALOG_SHOWN);
         }
     }
@@ -437,7 +445,7 @@
     }
 
     boolean performBackPressIfNeeded() {
-        if (mActivityView == null || !usingActivityView()) {
+        if (!usingActivityView()) {
             return false;
         }
         mActivityView.performBackPress();
@@ -505,23 +513,12 @@
         }
         Notification n = mEntry.notification.getNotification();
         int id = view.getId();
-        if (id == R.id.deep_link_button) {
-            mStackView.collapseStack(() -> {
-                try {
-                    n.contentIntent.send();
-                    logBubbleClickEvent(mEntry.notification,
-                            StatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_APP);
-                } catch (PendingIntent.CanceledException e) {
-                    Log.w(TAG, "Failed to send intent for bubble with key: "
-                            + (mEntry != null ? mEntry.key : " null entry"));
-                }
-            });
-        } else if (id == R.id.settings_button) {
+        if (id == R.id.settings_button) {
             Intent intent = getSettingsIntent(mEntry.notification.getPackageName(),
                     mEntry.notification.getUid());
             mStackView.collapseStack(() -> {
                 mContext.startActivity(intent);
-                logBubbleClickEvent(mEntry.notification,
+                logBubbleClickEvent(mEntry,
                         StatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
             });
         } else if (id == R.id.no_bubbles_button) {
@@ -538,13 +535,12 @@
                     mEntry.notification.getUid(),
                     allowed);
             if (allowed) {
-                mPermissionView.setVisibility(GONE);
-                mHeaderView.setVisibility(VISIBLE);
+                showSettingsIcon();
             } else if (mOnBubbleBlockedListener != null) {
                 mOnBubbleBlockedListener.onBubbleBlocked(mEntry);
             }
             mStackView.onExpandedHeightChanged();
-            logBubbleClickEvent(mEntry.notification,
+            logBubbleClickEvent(mEntry,
                     allowed ? StatsLog.BUBBLE_UICHANGED__ACTION__PERMISSION_OPT_IN :
                             StatsLog.BUBBLE_UICHANGED__ACTION__PERMISSION_OPT_OUT);
         } catch (RemoteException e) {
@@ -552,6 +548,17 @@
         }
     }
 
+    void showSettingsIcon() {
+        mPermissionView.setVisibility(GONE);
+        mSettingsIcon.setVisibility(VISIBLE);
+    }
+
+    void showPermissionView() {
+        mSettingsIcon.setVisibility(GONE);
+        mPermissionView.setVisibility(VISIBLE);
+
+    }
+
     /**
      * Update appearance of the expanded view being displayed.
      */
@@ -593,7 +600,7 @@
     }
 
     private boolean usingActivityView() {
-        return mBubbleIntent != null;
+        return mBubbleIntent != null && mActivityView != null;
     }
 
     private void applyRowState(ExpandableNotificationRow view) {
@@ -707,10 +714,11 @@
     /**
      * Logs bubble UI click event.
      *
-     * @param notification the bubble notification that user is interacting with.
+     * @param entry the bubble notification entry that user is interacting with.
      * @param action the user interaction enum.
      */
-    private void logBubbleClickEvent(StatusBarNotification notification, int action) {
+    private void logBubbleClickEvent(NotificationEntry entry, int action) {
+        StatusBarNotification notification = entry.notification;
         StatsLog.write(StatsLog.BUBBLE_UI_CHANGED,
                 notification.getPackageName(),
                 notification.getNotification().getChannelId(),
@@ -719,7 +727,8 @@
                 mStackView.getBubbleCount(),
                 action,
                 mStackView.getNormalizedXPosition(),
-                mStackView.getNormalizedYPosition());
+                mStackView.getNormalizedYPosition(),
+                entry.showInShadeWhenBubble());
     }
 
     private int getDimenForPackageUser(int resId, String pkg, int userId) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 580acb8..de4605b 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -42,7 +42,9 @@
 import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.animation.AccelerateDecelerateInterpolator;
 import android.widget.FrameLayout;
+import android.widget.TextView;
 
 import androidx.annotation.MainThread;
 import androidx.annotation.Nullable;
@@ -52,6 +54,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.ViewClippingUtil;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.bubbles.BubbleController.DismissReason;
 import com.android.systemui.bubbles.animation.ExpandedAnimationController;
@@ -69,6 +72,13 @@
     private static final String TAG = "BubbleStackView";
     private static final boolean DEBUG = false;
 
+    /** Duration of the flyout alpha animations. */
+    private static final int FLYOUT_ALPHA_ANIMATION_DURATION = 100;
+
+    /** How long to wait, in milliseconds, before hiding the flyout. */
+    @VisibleForTesting
+    static final int FLYOUT_HIDE_AFTER = 5000;
+
     /**
      * Interface to synchronize {@link View} state and the screen.
      *
@@ -118,6 +128,14 @@
 
     private FrameLayout mExpandedViewContainer;
 
+    private View mFlyout;
+    private TextView mFlyoutText;
+    /** Spring animation for the flyout. */
+    private SpringAnimation mFlyoutSpring;
+    /** Runnable that fades out the flyout and then sets it to GONE. */
+    private Runnable mHideFlyout =
+            () -> mFlyout.animate().alpha(0f).withEndAction(() -> mFlyout.setVisibility(GONE));
+
     private int mBubbleSize;
     private int mBubblePadding;
     private int mExpandedAnimateXDistance;
@@ -130,12 +148,15 @@
     private boolean mIsExpanded;
     private boolean mImeVisible;
 
+    /** Whether the stack is currently being dragged. */
+    private boolean mIsDragging = false;
+
     private BubbleTouchHandler mTouchHandler;
     private BubbleController.BubbleExpandListener mExpandListener;
     private BubbleExpandedView.OnBubbleBlockedListener mBlockedListener;
 
     private boolean mViewUpdatedRequested = false;
-    private boolean mIsAnimating = false;
+    private boolean mIsExpansionAnimating = false;
 
     private LayoutInflater mInflater;
 
@@ -220,6 +241,17 @@
         mExpandedViewContainer.setClipChildren(false);
         addView(mExpandedViewContainer);
 
+        mFlyout = mInflater.inflate(R.layout.bubble_flyout, this, false);
+        mFlyout.setVisibility(GONE);
+        mFlyout.animate()
+                .setDuration(FLYOUT_ALPHA_ANIMATION_DURATION)
+                .setInterpolator(new AccelerateDecelerateInterpolator());
+        addView(mFlyout);
+
+        mFlyoutText = mFlyout.findViewById(R.id.bubble_flyout_text);
+
+        mFlyoutSpring = new SpringAnimation(mFlyout, DynamicAnimation.TRANSLATION_X);
+
         mExpandedViewXAnim =
                 new SpringAnimation(mExpandedViewContainer, DynamicAnimation.TRANSLATION_X);
         mExpandedViewXAnim.setSpring(
@@ -233,6 +265,11 @@
                 new SpringForce()
                         .setStiffness(SpringForce.STIFFNESS_LOW)
                         .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
+        mExpandedViewYAnim.addEndListener((anim, cancelled, value, velocity) -> {
+            if (mIsExpanded && mExpandedBubble != null) {
+                mExpandedBubble.expandedView.updateView();
+            }
+        });
 
         setClipChildren(false);
         setFocusable(true);
@@ -241,7 +278,7 @@
         setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
             final int keyboardHeight = insets.getSystemWindowInsetBottom()
                     - insets.getStableInsetBottom();
-            if (!mIsExpanded) {
+            if (!mIsExpanded || mIsExpansionAnimating) {
                 return view.onApplyWindowInsets(insets);
             }
             mImeVisible = keyboardHeight != 0;
@@ -265,7 +302,9 @@
      * Handle config changes.
      */
     public void onConfigChanged() {
-        mExpandedBubble.expandedView.updateHeaderColor();
+        for (Bubble b: mBubbleData.getBubbles()) {
+            b.expandedView.updateHeaderColor();
+        }
     }
 
     @Override
@@ -309,7 +348,8 @@
         }
         switch (action) {
             case AccessibilityNodeInfo.ACTION_DISMISS:
-                stackDismissed(BubbleController.DISMISS_ACCESSIBILITY_ACTION);
+                Dependency.get(BubbleController.class).dismissStack(
+                        BubbleController.DISMISS_ACCESSIBILITY_ACTION);
                 return true;
             case AccessibilityNodeInfo.ACTION_COLLAPSE:
                 collapseStack();
@@ -415,7 +455,7 @@
      * Sets the entry that should be expanded and expands if needed.
      */
     @VisibleForTesting
-    public void setExpandedBubble(NotificationEntry entry) {
+    void setExpandedBubble(NotificationEntry entry) {
         for (int i = 0; i < mBubbleContainer.getChildCount(); i++) {
             BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i);
             if (entry.equals(bv.getEntry())) {
@@ -429,7 +469,7 @@
      *
      * @param entry the notification to add to the stack of bubbles.
      */
-    public void addBubble(NotificationEntry entry) {
+    void addBubble(NotificationEntry entry) {
         Bubble b = new Bubble(entry, mInflater, this /* stackView */, mBlockedListener);
         mBubbleData.addBubble(b);
 
@@ -439,17 +479,24 @@
 
         requestUpdate();
         logBubbleEvent(b, StatsLog.BUBBLE_UICHANGED__ACTION__POSTED);
+
+        animateInFlyoutForBubble(b);
     }
 
     /**
      * Remove a bubble from the stack.
      */
-    public void removeBubble(String key, int reason) {
+    void removeBubble(String key, int reason) {
         Bubble b = mBubbleData.removeBubble(key);
         if (b == null) {
             return;
         }
-        int removedIndex = dismissBubble(b, reason);
+        setBubbleDismissed(b, reason);
+
+        // Remove it from the views
+        int removedIndex = mBubbleContainer.indexOfChild(b.iconView);
+        mBubbleContainer.removeViewAt(removedIndex);
+
         int bubbleCount = mBubbleContainer.getChildCount();
         if (bubbleCount == 0) {
             // If no bubbles remain, collapse the entire stack.
@@ -474,9 +521,9 @@
     /**
      * Dismiss the stack of bubbles.
      */
-    public void stackDismissed(int reason) {
+    void stackDismissed(int reason) {
         for (Bubble bubble : mBubbleData.getBubbles()) {
-            dismissBubble(bubble, reason);
+            setBubbleDismissed(bubble, reason);
         }
         mBubbleData.clear();
         collapseStack();
@@ -488,8 +535,7 @@
     }
 
     /**
-     * Marks the notification entry as dismissed, cleans up Bubble icon and expanded view UI
-     * elements and calls deleteIntent if necessary.
+     * Marks the notification entry as dismissed & calls any delete intents for the bubble.
      *
      * <p>Note: This does not remove the Bubble from BubbleData.
      *
@@ -497,17 +543,13 @@
      * @param reason code for the reason the dismiss was triggered
      * @see BubbleController.DismissReason
      */
-    private int dismissBubble(Bubble bubble, @DismissReason int reason) {
+    private void setBubbleDismissed(Bubble bubble, @DismissReason int reason) {
         if (DEBUG) {
             Log.d(TAG, "dismissBubble: " + bubble + " reason=" + reason);
         }
         bubble.entry.setBubbleDismissed(true);
         bubble.expandedView.cleanUpExpandedState();
 
-        // Remove it from the views
-        int removedIndex = mBubbleContainer.indexOfChild(bubble.iconView);
-        mBubbleContainer.removeViewAt(removedIndex);
-
         if (reason == BubbleController.DISMISS_USER_GESTURE) {
             Notification.BubbleMetadata bubbleMetadata = bubble.entry.getBubbleMetadata();
             PendingIntent deleteIntent = bubbleMetadata != null
@@ -522,7 +564,6 @@
                 }
             }
         }
-        return removedIndex;
     }
 
     /**
@@ -541,6 +582,7 @@
                 mBubbleContainer.moveViewTo(b.iconView, 0);
             }
             requestUpdate();
+            animateInFlyoutForBubble(b /* bubble */);
         }
         if (mIsExpanded && entry.equals(mExpandedBubble.entry)) {
             entry.setShowInShadeWhenBubble(false);
@@ -569,11 +611,18 @@
             }
             // Outside parts of view we care about.
             return null;
+        } else if (isIntersecting(mFlyout, x, y)) {
+            return mFlyout;
         }
-        // If we're collapsed, the stack is always the target.
+
+        // If it wasn't an individual bubble in the expanded state, or the flyout, it's the stack.
         return this;
     }
 
+    public View getFlyoutView() {
+        return mFlyout;
+    }
+
     /**
      * Collapses the stack of bubbles.
      * <p>
@@ -614,28 +663,29 @@
      */
     private void animateExpansion(boolean shouldExpand) {
         if (mIsExpanded != shouldExpand) {
+            hideFlyoutImmediate();
+
             mIsExpanded = shouldExpand;
             updateExpandedBubble();
             applyCurrentState();
 
-            mIsAnimating = true;
+            mIsExpansionAnimating = true;
 
             Runnable updateAfter = () -> {
                 applyCurrentState();
-                mIsAnimating = false;
+                mIsExpansionAnimating = false;
                 requestUpdate();
             };
 
             if (shouldExpand) {
                 mBubbleContainer.setController(mExpandedAnimationController);
                 mExpandedAnimationController.expandFromStack(
-                        /* collapseTo */
-                        mStackAnimationController.getStackPositionAlongNearestHorizontalEdge(),
-                        /* after */
+                        mStackAnimationController.getStackPositionAlongNearestHorizontalEdge()
+                        /* collapseTo */,
                         () -> {
                             updatePointerPosition();
                             updateAfter.run();
-                        });
+                        } /* after */);
             } else {
                 mBubbleContainer.cancelAllAnimations();
                 mExpandedAnimationController.collapseBackToStack(
@@ -700,7 +750,7 @@
 
     /** Called with the coordinates to which an individual bubble has been dragged. */
     public void onBubbleDragged(View bubble, float x, float y) {
-        if (!mIsExpanded || mIsAnimating) {
+        if (!mIsExpanded || mIsExpansionAnimating) {
             return;
         }
 
@@ -710,7 +760,7 @@
     /** Called when a drag operation on an individual bubble has finished. */
     public void onBubbleDragFinish(
             View bubble, float x, float y, float velX, float velY, boolean dismissed) {
-        if (!mIsExpanded || mIsAnimating) {
+        if (!mIsExpanded || mIsExpansionAnimating) {
             return;
         }
 
@@ -722,16 +772,19 @@
     }
 
     void onDragStart() {
-        if (mIsExpanded || mIsAnimating) {
+        if (mIsExpanded || mIsExpansionAnimating) {
             return;
         }
 
         mStackAnimationController.cancelStackPositionAnimations();
         mBubbleContainer.setController(mStackAnimationController);
+        hideFlyoutImmediate();
+
+        mIsDragging = true;
     }
 
     void onDragged(float x, float y) {
-        if (mIsExpanded || mIsAnimating) {
+        if (mIsExpanded || mIsExpansionAnimating) {
             return;
         }
 
@@ -740,8 +793,9 @@
 
     void onDragFinish(float x, float y, float velX, float velY) {
         // TODO: Add fling to bottom to dismiss.
+        mIsDragging = false;
 
-        if (mIsExpanded || mIsAnimating) {
+        if (mIsExpanded || mIsExpansionAnimating) {
             return;
         }
 
@@ -790,6 +844,47 @@
         }
     }
 
+    /**
+     * Animates in the flyout for the given bubble, if available, and then hides it after some time.
+     */
+    @VisibleForTesting
+    void animateInFlyoutForBubble(Bubble bubble) {
+        final CharSequence updateMessage = bubble.entry.getUpdateMessage(getContext());
+
+        // Show the message if one exists, and we're not expanded or animating expansion.
+        if (updateMessage != null && !isExpanded() && !mIsExpansionAnimating && !mIsDragging) {
+            final PointF stackPos = mStackAnimationController.getStackPosition();
+
+            mFlyoutText.setText(updateMessage);
+            mFlyout.measure(WRAP_CONTENT, WRAP_CONTENT);
+            mFlyout.post(() -> {
+                final boolean onLeft = mStackAnimationController.isStackOnLeftSide();
+                final float destinationX = onLeft
+                        ? stackPos.x + mBubbleSize + mBubblePadding
+                        : stackPos.x - mFlyout.getMeasuredWidth();
+
+                // Translate towards the stack slightly, then spring out from the stack.
+                mFlyout.setTranslationX(destinationX + (onLeft ? -mBubblePadding : mBubblePadding));
+                mFlyout.setTranslationY(stackPos.y);
+                mFlyout.setAlpha(0f);
+
+                mFlyout.setVisibility(VISIBLE);
+
+                mFlyout.animate().alpha(1f);
+                mFlyoutSpring.animateToFinalPosition(destinationX);
+
+                mFlyout.removeCallbacks(mHideFlyout);
+                mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
+            });
+        }
+    }
+
+    /** Hide the flyout immediately and cancel any pending hide runnables. */
+    private void hideFlyoutImmediate() {
+        mFlyout.removeCallbacks(mHideFlyout);
+        mHideFlyout.run();
+    }
+
     @Override
     public void getBoundsOnScreen(Rect outRect) {
         if (!mIsExpanded) {
@@ -799,6 +894,12 @@
         } else {
             mBubbleContainer.getBoundsOnScreen(outRect);
         }
+
+        if (mFlyout.getVisibility() == View.VISIBLE) {
+            final Rect flyoutBounds = new Rect();
+            mFlyout.getBoundsOnScreen(flyoutBounds);
+            outRect.union(flyoutBounds);
+        }
     }
 
     private int getStatusBarHeight() {
@@ -830,7 +931,7 @@
     }
 
     private void requestUpdate() {
-        if (mViewUpdatedRequested || mIsAnimating) {
+        if (mViewUpdatedRequested || mIsExpansionAnimating) {
             return;
         }
         mViewUpdatedRequested = true;
@@ -850,7 +951,6 @@
 
     private void applyCurrentState() {
         Log.d(TAG, "applyCurrentState: mIsExpanded=" + mIsExpanded);
-
         mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE);
         if (mIsExpanded) {
             // First update the view so that it calculates a new height (ensuring the y position
@@ -860,18 +960,20 @@
             if (!mExpandedViewYAnim.isRunning()) {
                 // We're not animating so set the value
                 mExpandedViewContainer.setTranslationY(y);
+                mExpandedBubble.expandedView.updateView();
             } else {
-                // We are animating so update the value
+                // We are animating so update the value; there is an end listener on the animator
+                // that will ensure expandedeView.updateView gets called.
                 mExpandedViewYAnim.animateToFinalPosition(y);
             }
-            mExpandedBubble.expandedView.updateView();
         }
 
         int bubbsCount = mBubbleContainer.getChildCount();
         for (int i = 0; i < bubbsCount; i++) {
             BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i);
             bv.updateDotVisibility();
-            bv.setZ(bubbsCount - i);
+            bv.setZ((BubbleController.MAX_BUBBLES
+                    * getResources().getDimensionPixelSize(R.dimen.bubble_elevation)) - i);
 
             // Draw the shadow around the circle inscribed within the bubble's bounds. This
             // (intentionally) does not draw a shadow behind the update dot, which should be drawing
@@ -954,7 +1056,8 @@
                     getBubbleCount(),
                     action,
                     getNormalizedXPosition(),
-                    getNormalizedYPosition());
+                    getNormalizedYPosition(),
+                    false /* unread notification */);
         } else {
             StatusBarNotification notification = bubble.entry.notification;
             StatsLog.write(StatsLog.BUBBLE_UI_CHANGED,
@@ -965,7 +1068,8 @@
                     getBubbleCount(),
                     action,
                     getNormalizedXPosition(),
-                    getNormalizedYPosition());
+                    getNormalizedYPosition(),
+                    bubble.entry.showInShadeWhenBubble());
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
index a7170d0..baeedaa 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java
@@ -86,6 +86,7 @@
         }
 
         final boolean isStack = mStack.equals(mTouchedView);
+        final boolean isFlyout = mStack.getFlyoutView().equals(mTouchedView);
         final float rawX = event.getRawX();
         final float rawY = event.getRawY();
 
@@ -96,14 +97,18 @@
             case MotionEvent.ACTION_DOWN:
                 trackMovement(event);
 
-                mDismissViewController.createDismissTarget();
-                mHandler.postDelayed(mShowDismissAffordance, SHOW_TARGET_DELAY);
-
                 mTouchDown.set(rawX, rawY);
 
+                if (!isFlyout) {
+                    mDismissViewController.createDismissTarget();
+                    mHandler.postDelayed(mShowDismissAffordance, SHOW_TARGET_DELAY);
+                }
+
                 if (isStack) {
                     mViewPositionOnTouchDown.set(mStack.getStackPosition());
                     mStack.onDragStart();
+                } else if (isFlyout) {
+                    // TODO(b/129768381): Make the flyout dismissable with a gesture.
                 } else {
                     mViewPositionOnTouchDown.set(
                             mTouchedView.getTranslationX(), mTouchedView.getTranslationY());
@@ -123,6 +128,8 @@
                 if (mMovedEnough) {
                     if (isStack) {
                         mStack.onDragged(viewX, viewY);
+                    } else if (isFlyout) {
+                        // TODO(b/129768381): Make the flyout dismissable with a gesture.
                     } else {
                         mStack.onBubbleDragged(mTouchedView, viewX, viewY);
                     }
@@ -141,6 +148,11 @@
                 trackMovement(event);
                 if (mInDismissTarget && isStack) {
                     mController.dismissStack(BubbleController.DISMISS_USER_GESTURE);
+                } else if (isFlyout) {
+                    // TODO(b/129768381): Expand if tapped, dismiss if swiped away.
+                    if (!mStack.isExpanded() && !mMovedEnough) {
+                        mStack.expandStack();
+                    }
                 } else if (mMovedEnough) {
                     mVelocityTracker.computeCurrentVelocity(/* maxVelocity */ 1000);
                     final float velX = mVelocityTracker.getXVelocity();
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
index 7a68be4..84b86bf 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
@@ -20,14 +20,13 @@
 import android.app.Notification;
 import android.content.Context;
 import android.graphics.Color;
+import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.graphics.drawable.InsetDrawable;
-import android.graphics.drawable.LayerDrawable;
 import android.util.AttributeSet;
 import android.widget.FrameLayout;
-import android.widget.TextView;
 
 import com.android.internal.graphics.ColorUtils;
 import com.android.systemui.Interpolators;
@@ -41,12 +40,14 @@
 public class BubbleView extends FrameLayout {
     private static final String TAG = "BubbleView";
 
+    private static final int DARK_ICON_ALPHA = 180;
+    private static final double ICON_MIN_CONTRAST = 4.1;
+    private static final int DEFAULT_BACKGROUND_COLOR =  Color.LTGRAY;
     // Same value as Launcher3 badge code
     private static final float WHITE_SCRIM_ALPHA = 0.54f;
     private Context mContext;
 
     private BadgedImageView mBadgedImageView;
-    private TextView mMessageView;
     private int mPadding;
     private int mIconInset;
 
@@ -75,43 +76,12 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mBadgedImageView = (BadgedImageView) findViewById(R.id.bubble_image);
-        mMessageView = (TextView) findViewById(R.id.message_view);
-        mMessageView.setVisibility(GONE);
-        mMessageView.setPivotX(0);
+        mBadgedImageView = findViewById(R.id.bubble_image);
     }
 
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        updateViews();
-    }
-
-    @Override
-    protected void onMeasure(int widthSpec, int heightSpec) {
-        measureChild(mBadgedImageView, widthSpec, heightSpec);
-        measureChild(mMessageView, widthSpec, heightSpec);
-        boolean messageGone = mMessageView.getVisibility() == GONE;
-        int imageHeight = mBadgedImageView.getMeasuredHeight();
-        int imageWidth = mBadgedImageView.getMeasuredWidth();
-        int messageHeight = messageGone ? 0 : mMessageView.getMeasuredHeight();
-        int messageWidth = messageGone ? 0 : mMessageView.getMeasuredWidth();
-        setMeasuredDimension(
-                getPaddingStart() + imageWidth + mPadding + messageWidth + getPaddingEnd(),
-                getPaddingTop() + Math.max(imageHeight, messageHeight) + getPaddingBottom());
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        left = getPaddingStart();
-        top = getPaddingTop();
-        int imageWidth = mBadgedImageView.getMeasuredWidth();
-        int imageHeight = mBadgedImageView.getMeasuredHeight();
-        int messageWidth = mMessageView.getMeasuredWidth();
-        int messageHeight = mMessageView.getMeasuredHeight();
-        mBadgedImageView.layout(left, top, left + imageWidth, top + imageHeight);
-        mMessageView.layout(left + imageWidth + mPadding, top,
-                left + imageWidth + mPadding + messageWidth, top + messageHeight);
     }
 
     /**
@@ -206,12 +176,7 @@
         }
         Drawable iconDrawable = ic.loadDrawable(mContext);
         if (needsTint) {
-            // Center icon on coloured background
-            iconDrawable.setTint(Color.WHITE); // TODO: dark mode
-            Drawable bg = new ColorDrawable(n.color);
-            InsetDrawable d = new InsetDrawable(iconDrawable, mIconInset);
-            Drawable[] layers = {bg, d};
-            mBadgedImageView.setImageDrawable(new LayerDrawable(layers));
+            mBadgedImageView.setImageDrawable(buildIconWithTint(iconDrawable, n.color));
         } else {
             mBadgedImageView.setImageDrawable(iconDrawable);
         }
@@ -220,6 +185,23 @@
         animateDot(mEntry.showInShadeWhenBubble() /* showDot */);
     }
 
+    private Drawable buildIconWithTint(Drawable iconDrawable, int backgroundColor) {
+        backgroundColor = ColorUtils.setAlphaComponent(backgroundColor, 255 /* alpha */);
+        if (backgroundColor == Color.TRANSPARENT) {
+            // ColorUtils throws exception when background is translucent.
+            backgroundColor = DEFAULT_BACKGROUND_COLOR;
+        }
+        iconDrawable.setTint(Color.WHITE);
+        double contrastRatio = ColorUtils.calculateContrast(Color.WHITE, backgroundColor);
+        if (contrastRatio < ICON_MIN_CONTRAST) {
+            int dark = ColorUtils.setAlphaComponent(Color.BLACK, DARK_ICON_ALPHA);
+            iconDrawable.setTint(dark);
+        }
+        InsetDrawable foreground = new InsetDrawable(iconDrawable, mIconInset);
+        ColorDrawable background = new ColorDrawable(backgroundColor);
+        return new AdaptiveIconDrawable(background, foreground);
+    }
+
     private int determineDominateColor(Drawable d, int defaultTint) {
         // XXX: should we pull from the drawable, app icon, notif tint?
         return ColorUtils.blendARGB(defaultTint, Color.WHITE, WHITE_SCRIM_ALPHA);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
index 8731b6b..0f659c3 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
@@ -799,4 +799,9 @@
             }
         }
     }
+
+    @Override
+    protected boolean canReceivePointerEvents() {
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
index c395031..78c4fc1 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
@@ -157,6 +157,15 @@
         return mStackPosition;
     }
 
+    /** Whether the stack is on the left side of the screen. */
+    public boolean isStackOnLeftSide() {
+        if (mLayout != null) {
+            return mStackPosition.x - mIndividualBubbleSize / 2 < mLayout.getWidth() / 2;
+        } else {
+            return false;
+        }
+    }
+
     /**
      * Flings the stack starting with the given velocities, springing it to the nearest edge
      * afterward.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
index a4592d5..3c6dc73 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
@@ -87,7 +87,8 @@
     }
 
     private void requestPulseOutNow(State dozeState) {
-        if (dozeState == State.DOZE_REQUEST_PULSE || dozeState == State.DOZE_PULSING) {
+        if (dozeState == State.DOZE_REQUEST_PULSE || dozeState == State.DOZE_PULSING
+                || dozeState == State.DOZE_PULSING_BRIGHT) {
             final int pulseReason = mMachine.getPulseReason();
             if (pulseReason == DozeLog.PULSE_REASON_DOCKING) {
                 mDozeHost.stopPulsing();
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 36e28dc..0607654 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -71,7 +71,7 @@
                 new DozeScreenState(wrappedService, handler, params, wakeLock),
                 createDozeScreenBrightness(context, wrappedService, sensorManager, host, params,
                         handler),
-                new DozeWallpaperState(context, machine),
+                new DozeWallpaperState(context),
                 new DozeDockHandler(context, machine, host, config, handler, dockManager)
         });
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index bd7a421..3c9d4a9 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -33,7 +33,11 @@
     boolean isProvisioned();
     boolean isBlockingDoze();
 
-    void extendPulse();
+    /**
+     * Makes a current pulse last for twice as long.
+     * @param reason why we're extending it.
+     */
+    void extendPulse(int reason);
 
     void setAnimateWakeup(boolean animateWakeup);
     void setAnimateScreenOff(boolean animateScreenOff);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index c243899..8bf2256 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -59,6 +59,8 @@
         DOZE_REQUEST_PULSE,
         /** Pulse is showing. Device is awake and showing UI. */
         DOZE_PULSING,
+        /** Pulse is showing with bright wallpaper. Device is awake and showing UI. */
+        DOZE_PULSING_BRIGHT,
         /** Pulse is done showing. Followed by transition to DOZE or DOZE_AOD. */
         DOZE_PULSE_DONE,
         /** Doze is done. DozeService is finished. */
@@ -84,6 +86,7 @@
             switch (this) {
                 case DOZE_REQUEST_PULSE:
                 case DOZE_PULSING:
+                case DOZE_PULSING_BRIGHT:
                     return true;
                 default:
                     return false;
@@ -101,6 +104,7 @@
                 case DOZE:
                     return Display.STATE_OFF;
                 case DOZE_PULSING:
+                case DOZE_PULSING_BRIGHT:
                     return Display.STATE_ON;
                 case DOZE_AOD:
                 case DOZE_AOD_PAUSING:
@@ -188,7 +192,10 @@
     @MainThread
     public State getState() {
         Assert.isMainThread();
-        Preconditions.checkState(!isExecutingTransition());
+        if (isExecutingTransition()) {
+            throw new IllegalStateException("Cannot get state because there were pending "
+                    + "transitions: " + mQueuedRequests.toString());
+        }
         return mState;
     }
 
@@ -202,6 +209,7 @@
         Assert.isMainThread();
         Preconditions.checkState(mState == State.DOZE_REQUEST_PULSE
                 || mState == State.DOZE_PULSING
+                || mState == State.DOZE_PULSING_BRIGHT
                 || mState == State.DOZE_PULSE_DONE, "must be in pulsing state, but is " + mState);
         return mPulseReason;
     }
@@ -283,7 +291,8 @@
                     break;
                 case DOZE_PULSE_DONE:
                     Preconditions.checkState(
-                            mState == State.DOZE_REQUEST_PULSE || mState == State.DOZE_PULSING);
+                            mState == State.DOZE_REQUEST_PULSE || mState == State.DOZE_PULSING
+                                    || mState == State.DOZE_PULSING_BRIGHT);
                     break;
                 default:
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index 1dd3101..bd6882c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -56,6 +56,7 @@
     private boolean mRegistered;
     private int mDefaultDozeBrightness;
     private boolean mPaused = false;
+    private boolean mScreenOff = false;
     private int mLastSensorValue = -1;
 
     /**
@@ -118,6 +119,7 @@
                 break;
         }
         if (newState != DozeMachine.State.FINISH) {
+            setScreenOff(newState == DozeMachine.State.DOZE);
             setPaused(newState == DozeMachine.State.DOZE_AOD_PAUSED);
         }
     }
@@ -135,15 +137,15 @@
         try {
             if (mRegistered) {
                 mLastSensorValue = (int) event.values[0];
-                updateBrightnessAndReady();
+                updateBrightnessAndReady(false /* force */);
             }
         } finally {
             Trace.endSection();
         }
     }
 
-    private void updateBrightnessAndReady() {
-        if (mRegistered || mDebugBrightnessBucket != -1) {
+    private void updateBrightnessAndReady(boolean force) {
+        if (force || mRegistered || mDebugBrightnessBucket != -1) {
             int sensorValue = mDebugBrightnessBucket == -1
                     ? mLastSensorValue : mDebugBrightnessBucket;
             int brightness = computeBrightness(sensorValue);
@@ -153,7 +155,7 @@
             }
 
             int scrimOpacity = -1;
-            if (mPaused) {
+            if (mPaused || mScreenOff) {
                 // If AOD is paused, force the screen black until the
                 // sensor reports a new brightness. This ensures that when the screen comes on
                 // again, it will only show after the brightness sensor has stabilized,
@@ -216,13 +218,20 @@
     private void setPaused(boolean paused) {
         if (mPaused != paused) {
             mPaused = paused;
-            updateBrightnessAndReady();
+            updateBrightnessAndReady(false /* force */);
+        }
+    }
+
+    private void setScreenOff(boolean screenOff) {
+        if (mScreenOff != screenOff) {
+            mScreenOff = screenOff;
+            updateBrightnessAndReady(true /* force */);
         }
     }
 
     @Override
     public void onReceive(Context context, Intent intent) {
         mDebugBrightnessBucket = intent.getIntExtra(BRIGHTNESS_BUCKET, -1);
-        updateBrightnessAndReady();
+        updateBrightnessAndReady(false /* force */);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 7189a48..0fe6611 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.doze;
 
+import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.app.UiModeManager;
 import android.content.BroadcastReceiver;
@@ -147,7 +148,7 @@
         boolean wakeEvent = rawValues != null && rawValues.length > 0 && rawValues[0] != 0;
 
         if (isWakeDisplay) {
-            onWakeScreen(wakeEvent, mMachine.getState());
+            onWakeScreen(wakeEvent, mMachine.isExecutingTransition() ? null : mMachine.getState());
         } else if (isLongPress) {
             requestPulse(pulseReason, sensorPerformedProxCheck);
         } else if (isWakeLockScreen) {
@@ -168,7 +169,7 @@
                 } else if (isPickup) {
                     gentleWakeUp(pulseReason);
                 } else {
-                    mDozeHost.extendPulse();
+                    mDozeHost.extendPulse(pulseReason);
                 }
             }, sensorPerformedProxCheck
                     || (mDockManager != null && mDockManager.isDocked()), pulseReason);
@@ -212,7 +213,8 @@
         final boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
         final boolean aod = (state == DozeMachine.State.DOZE_AOD);
 
-        if (state == DozeMachine.State.DOZE_PULSING) {
+        if (state == DozeMachine.State.DOZE_PULSING
+                || state == DozeMachine.State.DOZE_PULSING_BRIGHT) {
             boolean ignoreTouch = near;
             if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
             mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
@@ -227,10 +229,14 @@
         }
     }
 
-    private void onWakeScreen(boolean wake, DozeMachine.State state) {
+    /**
+     * When a wake screen event is received from a sensor
+     * @param wake {@code true} when it's time to wake up, {@code false} when we should sleep.
+     * @param state The current state, or null if the state could not be determined due to enqueued
+     *              transitions.
+     */
+    private void onWakeScreen(boolean wake, @Nullable DozeMachine.State state) {
         DozeLog.traceWakeDisplay(wake);
-        boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
-        boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
         sWakeDisplaySensorState = wake;
 
         if (wake) {
@@ -244,6 +250,8 @@
                 }
             }, false /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP);
         } else {
+            boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
+            boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING);
             if (!pausing && !paused) {
                 mMachine.requestState(DozeMachine.State.DOZE);
             }
@@ -276,6 +284,7 @@
                 mDozeSensors.setListening(false);
                 break;
             case DOZE_PULSING:
+            case DOZE_PULSING_BRIGHT:
                 mDozeSensors.setTouchscreenSensorsListening(false);
                 mDozeSensors.setProxListening(true);
                 break;
@@ -306,7 +315,16 @@
 
     private void requestPulse(final int reason, boolean performedProxCheck) {
         Assert.isMainThread();
-        mDozeHost.extendPulse();
+        mDozeHost.extendPulse(reason);
+
+        // When already pulsing we're allowed to show the wallpaper directly without
+        // requesting a new pulse.
+        if (mMachine.getState() == DozeMachine.State.DOZE_PULSING
+                && reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
+            mMachine.requestState(DozeMachine.State.DOZE_PULSING_BRIGHT);
+            return;
+        }
+
         if (mPulsePending || !mAllowPulseTriggers || !canPulse()) {
             if (mAllowPulseTriggers) {
                 DozeLog.tracePulseDropped(mContext, mPulsePending, mMachine.getState(),
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 847182d..51e96d2 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -94,7 +94,10 @@
                     @Override
                     public void onPulseStarted() {
                         try {
-                            mMachine.requestState(DozeMachine.State.DOZE_PULSING);
+                            mMachine.requestState(
+                                    reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
+                                            ? DozeMachine.State.DOZE_PULSING_BRIGHT
+                                            : DozeMachine.State.DOZE_PULSING);
                         } catch (IllegalStateException e) {
                             // It's possible that the pulse was asynchronously cancelled while
                             // we were waiting for it to start (under stress conditions.)
@@ -148,6 +151,7 @@
         switch (state) {
             case DOZE_REQUEST_PULSE:
             case DOZE_PULSING:
+            case DOZE_PULSING_BRIGHT:
             case DOZE_PULSE_DONE:
                 mHost.setAnimateWakeup(true);
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
index ca9f24f..1b3cd88 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
@@ -38,19 +38,17 @@
 
     private final IWallpaperManager mWallpaperManagerService;
     private final DozeParameters mDozeParameters;
-    private final DozeMachine mMachine;
     private boolean mIsAmbientMode;
 
-    public DozeWallpaperState(Context context, DozeMachine machine) {
-        this(machine, IWallpaperManager.Stub.asInterface(
+    public DozeWallpaperState(Context context) {
+        this(IWallpaperManager.Stub.asInterface(
                 ServiceManager.getService(Context.WALLPAPER_SERVICE)),
                 DozeParameters.getInstance(context));
     }
 
     @VisibleForTesting
-    DozeWallpaperState(DozeMachine machine, IWallpaperManager wallpaperManagerService,
+    DozeWallpaperState(IWallpaperManager wallpaperManagerService,
             DozeParameters parameters) {
-        mMachine = machine;
         mWallpaperManagerService = wallpaperManagerService;
         mDozeParameters = parameters;
     }
@@ -65,16 +63,13 @@
             case DOZE_AOD_PAUSED:
             case DOZE_REQUEST_PULSE:
             case DOZE_PULSE_DONE:
+            case DOZE_PULSING:
                 isAmbientMode = true;
                 break;
-            case DOZE_PULSING:
-                isAmbientMode =
-                        mMachine.getPulseReason() != DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN;
-                break;
+            case DOZE_PULSING_BRIGHT:
             default:
                 isAmbientMode = false;
         }
-
         final boolean animated;
         if (isAmbientMode) {
             animated = mDozeParameters.shouldControlScreenOff();
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index f07887e..dcacd0f 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -439,6 +439,9 @@
     @Override
     public void onUiModeChanged() {
         mContext.getTheme().applyStyle(mContext.getThemeResId(), true);
+        if (mDialog.isShowing()) {
+            mDialog.refreshDialog();
+        }
     }
 
     public void destroy() {
@@ -1577,7 +1580,9 @@
 
             boolean panelEnabled = initializePanel();
             if (!panelEnabled) {
-                mBackgroundDrawable = new GradientDrawable(mContext);
+                if (mBackgroundDrawable == null) {
+                    mBackgroundDrawable = new GradientDrawable(mContext);
+                }
                 mScrimAlpha = ScrimController.GRADIENT_SCRIM_ALPHA;
             } else {
                 mBackgroundDrawable = mContext.getDrawable(
@@ -1720,10 +1725,14 @@
             mKeyguardShowing = keyguardShowing;
         }
 
+        public void refreshDialog() {
+            initializeLayout();
+            mGlobalActionsLayout.updateList();
+        }
+
         public void onRotate(int from, int to) {
             if (mShowing && isGridEnabled(mContext)) {
-                initializeLayout();
-                mGlobalActionsLayout.updateList();
+                refreshDialog();
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index b03b872..6f50baa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -286,8 +286,9 @@
         RowBuilder dndBuilder = new RowBuilder(mDndUri)
                 .setContentDescription(getContext().getResources()
                         .getString(R.string.accessibility_quick_settings_dnd))
-                .addEndItem(IconCompat.createWithResource(getContext(), R.drawable.stat_sys_dnd),
-                        ListBuilder.ICON_IMAGE);
+                .addEndItem(
+                    IconCompat.createWithResource(getContext(), R.drawable.stat_sys_dnd),
+                    ListBuilder.ICON_IMAGE);
         builder.addRow(dndBuilder);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 3140e6d..3ec6cb7 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -795,7 +795,10 @@
                 ? mExpandedMovementBounds
                 : mNormalMovementBounds;
         try {
-            mPinnedStackController.setMinEdgeSize(isMenuExpanded ? mExpandedShortestEdgeSize : 0);
+            if (mPinnedStackController != null) {
+                mPinnedStackController.setMinEdgeSize(
+                        isMenuExpanded ? mExpandedShortestEdgeSize : 0);
+            }
         } catch (RemoteException e) {
             Log.e(TAG, "Could not set minimized state", e);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt b/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
index d7a2d9a..02ad0f1 100644
--- a/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
+++ b/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
@@ -17,7 +17,8 @@
     val timeRemainingMillis: Long,
     val severeThresholdMillis: Long,
     val lowThresholdMillis: Long,
-    val isBasedOnUsage: Boolean
+    val isBasedOnUsage: Boolean,
+    val isLowWarningEnabled: Boolean
 ) {
     /**
      * Returns whether hybrid warning logic/copy should be used for this snapshot
@@ -48,7 +49,8 @@
         NO_ESTIMATE_AVAILABLE.toLong(),
         NO_ESTIMATE_AVAILABLE.toLong(),
         NO_ESTIMATE_AVAILABLE.toLong(),
-        false
+        false,
+        true
     ) {
         this.isHybrid = false
     }
diff --git a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java
index bd130f4..a879227 100644
--- a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java
+++ b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimates.java
@@ -23,4 +23,9 @@
      * show a severe warning to the user.
      */
     long getSevereWarningThreshold();
+
+    /**
+     * Returns a boolean indicating if the low warning should be shown at all or not.
+     */
+    boolean getLowWarningEnabled();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
index 3f24176..bfb809e 100644
--- a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java
@@ -21,4 +21,9 @@
     public long getSevereWarningThreshold() {
         return 0;
     }
+
+    @Override
+    public boolean getLowWarningEnabled() {
+        return true;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 41bcab5..10f727b 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -31,6 +31,7 @@
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.UserHandle;
+import android.provider.Settings.Secure;
 import android.text.Annotation;
 import android.text.Layout;
 import android.text.SpannableString;
@@ -70,6 +71,7 @@
  */
 @Singleton
 public class PowerNotificationWarnings implements PowerUI.WarningsUI {
+
     private static final String TAG = PowerUI.TAG + ".Notification";
     private static final boolean DEBUG = PowerUI.DEBUG;
 
@@ -119,6 +121,7 @@
             .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
             .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
             .build();
+    public static final String EXTRA_CONFIRM_ONLY = "extra_confirm_only";
 
     private final Context mContext;
     private final NotificationManager mNoMan;
@@ -544,10 +547,9 @@
         updateNotification();
     }
 
-    private void showStartSaverConfirmation() {
+    private void showStartSaverConfirmation(boolean confirmOnly) {
         if (mSaverConfirmation != null) return;
         final SystemUIDialog d = new SystemUIDialog(mContext);
-        d.setTitle(R.string.battery_saver_confirmation_title);
         d.setMessage(getBatterySaverDescription());
 
         // Sad hack for http://b/78261259 and http://b/78298335. Otherwise "Battery" may be split
@@ -558,9 +560,19 @@
         // We need to set LinkMovementMethod to make the link clickable.
         d.setMessageMovementMethod(LinkMovementMethod.getInstance());
 
-        d.setNegativeButton(android.R.string.cancel, null);
-        d.setPositiveButton(R.string.battery_saver_confirmation_ok,
+        if (confirmOnly) {
+            d.setTitle(R.string.battery_saver_confirmation_title_generic);
+            d.setPositiveButton(com.android.internal.R.string.confirm_battery_saver,
+                    (dialog, which) -> Secure.putInt(
+                            mContext.getContentResolver(),
+                            Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
+                            1));
+        } else {
+            d.setTitle(R.string.battery_saver_confirmation_title);
+            d.setPositiveButton(R.string.battery_saver_confirmation_ok,
                 (dialog, which) -> setSaverMode(true, false));
+            d.setNegativeButton(android.R.string.cancel, null);
+        }
         d.setShowForAllUsers(true);
         d.setOnDismissListener((dialog) -> mSaverConfirmation = null);
         d.show();
@@ -719,7 +731,7 @@
                 dismissLowBatteryNotification();
             } else if (action.equals(ACTION_SHOW_START_SAVER_CONFIRMATION)) {
                 dismissLowBatteryNotification();
-                showStartSaverConfirmation();
+                showStartSaverConfirmation(intent.getBooleanExtra(EXTRA_CONFIRM_ONLY, false));
             } else if (action.equals(ACTION_DISMISSED_WARNING)) {
                 dismissLowBatteryWarning();
             } else if (ACTION_CLICKED_TEMP_WARNING.equals(action)) {
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 1863860..4e41108 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -284,7 +284,8 @@
                     plugged, bucket, mBatteryStatus, mLowBatteryReminderLevels[1],
                     mLowBatteryReminderLevels[0], estimate.getEstimateMillis(),
                     mEnhancedEstimates.getSevereWarningThreshold(),
-                    mEnhancedEstimates.getLowWarningThreshold(), estimate.isBasedOnUsage());
+                    mEnhancedEstimates.getLowWarningThreshold(), estimate.isBasedOnUsage(),
+                    mEnhancedEstimates.getLowWarningEnabled());
         } else {
             if (DEBUG) {
                 Slog.d(TAG, "using standard");
@@ -351,7 +352,6 @@
                 Slog.d(TAG, "Low warning marked as shown this cycle");
                 mLowWarningShownThisChargeCycle = true;
             }
-
         } else if (shouldDismissHybridWarning(currentSnapshot)) {
             if (DEBUG) {
                 Slog.d(TAG, "Dismissing warning");
@@ -375,8 +375,9 @@
             return false;
         }
 
-        // Only show the low warning once per charge cycle & no battery saver
-        final boolean canShowWarning = !mLowWarningShownThisChargeCycle && !snapshot.isPowerSaver()
+        // Only show the low warning if enabled once per charge cycle & no battery saver
+        final boolean canShowWarning = snapshot.isLowWarningEnabled()
+                && !mLowWarningShownThisChargeCycle && !snapshot.isPowerSaver()
                 && (snapshot.getTimeRemainingMillis() < snapshot.getLowThresholdMillis()
                 || snapshot.getBatteryLevel() <= snapshot.getLowLevelThreshold());
 
@@ -386,6 +387,7 @@
                 || snapshot.getBatteryLevel() <= snapshot.getSevereLevelThreshold());
 
         final boolean canShow = canShowWarning || canShowSevereWarning;
+
         if (DEBUG) {
             Slog.d(TAG, "Enhanced trigger is: " + canShow + "\nwith battery snapshot:"
                     + " mLowWarningShownThisChargeCycle: " + mLowWarningShownThisChargeCycle
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
index 59b3c34..d08a373 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
@@ -53,9 +53,4 @@
             else -> types.map { it.getName(context) }.joinWithAnd().toString()
         }
     }
-
-    fun getDialogTitle(): String {
-        return context.getString(R.string.ongoing_privacy_dialog_multiple_apps_title,
-                    joinTypes())
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 76dfddb..bb159a9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -62,6 +62,7 @@
     private int mLayoutOrientation;
     private int mLayoutDirection;
     private int mHorizontalClipBound;
+    private final Rect mClippingRect;
 
     public PagedTileLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -71,6 +72,7 @@
         setCurrentItem(0, false);
         mLayoutOrientation = getResources().getConfiguration().orientation;
         mLayoutDirection = getLayoutDirection();
+        mClippingRect = new Rect();
     }
 
     public void saveInstanceState(Bundle outState) {
@@ -280,8 +282,8 @@
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
-        Rect clipBounds = new Rect(mHorizontalClipBound, 0, (r-l) - mHorizontalClipBound, b - t);
-        setClipBounds(clipBounds);
+        mClippingRect.set(mHorizontalClipBound, 0, (r - l) - mHorizontalClipBound, b - t);
+        setClipBounds(mClippingRect);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index 10eacba..644664e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -22,7 +22,6 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.graphics.PorterDuff.Mode;
@@ -320,29 +319,13 @@
         mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
                 TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
         final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
-        mMultiUserSwitch.setVisibility(showUserSwitcher(isDemo) ? View.VISIBLE : View.INVISIBLE);
+        mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.INVISIBLE);
         mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
         mSettingsButton.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
     }
 
-    private boolean showUserSwitcher(boolean isDemo) {
-        if (!mExpanded || isDemo || !UserManager.supportsMultipleUsers()) {
-            return false;
-        }
-        UserManager userManager = UserManager.get(mContext);
-        if (userManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)) {
-            return false;
-        }
-        int switchableUserCount = 0;
-        for (UserInfo user : userManager.getUsers(true)) {
-            if (user.supportsSwitchToByUser()) {
-                ++switchableUserCount;
-                if (switchableUserCount > 1) {
-                    return true;
-                }
-            }
-        }
-        return getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user);
+    private boolean showUserSwitcher() {
+        return mExpanded && mMultiUserSwitch.isMultiUserEnabled();
     }
 
     private void updateListeners() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index b93f8d04..d6e0306 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -118,7 +118,6 @@
         updateResources();
 
         mBrightnessController = new BrightnessController(getContext(),
-                findViewById(R.id.brightness_icon),
                 findViewById(R.id.brightness_slider));
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index 7c937a9..b682cb0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -160,9 +160,9 @@
         int footerIconId = R.drawable.ic_info_outline;
         if (vpnName != null || vpnNameWorkProfile != null) {
             if (mSecurityController.isVpnBranded()) {
-                footerIconId = R.drawable.ic_qs_branded_vpn;
+                footerIconId = R.drawable.stat_sys_branded_vpn;
             } else {
-                footerIconId = R.drawable.ic_qs_vpn;
+                footerIconId = R.drawable.stat_sys_vpn_ic;
             }
         }
         if (mFooterIconId != footerIconId) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 608f646..8ed5424 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -113,6 +113,7 @@
 
     public void saveSpecs(QSTileHost host) {
         List<String> newSpecs = new ArrayList<>();
+        clearAccessibilityState();
         for (int i = 1; i < mTiles.size() && mTiles.get(i) != null; i++) {
             newSpecs.add(mTiles.get(i).spec);
         }
@@ -120,6 +121,17 @@
         mCurrentSpecs = newSpecs;
     }
 
+    private void clearAccessibilityState() {
+        if (mAccessibilityAction == ACTION_ADD) {
+            // Remove blank tile from last spot
+            mTiles.remove(--mEditIndex);
+            // Update the tile divider position
+            mTileDividerIndex--;
+            notifyDataSetChanged();
+        }
+        mAccessibilityAction = ACTION_NONE;
+    }
+
     public void resetTileSpecs(QSTileHost host, List<String> specs) {
         // Notify the host so the tiles get removed callbacks.
         host.changeTiles(mCurrentSpecs, specs);
@@ -333,8 +345,6 @@
             // Remove the placeholder.
             mTiles.remove(mEditIndex--);
             notifyItemRemoved(mEditIndex);
-            // Don't remove items when the last position is selected.
-            if (position == mEditIndex - 1) position--;
         }
         mAccessibilityAction = ACTION_NONE;
         move(mAccessibilityFromIndex, position, v);
@@ -372,6 +382,8 @@
         mAccessibilityAction = ACTION_ADD;
         // Add placeholder for last slot.
         mTiles.add(mEditIndex++, null);
+        // Update the tile divider position
+        mTileDividerIndex++;
         mNeedsFocus = true;
         notifyDataSetChanged();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 387de71..19e20a9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -43,8 +43,7 @@
 
 /** Quick settings tile: Airplane mode **/
 public class AirplaneModeTile extends QSTileImpl<BooleanState> {
-    private final Icon mIcon =
-            ResourceIcon.get(R.drawable.ic_signal_airplane);
+    private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_airplane);
     private final GlobalSetting mSetting;
     private final ActivityStarter mActivityStarter;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 5b85498..ca04076 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -147,14 +147,15 @@
                 state.icon = ResourceIcon.get(R.drawable.ic_bluetooth_transient_animation);
                 state.contentDescription = state.secondaryLabel;
             } else {
-                state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);
+                state.icon =
+                        ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth);
                 state.contentDescription = mContext.getString(
                         R.string.accessibility_quick_settings_bluetooth) + ","
                         + mContext.getString(R.string.accessibility_not_connected);
             }
             state.state = Tile.STATE_ACTIVE;
         } else {
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_on);
+            state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_bluetooth);
             state.contentDescription = mContext.getString(
                     R.string.accessibility_quick_settings_bluetooth);
             state.state = Tile.STATE_INACTIVE;
@@ -288,7 +289,7 @@
             // This method returns Pair<Drawable, String> while first value is the drawable
             return BluetoothDeviceLayerDrawable.createLayerDrawable(
                     context,
-                    R.drawable.ic_qs_bluetooth_connected,
+                    R.drawable.ic_bluetooth_connected,
                     mBatteryLevel,
                     mIconScale);
         }
@@ -309,7 +310,7 @@
         @Override
         public Drawable getDrawable(Context context) {
             // This method returns Pair<Drawable, String> - the first value is the drawable.
-            return context.getDrawable(R.drawable.ic_qs_bluetooth_connected);
+            return context.getDrawable(R.drawable.ic_bluetooth_connected);
         }
     }
 
@@ -383,12 +384,12 @@
                 for (CachedBluetoothDevice device : devices) {
                     if (mController.getBondState(device) == BluetoothDevice.BOND_NONE) continue;
                     final Item item = new Item();
-                    item.iconResId = R.drawable.ic_qs_bluetooth_on;
+                    item.iconResId = com.android.internal.R.drawable.ic_qs_bluetooth;
                     item.line1 = device.getName();
                     item.tag = device;
                     int state = device.getMaxConnectionState();
                     if (state == BluetoothProfile.STATE_CONNECTED) {
-                        item.iconResId = R.drawable.ic_qs_bluetooth_connected;
+                        item.iconResId = R.drawable.ic_bluetooth_connected;
                         int batteryLevel = device.getBatteryLevel();
                         if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
                             item.icon = new BluetoothBatteryTileIcon(batteryLevel,1 /* iconScale */);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index bdebf79..b1dfbb5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -21,7 +21,7 @@
 import android.app.Dialog;
 import android.content.Context;
 import android.content.Intent;
-import android.media.projection.MediaProjectionInfo;
+import android.media.MediaRouter.RouteInfo;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.util.Log;
@@ -48,8 +48,9 @@
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.NetworkController;
 
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
-import java.util.Set;
+import java.util.List;
 
 import javax.inject.Inject;
 
@@ -128,35 +129,30 @@
             return;
         }
 
-        CastDevice activeProjection = getActiveDeviceMediaProjection();
-        if (activeProjection == null) {
-            if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
-                mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
-                    showDetail(true);
-                });
-            } else {
+        List<CastDevice> activeDevices = getActiveDevices();
+        // We want to pop up the media route selection dialog if we either have no active devices
+        // (neither routes nor projection), or if we have an active route. In other cases, we assume
+        // that a projection is active. This is messy, but this tile never correctly handled the
+        // case where multiple devices were active :-/.
+        if (activeDevices.isEmpty() || (activeDevices.get(0).tag instanceof RouteInfo)) {
+            mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
                 showDetail(true);
-            }
+            });
         } else {
-            mController.stopCasting(activeProjection);
+            mController.stopCasting(activeDevices.get(0));
         }
     }
 
-    private CastDevice getActiveDeviceMediaProjection() {
-        CastDevice activeDevice = null;
+    private List<CastDevice> getActiveDevices() {
+        ArrayList<CastDevice> activeDevices = new ArrayList<>();
         for (CastDevice device : mController.getCastDevices()) {
             if (device.state == CastDevice.STATE_CONNECTED
                     || device.state == CastDevice.STATE_CONNECTING) {
-                activeDevice = device;
-                break;
+                activeDevices.add(device);
             }
         }
 
-        if (activeDevice != null && activeDevice.tag instanceof MediaProjectionInfo) {
-            return activeDevice;
-        }
-
-        return null;
+        return activeDevices;
     }
 
     @Override
@@ -187,14 +183,18 @@
         state.label = mContext.getString(R.string.quick_settings_cast_title);
         state.contentDescription = state.label;
         state.value = false;
-        final Set<CastDevice> devices = mController.getCastDevices();
+        final List<CastDevice> devices = mController.getCastDevices();
         boolean connecting = false;
+        // We always choose the first device that's in the CONNECTED state in the case where
+        // multiple devices are CONNECTED at the same time.
         for (CastDevice device : devices) {
             if (device.state == CastDevice.STATE_CONNECTED) {
                 state.value = true;
                 state.secondaryLabel = getDeviceName(device);
                 state.contentDescription = state.contentDescription + "," +
                         mContext.getString(R.string.accessibility_cast_name, state.label);
+                connecting = false;
+                break;
             } else if (device.state == CastDevice.STATE_CONNECTING) {
                 connecting = true;
             }
@@ -202,8 +202,8 @@
         if (connecting && !state.value) {
             state.secondaryLabel = mContext.getString(R.string.quick_settings_connecting);
         }
-        state.icon = ResourceIcon.get(state.value ? R.drawable.ic_qs_cast_on
-                : R.drawable.ic_qs_cast_off);
+        state.icon = ResourceIcon.get(state.value ? R.drawable.ic_cast_connected
+                : R.drawable.ic_cast);
         if (mWifiConnected || state.value) {
             state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
             if (!state.value) {
@@ -326,7 +326,7 @@
             return mItems;
         }
 
-        private void updateItems(Set<CastDevice> devices) {
+        private void updateItems(List<CastDevice> devices) {
             if (mItems == null) return;
             Item[] items = null;
             if (devices != null && !devices.isEmpty()) {
@@ -334,7 +334,7 @@
                 for (CastDevice device : devices) {
                     if (device.state == CastDevice.STATE_CONNECTED) {
                         final Item item = new Item();
-                        item.iconResId = R.drawable.ic_qs_cast_on;
+                        item.iconResId = R.drawable.ic_cast_connected;
                         item.line1 = getDeviceName(device);
                         item.line2 = mContext.getString(R.string.quick_settings_connected);
                         item.tag = device;
@@ -354,7 +354,7 @@
                         final CastDevice device = mVisibleOrder.get(id);
                         if (!devices.contains(device)) continue;
                         final Item item = new Item();
-                        item.iconResId = R.drawable.ic_qs_cast_off;
+                        item.iconResId = R.drawable.ic_cast;
                         item.line1 = getDeviceName(device);
                         if (device.state == CastDevice.STATE_CONNECTING) {
                             item.line2 = mContext.getString(R.string.quick_settings_connecting);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index c587a39..38962eb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -25,11 +25,7 @@
 import android.content.res.Resources;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
 import android.text.TextUtils;
-import android.text.style.TextAppearanceSpan;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -49,7 +45,6 @@
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
-import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -66,15 +61,13 @@
 
     private final CellSignalCallback mSignalCallback = new CellSignalCallback();
     private final ActivityStarter mActivityStarter;
-    private final KeyguardMonitor mKeyguardMonitor;
 
     @Inject
     public CellularTile(QSHost host, NetworkController networkController,
-            ActivityStarter activityStarter, KeyguardMonitor keyguardMonitor) {
+            ActivityStarter activityStarter) {
         super(host);
         mController = networkController;
         mActivityStarter = activityStarter;
-        mKeyguardMonitor = keyguardMonitor;
         mDataController = mController.getMobileDataController();
         mDetailAdapter = new CellularDetailAdapter();
         mController.observe(getLifecycle(), mSignalCallback);
@@ -110,11 +103,7 @@
             return;
         }
         if (mDataController.isMobileDataEnabled()) {
-            if (mKeyguardMonitor.isSecure() && !mKeyguardMonitor.canSkipBouncer()) {
-                mActivityStarter.postQSRunnableDismissingKeyguard(this::maybeShowDisableDialog);
-            } else {
-                mUiHandler.post(this::maybeShowDisableDialog);
-            }
+            maybeShowDisableDialog();
         } else {
             mDataController.setMobileDataEnabled(true);
         }
@@ -192,8 +181,10 @@
             state.secondaryLabel = r.getString(R.string.status_bar_airplane);
         } else if (mobileDataEnabled) {
             state.state = Tile.STATE_ACTIVE;
-            state.secondaryLabel = appendMobileDataType(getMobileDataSubscriptionName(cb),
-                    cb.dataContentDescription);
+            state.secondaryLabel = appendMobileDataType(
+                    // Only show carrier name if there are more than 1 subscription
+                    cb.multipleSubs ? cb.dataSubscriptionName : "",
+                    getMobileDataContentName(cb));
         } else {
             state.state = Tile.STATE_INACTIVE;
             state.secondaryLabel = r.getString(R.string.cell_data_off);
@@ -216,24 +207,22 @@
         if (TextUtils.isEmpty(dataType)) {
             return current;
         }
-        SpannableString type = new SpannableString(dataType);
-        SpannableStringBuilder builder = new SpannableStringBuilder(current);
-        builder.append(" ");
-        builder.append(type, new TextAppearanceSpan(mContext, R.style.TextAppearance_RATBadge),
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-        return builder;
+        if (TextUtils.isEmpty(current)) {
+            return dataType;
+        }
+        return mContext.getString(R.string.mobile_carrier_text_format, current, dataType);
     }
 
-    private CharSequence getMobileDataSubscriptionName(CallbackInfo cb) {
-        if (cb.roaming && !TextUtils.isEmpty(cb.dataSubscriptionName)) {
+    private CharSequence getMobileDataContentName(CallbackInfo cb) {
+        if (cb.roaming && !TextUtils.isEmpty(cb.dataContentDescription)) {
             String roaming = mContext.getString(R.string.data_connection_roaming);
-            String dataDescription = cb.dataSubscriptionName.toString();
+            String dataDescription = cb.dataContentDescription.toString();
             return mContext.getString(R.string.mobile_data_text_format, roaming, dataDescription);
         }
         if (cb.roaming) {
             return mContext.getString(R.string.data_connection_roaming);
         }
-        return cb.dataSubscriptionName;
+        return cb.dataContentDescription;
     }
 
     @Override
@@ -254,6 +243,7 @@
         boolean activityOut;
         boolean noSim;
         boolean roaming;
+        boolean multipleSubs;
     }
 
     private final class CellSignalCallback implements SignalCallback {
@@ -272,6 +262,7 @@
             mInfo.activityIn = activityIn;
             mInfo.activityOut = activityOut;
             mInfo.roaming = roaming;
+            mInfo.multipleSubs = mController.getNumberSubscriptions() > 1;
             refreshState(mInfo);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 7fcd59f..869fa6b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -235,7 +235,7 @@
         state.label = getTileLabel();
         state.secondaryLabel = TextUtils.emptyIfNull(ZenModeConfig.getDescription(mContext,
                 zen != Global.ZEN_MODE_OFF, mController.getConfig(), false));
-        state.icon = ResourceIcon.get(R.drawable.ic_dnd);
+        state.icon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_dnd);
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
         switch (zen) {
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index dfa3fb9..2755e98 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -35,7 +35,7 @@
 public class FlashlightTile extends QSTileImpl<BooleanState> implements
         FlashlightController.FlashlightListener {
 
-    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_flashlight);
+    private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_flashlight);
     private final FlashlightController mFlashlightController;
 
     @Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index a0f4e24..837ea9f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -37,7 +37,7 @@
 /** Quick settings tile: Location **/
 public class LocationTile extends QSTileImpl<BooleanState> {
 
-    private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_signal_location);
+    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_location);
 
     private final LocationController mController;
     private final KeyguardMonitor mKeyguard;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 21f3d6e..7ca1e44 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -36,7 +36,7 @@
 /** Quick settings tile: Rotation **/
 public class RotationLockTile extends QSTileImpl<BooleanState> {
 
-    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_auto_rotate);
+    private final Icon mIcon = ResourceIcon.get(com.android.internal.R.drawable.ic_qs_auto_rotate);
     private final RotationLockController mController;
 
     @Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
index f921eb9..7853dc3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -33,7 +33,7 @@
 /** Quick settings tile: Work profile on/off */
 public class WorkModeTile extends QSTileImpl<BooleanState> implements
         ManagedProfileController.Callback {
-    private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_workmode_disable);
+    private final Icon mIcon = ResourceIcon.get(R.drawable.stat_sys_managed_profile_status);
 
     private final ManagedProfileController mProfileController;
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 494e6cd..2b361f8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -24,7 +24,7 @@
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
 import static com.android.systemui.shared.system.NavigationBarCompat.InteractionType;
-import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_CHANNEL;
+import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS;
@@ -38,6 +38,7 @@
 import android.content.ServiceConnection;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.hardware.input.InputManager;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -47,7 +48,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
-import android.view.InputChannel;
+import android.view.InputMonitor;
 import android.view.MotionEvent;
 
 import com.android.internal.policy.ScreenDecorationsUtils;
@@ -58,7 +59,6 @@
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -115,8 +115,6 @@
     private float mWindowCornerRadius;
     private boolean mSupportsRoundedCornersOnWindows;
 
-    private InputEventDispatcher mInputEventDispatcher;
-
     private ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() {
 
         public void startScreenPinning(int taskId) {
@@ -295,6 +293,22 @@
             }
         }
 
+        public Bundle monitorGestureInput(String name, int displayId) {
+            if (!verifyCaller("monitorGestureInput")) {
+                return null;
+            }
+            long token = Binder.clearCallingIdentity();
+            try {
+                InputMonitor monitor =
+                        InputManager.getInstance().monitorGestureInput(name, displayId);
+                Bundle result = new Bundle();
+                result.putParcelable(KEY_EXTRA_INPUT_MONITOR, monitor);
+                return result;
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
         private boolean verifyCaller(String reason) {
             final int callerId = Binder.getCallingUserHandle().getIdentifier();
             if (callerId != mCurrentBoundedUserId) {
@@ -341,23 +355,16 @@
             } catch (RemoteException e) {
                 Log.e(TAG_OPS, "Lost connection to launcher service", e);
             }
-            try {
-                mOverviewProxy.onBind(mSysUiProxy);
-            } catch (RemoteException e) {
-                mCurrentBoundedUserId = -1;
-                Log.e(TAG_OPS, "Failed to call onBind()", e);
-            }
 
             Bundle params = new Bundle();
             params.putBinder(KEY_EXTRA_SYSUI_PROXY, mSysUiProxy.asBinder());
-            params.putParcelable(KEY_EXTRA_INPUT_CHANNEL, createNewInputDispatcher());
             params.putFloat(KEY_EXTRA_WINDOW_CORNER_RADIUS, mWindowCornerRadius);
             params.putBoolean(KEY_EXTRA_SUPPORTS_WINDOW_CORNERS, mSupportsRoundedCornersOnWindows);
             try {
                 mOverviewProxy.onInitialize(params);
             } catch (RemoteException e) {
-                // Ignore error until the migration is complete.
-                Log.e(TAG_OPS, "Failed to call onBind()", e);
+                mCurrentBoundedUserId = -1;
+                Log.e(TAG_OPS, "Failed to call onInitialize()", e);
             }
             dispatchNavButtonBounds();
 
@@ -369,7 +376,6 @@
             Log.w(TAG_OPS, "Null binding of '" + name + "', try reconnecting");
             mCurrentBoundedUserId = -1;
             retryConnectionWithBackoff();
-            disposeInputDispatcher();
         }
 
         @Override
@@ -377,32 +383,15 @@
             Log.w(TAG_OPS, "Binding died of '" + name + "', try reconnecting");
             mCurrentBoundedUserId = -1;
             retryConnectionWithBackoff();
-            disposeInputDispatcher();
         }
 
         @Override
         public void onServiceDisconnected(ComponentName name) {
             // Do nothing
             mCurrentBoundedUserId = -1;
-            disposeInputDispatcher();
         }
     };
 
-    private void disposeInputDispatcher() {
-        if (mInputEventDispatcher != null) {
-            mInputEventDispatcher.dispose();
-            mInputEventDispatcher = null;
-        }
-    }
-
-    private InputChannel createNewInputDispatcher() {
-        disposeInputDispatcher();
-
-        InputChannel[] channels = InputChannel.openInputChannelPair("overview-proxy-service");
-        mInputEventDispatcher = new InputEventDispatcher(channels[0], Looper.getMainLooper());
-        return channels[1];
-    }
-
     private final DeviceProvisionedListener mDeviceProvisionedCallback =
                 new DeviceProvisionedListener() {
             @Override
@@ -439,6 +428,9 @@
         mSupportsRoundedCornersOnWindows = ScreenDecorationsUtils
                 .supportsRoundedCornersOnWindows(mContext.getResources());
 
+        // Assumes device always starts with back button until launcher tells it that it does not
+        mBackButtonAlpha = 1.0f;
+
         // Listen for the package update changes.
         if (mDeviceProvisionedController.getCurrentUser() == UserHandle.USER_SYSTEM) {
             updateEnabledState();
@@ -564,10 +556,6 @@
         return mOverviewProxy;
     }
 
-    public InputEventDispatcher getInputEventDispatcher() {
-        return mInputEventDispatcher;
-    }
-
     public int getInteractionFlags() {
         return mInteractionFlags;
     }
@@ -630,6 +618,14 @@
         }
     }
 
+    public void notifyAssistantVisibilityChanged(float visibility) {
+        try {
+            mOverviewProxy.onAssistantVisibilityChanged(visibility);
+        } catch (RemoteException e) {
+            Log.e(TAG_OPS, "Failed to call onAssistantVisibilityChanged()", e);
+        }
+    }
+
     private void updateEnabledState() {
         mIsEnabled = mContext.getPackageManager().resolveServiceAsUser(mQuickStepIntent,
                 MATCH_SYSTEM_ONLY,
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 79228b9..1e0a9f1 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -39,7 +39,6 @@
 import android.service.vr.IVrManager;
 import android.service.vr.IVrStateCallbacks;
 import android.util.Log;
-import android.widget.ImageView;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -50,11 +49,8 @@
 
 public class BrightnessController implements ToggleSlider.Listener {
     private static final String TAG = "StatusBar.BrightnessController";
-    private static final boolean SHOW_AUTOMATIC_ICON = false;
-
     private static final int SLIDER_ANIMATION_DURATION = 3000;
 
-    private static final int MSG_UPDATE_ICON = 0;
     private static final int MSG_UPDATE_SLIDER = 1;
     private static final int MSG_SET_CHECKED = 2;
     private static final int MSG_ATTACH_LISTENER = 3;
@@ -69,7 +65,6 @@
     private final int mDefaultBacklightForVr;
 
     private final Context mContext;
-    private final ImageView mIcon;
     private final ToggleSlider mControl;
     private final boolean mAutomaticAvailable;
     private final DisplayManager mDisplayManager;
@@ -193,10 +188,8 @@
                         Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
                         UserHandle.USER_CURRENT);
                 mAutomatic = automatic != Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
-                mHandler.obtainMessage(MSG_UPDATE_ICON, mAutomatic ? 1 : 0).sendToTarget();
             } else {
                 mHandler.obtainMessage(MSG_SET_CHECKED, 0).sendToTarget();
-                mHandler.obtainMessage(MSG_UPDATE_ICON, 0 /* automatic */).sendToTarget();
             }
         }
     };
@@ -237,9 +230,6 @@
             mExternalChange = true;
             try {
                 switch (msg.what) {
-                    case MSG_UPDATE_ICON:
-                        updateIcon(msg.arg1 != 0);
-                        break;
                     case MSG_UPDATE_SLIDER:
                         updateSlider(msg.arg1, msg.arg2 != 0);
                         break;
@@ -264,9 +254,8 @@
         }
     };
 
-    public BrightnessController(Context context, ImageView icon, ToggleSlider control) {
+    public BrightnessController(Context context, ToggleSlider control) {
         mContext = context;
-        mIcon = icon;
         mControl = control;
         mControl.setMax(GAMMA_SPACE_MAX);
         mBackgroundHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER));
@@ -347,7 +336,6 @@
     @Override
     public void onChanged(ToggleSlider toggleSlider, boolean tracking, boolean automatic,
             int value, boolean stopTracking) {
-        updateIcon(mAutomatic);
         if (mExternalChange) return;
 
         if (mSliderAnimator != null) {
@@ -416,18 +404,6 @@
         mDisplayManager.setTemporaryBrightness(brightness);
     }
 
-    private void setBrightnessAdj(float adj) {
-        mDisplayManager.setTemporaryAutoBrightnessAdjustment(adj);
-    }
-
-    private void updateIcon(boolean automatic) {
-        if (mIcon != null) {
-            mIcon.setImageResource(automatic && SHOW_AUTOMATIC_ICON ?
-                    com.android.systemui.R.drawable.ic_qs_brightness_auto_on :
-                    com.android.systemui.R.drawable.ic_qs_brightness_auto_off);
-        }
-    }
-
     private void updateVrMode(boolean isEnabled) {
         if (mIsVrModeEnabled != isEnabled) {
             mIsVrModeEnabled = isEnabled;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index 0374a01..d8b4df5 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -24,7 +24,6 @@
 import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
-import android.widget.ImageView;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -49,9 +48,8 @@
                 R.layout.quick_settings_brightness_dialog, null);
         setContentView(v);
 
-        final ImageView icon = findViewById(R.id.brightness_icon);
         final ToggleSliderView slider = findViewById(R.id.brightness_slider);
-        mBrightnessController = new BrightnessController(this, icon, slider);
+        mBrightnessController = new BrightnessController(this, slider);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index 7f39e47..7e6ddcf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -128,7 +128,8 @@
     private KeyCharacterMap mBackupKeyCharacterMap;
 
     private KeyboardShortcuts(Context context) {
-        this.mContext = new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light);
+        this.mContext = new ContextThemeWrapper(
+                context, android.R.style.Theme_DeviceDefault_Settings);
         this.mPackageManager = AppGlobals.getPackageManager();
         loadResources(context);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 8faeb15..a87e50c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -308,11 +308,23 @@
             // Walk down a precedence-ordered list of what indication
             // should be shown based on user or device state
             if (mDozing) {
+                // When dozing we ignore any text color and use white instead, because
+                // colors can be hard to read in low brightness.
+                mTextView.setTextColor(Color.WHITE);
                 if (!TextUtils.isEmpty(mTransientIndication)) {
-                    mTextView.setTextColor(Color.WHITE);
                     mTextView.switchIndication(mTransientIndication);
+                } else if (mPowerPluggedIn) {
+                    String indication = computePowerIndication();
+                    if (animate) {
+                        animateText(mTextView, indication);
+                    } else {
+                        mTextView.switchIndication(indication);
+                    }
+                } else {
+                    String percentage = NumberFormat.getPercentInstance()
+                            .format(mBatteryLevel / 100f);
+                    mTextView.switchIndication(percentage);
                 }
-                updateAlphas();
                 return;
             }
 
@@ -353,14 +365,6 @@
         }
     }
 
-    private void updateAlphas() {
-        if (!TextUtils.isEmpty(mTransientIndication)) {
-            mTextView.setAlpha(1f);
-        } else {
-            mTextView.setAlpha(1f - mDarkAmount);
-        }
-    }
-
     // animates textView - textView moves up and bounces down
     private void animateText(KeyguardIndicationTextView textView, String indication) {
         int yTranslation = mContext.getResources().getInteger(
@@ -523,14 +527,6 @@
         pw.println("  computePowerIndication(): " + computePowerIndication());
     }
 
-    public void setDarkAmount(float darkAmount) {
-        if (mDarkAmount == darkAmount) {
-            return;
-        }
-        mDarkAmount = darkAmount;
-        updateAlphas();
-    }
-
     @Override
     public void onStateChanged(int newState) {
         // don't care
@@ -675,6 +671,7 @@
         public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType) {
             super.onBiometricAuthenticated(userId, biometricSourceType);
             mLastSuccessiveErrorMessage = -1;
+            mHandler.sendEmptyMessage(MSG_HIDE_TRANSIENT);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index a630e49..2793b2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -63,6 +63,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Objects;
 import java.util.Set;
 
 import javax.inject.Inject;
@@ -142,7 +143,7 @@
             if (DEBUG) {
                 Log.v(TAG, "Notification click handler invoked for intent: " + pendingIntent);
             }
-            logActionClick(view);
+            logActionClick(view, pendingIntent);
             // The intent we are sending is for the application, which
             // won't have permission to immediately start an activity after
             // the user switches to home.  We know it is safe to do at this
@@ -159,11 +160,11 @@
             });
         }
 
-        private void logActionClick(View view) {
+        private void logActionClick(View view, PendingIntent actionIntent) {
             Integer actionIndex = (Integer)
                     view.getTag(com.android.internal.R.id.notification_action_index_tag);
             if (actionIndex == null) {
-                Log.e(TAG, "Couldn't retrieve the actionIndex from the clicked button");
+                // Custom action button, not logging.
                 return;
             }
             ViewParent parent = view.getParent();
@@ -182,8 +183,20 @@
             }
             final int count = mEntryManager.getNotificationData().getActiveNotifications().size();
             final int rank = mEntryManager.getNotificationData().getRank(key);
+
+            // Notification may be updated before this function is executed, and thus play safe
+            // here and verify that the action object is still the one that where the click happens.
+            Notification.Action[] actions = statusBarNotification.getNotification().actions;
+            if (actions == null || actionIndex >= actions.length) {
+                Log.w(TAG, "statusBarNotification.getNotification().actions is null or invalid");
+                return;
+            }
             final Notification.Action action =
                     statusBarNotification.getNotification().actions[actionIndex];
+            if (Objects.equals(action.actionIntent, actionIntent)) {
+                Log.w(TAG, "actionIntent does not match");
+                return;
+            }
             NotificationVisibility.NotificationLocation location =
                     NotificationLogger.getNotificationLocation(
                             mEntryManager.getNotificationData().get(key));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index cb9060b..cf6e64c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -289,4 +289,9 @@
             }
         }
     }
+
+    @Override
+    protected boolean canReceivePointerEvents() {
+        return false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index b788f53..fd2f720 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -78,8 +78,7 @@
         row.setJustClicked(true);
         DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));
 
-        // If it was a bubble we should close it
-        if (row.getEntry().isBubble()) {
+        if (!row.getEntry().isBubble()) {
             mBubbleController.collapseStack();
         }
 
@@ -95,7 +94,8 @@
      */
     public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
         Notification notification = sbn.getNotification();
-        if (notification.contentIntent != null || notification.fullScreenIntent != null) {
+        if (notification.contentIntent != null || notification.fullScreenIntent != null
+                || row.getEntry().isBubble()) {
             row.setOnClickListener(this);
         } else {
             row.setOnClickListener(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 3433fa8..1e506ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -163,6 +163,7 @@
     private fun handleAnimationFinished() {
         if (mLinearDozeAmount == 0.0f || mLinearVisibilityAmount == 0.0f) {
             mEntrySetToClearWhenFinished.forEach { it.setAmbientGoingAway(false) }
+            mEntrySetToClearWhenFinished.clear()
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index f1373d1..f69356e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -21,6 +21,7 @@
 import static android.app.Notification.CATEGORY_EVENT;
 import static android.app.Notification.CATEGORY_MESSAGE;
 import static android.app.Notification.CATEGORY_REMINDER;
+import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
@@ -40,6 +41,7 @@
 import android.service.notification.NotificationListenerService;
 import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.view.View;
 import android.widget.ImageView;
@@ -50,6 +52,7 @@
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.ContrastColorUtil;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.InflationException;
@@ -146,11 +149,6 @@
     private boolean hasSentReply;
 
     /**
-     * Whether this notification should be displayed as a bubble.
-     */
-    private boolean mIsBubble;
-
-    /**
      * Whether this notification has been approved globally, at the app level, and at the channel
      * level for bubbling.
      */
@@ -222,12 +220,8 @@
         this.mHighPriority = highPriority;
     }
 
-    public void setIsBubble(boolean bubbleable) {
-        mIsBubble = bubbleable;
-    }
-
     public boolean isBubble() {
-        return mIsBubble;
+        return (notification.getNotification().flags & FLAG_BUBBLE) != 0;
     }
 
     public void setBubbleDismissed(boolean userDismissed) {
@@ -401,6 +395,72 @@
     }
 
     /**
+     * Returns our best guess for the most relevant text summary of the latest update to this
+     * notification, based on its type. Returns null if there should not be an update message.
+     */
+    public CharSequence getUpdateMessage(Context context) {
+        final Notification underlyingNotif = notification.getNotification();
+        final Class<? extends Notification.Style> style = underlyingNotif.getNotificationStyle();
+
+        try {
+            if (Notification.BigTextStyle.class.equals(style)) {
+                // Return the big text, it is big so probably important. If it's not there use the
+                // normal text.
+                CharSequence bigText =
+                        underlyingNotif.extras.getCharSequence(Notification.EXTRA_BIG_TEXT);
+                return !TextUtils.isEmpty(bigText)
+                        ? bigText
+                        : underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT);
+            } else if (Notification.MessagingStyle.class.equals(style)) {
+                final List<Notification.MessagingStyle.Message> messages =
+                        Notification.MessagingStyle.Message.getMessagesFromBundleArray(
+                                (Parcelable[]) underlyingNotif.extras.get(
+                                        Notification.EXTRA_MESSAGES));
+
+                final Notification.MessagingStyle.Message latestMessage =
+                        Notification.MessagingStyle.findLatestIncomingMessage(messages);
+
+                if (latestMessage != null) {
+                    final CharSequence personName = latestMessage.getSenderPerson() != null
+                            ? latestMessage.getSenderPerson().getName()
+                            : null;
+
+                    // Prepend the sender name if available since group chats also use messaging
+                    // style.
+                    if (!TextUtils.isEmpty(personName)) {
+                        return context.getResources().getString(
+                                R.string.notification_summary_message_format,
+                                personName,
+                                latestMessage.getText());
+                    } else {
+                        return latestMessage.getText();
+                    }
+                }
+            } else if (Notification.InboxStyle.class.equals(style)) {
+                CharSequence[] lines =
+                        underlyingNotif.extras.getCharSequenceArray(Notification.EXTRA_TEXT_LINES);
+
+                // Return the last line since it should be the most recent.
+                if (lines != null && lines.length > 0) {
+                    return lines[lines.length - 1];
+                }
+            } else if (Notification.MediaStyle.class.equals(style)) {
+                // Return nothing, media updates aren't typically useful as a text update.
+                return null;
+            } else {
+                // Default to text extra.
+                return underlyingNotif.extras.getCharSequence(Notification.EXTRA_TEXT);
+            }
+        } catch (ClassCastException | NullPointerException | ArrayIndexOutOfBoundsException e) {
+            // No use crashing, we'll just return null and the caller will assume there's no update
+            // message.
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    /**
      * Abort all existing inflation tasks
      */
     public void abortTask() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
index b91cdaf..d3e5af8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
@@ -220,8 +220,6 @@
             StatusBarNotification sbn,
             ExpandableNotificationRow row) {
         row.setIsLowPriority(entry.ambient);
-        // bind the click event to the content area
-        checkNotNull(mNotificationClicker).register(row, sbn);
 
         // Extract target SDK version.
         try {
@@ -257,6 +255,9 @@
         row.setNeedsRedaction(
                 Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry));
         row.inflateViews();
+
+        // bind the click event to the content area
+        checkNotNull(mNotificationClicker).register(row, sbn);
     }
 
     private void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 9630727c..d287b92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -552,6 +552,9 @@
             mEntry.mIsSystemNotification = isSystemNotification(mContext, mStatusBarNotification);
         }
 
+        isNonblockable |= mEntry.channel.isImportanceLockedByOEM();
+        isNonblockable |= mEntry.channel.isImportanceLockedByCriticalDeviceFunction();
+
         if (!isNonblockable && mEntry != null && mEntry.mIsSystemNotification != null) {
             if (mEntry.mIsSystemNotification) {
                 if (mEntry.channel != null
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 520df97..bbb17c2 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
@@ -399,7 +399,7 @@
     private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() {
         @Override
         public void getOutline(View view, Outline outline) {
-            if (mAmbientState.isDarkAtAll() && !mAmbientState.isFullyDark()) {
+            if (mAmbientState.isDarkAtAll() || !mShowDarkShelf) {
                 outline.setRoundRect(mBackgroundAnimationRect, mCornerRadius);
             } else {
                 ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index 7905617..211a40a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -70,7 +70,7 @@
 
     private final String mTag;
     private final View mView;
-    private final BarBackgroundDrawable mBarBackground;
+    protected final BarBackgroundDrawable mBarBackground;
 
     private int mMode;
     private boolean mAlwaysOpaque = false;
@@ -152,7 +152,7 @@
         return mode == MODE_LIGHTS_OUT || mode == MODE_LIGHTS_OUT_TRANSPARENT;
     }
 
-    private static class BarBackgroundDrawable extends Drawable {
+    protected static class BarBackgroundDrawable extends Drawable {
         private final int mOpaque;
         private final int mSemiTransparent;
         private final int mTransparent;
@@ -171,6 +171,7 @@
 
         private int mGradientAlphaStart;
         private int mColorStart;
+        private Rect mFrame;
 
 
         public BarBackgroundDrawable(Context context, int gradientResourceId) {
@@ -190,6 +191,10 @@
             mGradient = context.getDrawable(gradientResourceId);
         }
 
+        public void setFrame(Rect frame) {
+            mFrame = frame;
+        }
+
         @Override
         public void setAlpha(int alpha) {
             // noop
@@ -296,7 +301,11 @@
                 if (mTintFilter != null) {
                     mPaint.setColorFilter(mTintFilter);
                 }
-                canvas.drawPaint(mPaint);
+                if (mFrame != null) {
+                    canvas.drawRect(mFrame, mPaint);
+                } else {
+                    canvas.drawPaint(mPaint);
+                }
             }
             if (mAnimating) {
                 invalidateSelf();  // keep going
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index ca45209..2e85fea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -414,7 +414,9 @@
             return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
         }
         if (mStatusBarKeyguardViewManager.isShowing()) {
-            if (mStatusBarKeyguardViewManager.isBouncerShowing() && unlockingAllowed) {
+            if ((mStatusBarKeyguardViewManager.isBouncerShowing()
+                    || mStatusBarKeyguardViewManager.isBouncerPartiallyVisible())
+                    && unlockingAllowed) {
                 return MODE_DISMISS_BOUNCER;
             } else if (unlockingAllowed) {
                 return faceStayingOnKeyguard ? MODE_ONLY_WAKE : MODE_UNLOCK;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
index 08a10dc..ac58e68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
@@ -36,7 +36,8 @@
 /**
  */
 @Singleton
-public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher {
+public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher,
+        LightBarTransitionsController.DarkIntensityApplier {
 
     private final LightBarTransitionsController mTransitionsController;
     private final Rect mTintArea = new Rect();
@@ -54,8 +55,7 @@
         mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone);
         mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone);
 
-        mTransitionsController = new LightBarTransitionsController(context,
-                this::setIconTintInternal);
+        mTransitionsController = new LightBarTransitionsController(context, this);
     }
 
     public LightBarTransitionsController getTransitionsController() {
@@ -104,13 +104,19 @@
         applyIconTint();
     }
 
-    private void setIconTintInternal(float darkIntensity) {
+    @Override
+    public void applyDarkIntensity(float darkIntensity) {
         mDarkIntensity = darkIntensity;
         mIconTint = (int) ArgbEvaluator.getInstance().evaluate(darkIntensity,
                 mLightModeIconColorSingleTone, mDarkModeIconColorSingleTone);
         applyIconTint();
     }
 
+    @Override
+    public int getTintAnimationDuration() {
+        return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION;
+    }
+
     private void applyIconTint() {
         for (int i = 0; i < mReceivers.size(); i++) {
             mReceivers.valueAt(i).onDarkChanged(mTintArea, mDarkIntensity, mIconTint);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 236c72c..0731a56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -108,16 +108,13 @@
             }
             String zen = args.getString("zen");
             if (zen != null) {
-                int iconId = zen.equals("important") ? R.drawable.stat_sys_zen_important
-                        : zen.equals("none") ? R.drawable.stat_sys_zen_none
-                        : 0;
+                int iconId = zen.equals("dnd") ? R.drawable.stat_sys_dnd : 0;
                 updateSlot("zen", null, iconId);
             }
             String bt = args.getString("bluetooth");
             if (bt != null) {
-                int iconId = bt.equals("disconnected") ? R.drawable.stat_sys_data_bluetooth
-                        : bt.equals("connected") ? R.drawable.stat_sys_data_bluetooth_connected
-                        : 0;
+                int iconId = bt.equals("connected")
+                        ? R.drawable.stat_sys_data_bluetooth_connected : 0;
                 updateSlot("bluetooth", null, iconId);
             }
             String location = args.getString("location");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
new file mode 100644
index 0000000..95abb66
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
@@ -0,0 +1,351 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.phone;
+
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
+import android.hardware.input.InputManager;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.MathUtils;
+import android.view.Choreographer;
+import android.view.Gravity;
+import android.view.IPinnedStackController;
+import android.view.IPinnedStackListener;
+import android.view.ISystemGestureExclusionListener;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.InputMonitor;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+
+import com.android.systemui.R;
+import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
+import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.WindowManagerWrapper;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Utility class to handle edge swipes for back gesture
+ */
+public class EdgeBackGestureHandler implements DisplayListener {
+
+    private static final String TAG = "EdgeBackGestureHandler";
+
+    private final IPinnedStackListener.Stub mImeChangedListener = new IPinnedStackListener.Stub() {
+        @Override
+        public void onListenerRegistered(IPinnedStackController controller) {
+        }
+
+        @Override
+        public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+            // No need to thread jump, assignments are atomic
+            mImeHeight = imeVisible ? imeHeight : 0;
+            // TODO: Probably cancel any existing gesture
+        }
+
+        @Override
+        public void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
+        }
+
+        @Override
+        public void onMinimizedStateChanged(boolean isMinimized) {
+        }
+
+        @Override
+        public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
+                Rect animatingBounds, boolean fromImeAdjustment, boolean fromShelfAdjustment,
+                int displayRotation) {
+        }
+
+        @Override
+        public void onActionsChanged(ParceledListSlice actions) {
+        }
+    };
+
+    private ISystemGestureExclusionListener mGestureExclusionListener =
+            new ISystemGestureExclusionListener.Stub() {
+                @Override
+                public void onSystemGestureExclusionChanged(int displayId,
+                        Region systemGestureExclusion) {
+                    if (displayId == mDisplayId) {
+                        mMainExecutor.execute(() -> mExcludeRegion.set(systemGestureExclusion));
+                    }
+                }
+            };
+
+    private final Context mContext;
+
+    private final Point mDisplaySize = new Point();
+    private final int mDisplayId;
+
+    private final Executor mMainExecutor;
+
+    private final Region mExcludeRegion = new Region();
+    // The edge width where touch down is allowed
+    private final int mEdgeWidth;
+    // The slop to distinguish between horizontal and vertical motion
+    private final float mTouchSlop;
+    // Minimum distance to move so that is can be considerd as a back swipe
+    private final float mSwipeThreshold;
+
+    private final int mNavBarHeight;
+
+    private final PointF mDownPoint = new PointF();
+    private boolean mThresholdCrossed = false;
+    private boolean mIgnoreThisGesture = false;
+    private boolean mIsOnLeftEdge;
+
+    private int mImeHeight = 0;
+
+    private boolean mIsAttached;
+    private boolean mIsGesturalModeEnabled;
+    private boolean mIsEnabled;
+
+    private InputMonitor mInputMonitor;
+    private InputEventReceiver mInputEventReceiver;
+
+    private final WindowManager mWm;
+
+    private NavigationBarEdgePanel mEdgePanel;
+    private WindowManager.LayoutParams mEdgePanelLp;
+
+    public EdgeBackGestureHandler(Context context) {
+        mContext = context;
+        mDisplayId = context.getDisplayId();
+        mMainExecutor = context.getMainExecutor();
+        mWm = context.getSystemService(WindowManager.class);
+
+        mEdgeWidth = QuickStepContract.getEdgeSensitivityWidth(context);
+        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+        mSwipeThreshold = context.getResources()
+                .getDimension(R.dimen.navigation_edge_action_drag_threshold);
+
+        mNavBarHeight = context.getResources().getDimensionPixelSize(R.dimen.navigation_bar_height);
+    }
+
+    /**
+     * @see NavigationBarView#onAttachedToWindow()
+     */
+    public void onNavBarAttached() {
+        mIsAttached = true;
+        onOverlaysChanged();
+    }
+
+    /**
+     * @see NavigationBarView#onDetachedFromWindow()
+     */
+    public void onNavBarDetached() {
+        mIsAttached = false;
+        updateIsEnabled();
+    }
+
+    /**
+     * Called when system overlays has changed
+     */
+    public void onOverlaysChanged() {
+        mIsGesturalModeEnabled = QuickStepContract.isGesturalMode(mContext);
+        updateIsEnabled();
+    }
+
+    private void disposeInputChannel() {
+        if (mInputEventReceiver != null) {
+            mInputEventReceiver.dispose();
+            mInputEventReceiver = null;
+        }
+        if (mInputMonitor != null) {
+            mInputMonitor.dispose();
+            mInputMonitor = null;
+        }
+    }
+
+    private void updateIsEnabled() {
+        boolean isEnabled = mIsAttached && mIsGesturalModeEnabled;
+        if (isEnabled == mIsEnabled) {
+            return;
+        }
+        mIsEnabled = isEnabled;
+        disposeInputChannel();
+
+        if (mEdgePanel != null) {
+            mWm.removeView(mEdgePanel);
+            mEdgePanel = null;
+        }
+
+        if (!mIsEnabled) {
+            WindowManagerWrapper.getInstance().removePinnedStackListener(mImeChangedListener);
+
+            try {
+                WindowManagerGlobal.getWindowManagerService()
+                        .unregisterSystemGestureExclusionListener(
+                                mGestureExclusionListener, mDisplayId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to unregister window manager callbacks", e);
+            }
+
+        } else {
+            updateDisplaySize();
+
+            try {
+                WindowManagerWrapper.getInstance().addPinnedStackListener(mImeChangedListener);
+                WindowManagerGlobal.getWindowManagerService()
+                        .registerSystemGestureExclusionListener(
+                                mGestureExclusionListener, mDisplayId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to register window manager callbacks", e);
+            }
+
+            // Register input event receiver
+            mInputMonitor = InputManager.getInstance().monitorGestureInput(
+                    "edge-swipe", mDisplayId);
+            mInputEventReceiver = new InputEventReceiver(mInputMonitor.getInputChannel(),
+                    Looper.getMainLooper(), Choreographer.getMainThreadInstance(),
+                    this::onInputEvent);
+
+            // Add a nav bar panel window
+            mEdgePanel = new NavigationBarEdgePanel(mContext);
+            mEdgePanelLp = new WindowManager.LayoutParams(
+                    mContext.getResources()
+                            .getDimensionPixelSize(R.dimen.navigation_edge_panel_width),
+                    mContext.getResources()
+                            .getDimensionPixelSize(R.dimen.navigation_edge_panel_height),
+                    WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                            | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+                    PixelFormat.TRANSLUCENT);
+            mEdgePanelLp.setTitle(TAG + mDisplayId);
+            mEdgePanelLp.accessibilityTitle = mContext.getString(R.string.nav_bar_edge_panel);
+            mEdgePanelLp.windowAnimations = 0;
+            mEdgePanel.setLayoutParams(mEdgePanelLp);
+            mWm.addView(mEdgePanel, mEdgePanelLp);
+        }
+    }
+
+    private void onInputEvent(InputEvent ev) {
+        if (ev instanceof MotionEvent) {
+            onMotionEvent((MotionEvent) ev);
+        }
+    }
+
+    private boolean isWithinTouchRegion(int x, int y) {
+        if (y > (mDisplaySize.y - Math.max(mImeHeight, mNavBarHeight))) {
+            return false;
+        }
+
+        if (x > mEdgeWidth && x < (mDisplaySize.x - mEdgeWidth)) {
+            return false;
+        }
+        return !mExcludeRegion.contains(x, y);
+    }
+
+    private void onMotionEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            // Verify if this is in within the touch region
+            mIgnoreThisGesture = !isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
+            if (!mIgnoreThisGesture) {
+                mIsOnLeftEdge = ev.getX() < mEdgeWidth;
+                mEdgePanelLp.gravity = mIsOnLeftEdge
+                        ? (Gravity.LEFT | Gravity.TOP)
+                        : (Gravity.RIGHT | Gravity.TOP);
+                mEdgePanel.setIsLeftPanel(mIsOnLeftEdge);
+                mEdgePanelLp.y = MathUtils.constrain(
+                        (int) (ev.getY() - mEdgePanelLp.height / 2),
+                        0, mDisplaySize.y);
+                mWm.updateViewLayout(mEdgePanel, mEdgePanelLp);
+
+                mDownPoint.set(ev.getX(), ev.getY());
+                mThresholdCrossed = false;
+                mEdgePanel.handleTouch(ev);
+            }
+        } else if (!mIgnoreThisGesture) {
+            if (!mThresholdCrossed && ev.getAction() == MotionEvent.ACTION_MOVE) {
+                float dx = Math.abs(ev.getX() - mDownPoint.x);
+                float dy = Math.abs(ev.getY() - mDownPoint.y);
+                if (dy > dx && dy > mTouchSlop) {
+                    // Send action cancel to reset all the touch events
+                    mIgnoreThisGesture = true;
+                    MotionEvent cancelEv = MotionEvent.obtain(ev);
+                    cancelEv.setAction(MotionEvent.ACTION_CANCEL);
+                    mEdgePanel.handleTouch(cancelEv);
+                    cancelEv.recycle();
+                    return;
+
+                } else if (dx > dy && dx > mTouchSlop) {
+                    mThresholdCrossed = true;
+                    // Capture inputs
+                    mInputMonitor.pilferPointers();
+                }
+            }
+
+            // forward touch
+            mEdgePanel.handleTouch(ev);
+
+            if (ev.getAction() == MotionEvent.ACTION_UP) {
+                float xDiff = ev.getX() - mDownPoint.x;
+                boolean exceedsThreshold = mIsOnLeftEdge
+                        ? (xDiff > mSwipeThreshold) : (-xDiff > mSwipeThreshold);
+                if (exceedsThreshold && Math.abs(xDiff) > Math.abs(ev.getY() - mDownPoint.y)) {
+                    // Perform back
+                    sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
+                    sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onDisplayAdded(int displayId) { }
+
+    @Override
+    public void onDisplayRemoved(int displayId) { }
+
+    @Override
+    public void onDisplayChanged(int displayId) {
+        if (displayId == mDisplayId) {
+            updateDisplaySize();
+        }
+    }
+
+    private void updateDisplaySize() {
+        mContext.getSystemService(DisplayManager.class)
+                .getDisplay(mDisplayId).getRealSize(mDisplaySize);
+    }
+
+    private void sendEvent(int action, int code) {
+        long when = SystemClock.uptimeMillis();
+        final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,
+                0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
+                KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+                InputDevice.SOURCE_KEYBOARD);
+        InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 9844d8e..b7a154d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -140,7 +140,7 @@
         mHeadsUpInset = mStatusBarHeight + resources.getDimensionPixelSize(
                 R.dimen.heads_up_status_bar_padding);
         mDisplayCutoutTouchableRegionSize = resources.getDimensionPixelSize(
-                R.dimen.display_cutout_touchable_region_size);
+                com.android.internal.R.dimen.display_cutout_touchable_region_size);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 800ae58..a924680 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -19,6 +19,7 @@
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
 import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 
+import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
 import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
 import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
 import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON;
@@ -122,6 +123,7 @@
     private KeyguardAffordanceView mRightAffordanceView;
     private KeyguardAffordanceView mLeftAffordanceView;
     private LockIcon mLockIcon;
+    private ViewGroup mLockIconContainer;
     private ViewGroup mIndicationArea;
     private TextView mEnterpriseDisclosure;
     private TextView mIndicationText;
@@ -171,6 +173,8 @@
     private boolean mDozing;
     private int mIndicationBottomMargin;
     private float mDarkAmount;
+    private int mBurnInXOffset;
+    private int mBurnInYOffset;
     private ActivityIntentHelper mActivityIntentHelper;
 
     public KeyguardBottomAreaView(Context context) {
@@ -244,12 +248,15 @@
         mRightAffordanceView = findViewById(R.id.camera_button);
         mLeftAffordanceView = findViewById(R.id.left_button);
         mLockIcon = findViewById(R.id.lock_icon);
+        mLockIconContainer = findViewById(R.id.lock_icon_container);
         mIndicationArea = findViewById(R.id.keyguard_indication_area);
         mEnterpriseDisclosure = findViewById(
                 R.id.keyguard_indication_enterprise_disclosure);
         mIndicationText = findViewById(R.id.keyguard_indication_text);
         mIndicationBottomMargin = getResources().getDimensionPixelSize(
                 R.dimen.keyguard_indication_margin_bottom);
+        mBurnInYOffset = getResources().getDimensionPixelSize(
+                R.dimen.default_burn_in_prevention_offset);
         updateCameraVisibility();
         mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
         mUnlockMethodCache.addListener(this);
@@ -319,6 +326,8 @@
         super.onConfigurationChanged(newConfig);
         mIndicationBottomMargin = getResources().getDimensionPixelSize(
                 R.dimen.keyguard_indication_margin_bottom);
+        mBurnInYOffset = getResources().getDimensionPixelSize(
+                R.dimen.default_burn_in_prevention_offset);
         MarginLayoutParams mlp = (MarginLayoutParams) mIndicationArea.getLayoutParams();
         if (mlp.bottomMargin != mIndicationBottomMargin) {
             mlp.bottomMargin = mIndicationBottomMargin;
@@ -562,8 +571,8 @@
             return;
         }
         mDarkAmount = darkAmount;
-        mIndicationController.setDarkAmount(darkAmount);
         mLockIcon.setDarkAmount(darkAmount);
+        dozeTimeTick();
     }
 
     /**
@@ -657,6 +666,10 @@
         return mLockIcon;
     }
 
+    public ViewGroup getLockIconContainer() {
+        return mLockIconContainer;
+    }
+
     public View getIndicationArea() {
         return mIndicationArea;
     }
@@ -835,6 +848,20 @@
         }
     }
 
+    public void dozeTimeTick() {
+        int burnInYOffset = getBurnInOffset(mBurnInYOffset * 2, false /* xAxis */)
+                - mBurnInYOffset;
+        mIndicationArea.setTranslationY(burnInYOffset * mDarkAmount);
+    }
+
+    public void setAntiBurnInOffsetX(int burnInXOffset) {
+        if (mBurnInXOffset == burnInXOffset) {
+            return;
+        }
+        mBurnInXOffset = burnInXOffset;
+        mIndicationArea.setTranslationX(burnInXOffset);
+    }
+
     /**
      * Sets the alpha of the indication areas and affordances, excluding the lock icon.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index fe3a455..1d2ca9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -123,6 +123,7 @@
             return;
         }
         ensureView();
+        mIsScrimmed = isScrimmed;
 
         // On the keyguard, we want to show the bouncer when the user drags up, but it's
         // not correct to end the falsing session. We still need to verify if those touches
@@ -132,13 +133,13 @@
         if (isScrimmed) {
             setExpansion(EXPANSION_VISIBLE);
         }
-        mIsScrimmed = isScrimmed;
 
         if (resetSecuritySelection) {
             // showPrimarySecurityScreen() updates the current security method. This is needed in
             // case we are already showing and the current security method changed.
             showPrimarySecurityScreen();
         }
+
         if (mRoot.getVisibility() == View.VISIBLE || mShowingSoon) {
             return;
         }
@@ -168,8 +169,8 @@
         mCallback.onBouncerVisiblityChanged(true /* shown */);
     }
 
-    public boolean isShowingScrimmed() {
-        return isShowing() && mIsScrimmed;
+    public boolean isScrimmed() {
+        return mIsScrimmed;
     }
 
     public ViewGroup getLockIconContainer() {
@@ -281,6 +282,7 @@
                 StatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN);
             mDismissCallbackRegistry.notifyDismissCancelled();
         }
+        mIsScrimmed = false;
         mFalsingManager.onBouncerHidden();
         mCallback.onBouncerVisiblityChanged(false /* shown */);
         cancelShowRunnable();
@@ -332,6 +334,11 @@
                 && mExpansion == EXPANSION_VISIBLE && !isAnimatingAway();
     }
 
+    public boolean isPartiallyVisible() {
+        return (mShowingSoon || (mRoot != null && mRoot.getVisibility() == View.VISIBLE))
+                && mExpansion != EXPANSION_HIDDEN && !isAnimatingAway();
+    }
+
     /**
      * @return {@code true} when bouncer's pre-hide animation already started but isn't completely
      *         hidden yet, {@code false} otherwise.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 4c50d07..6ee031a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.phone;
 
 import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
-import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
 
 import android.annotation.ColorInt;
 import android.content.Context;
@@ -102,19 +101,6 @@
      */
     private int mCutoutSideNudge = 0;
 
-    /**
-     * How much to move icons to avoid burn in.
-     */
-    private int mBurnInOffset;
-    private int mCurrentBurnInOffsetX;
-    private int mCurrentBurnInOffsetY;
-
-    /**
-     * Ratio representing being in ambient mode or not.
-     */
-    private float mDarkAmount;
-    private boolean mDozing;
-
     public KeyguardStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -186,8 +172,6 @@
                 R.dimen.system_icons_super_container_avatarless_margin_end);
         mCutoutSideNudge = getResources().getDimensionPixelSize(
                 R.dimen.display_cutout_margin_consumption);
-        mBurnInOffset = getResources().getDimensionPixelSize(
-                R.dimen.default_burn_in_prevention_offset);
         mShowPercentAvailable = getContext().getResources().getBoolean(
                 com.android.internal.R.bool.config_battery_percentage_setting_available);
     }
@@ -203,15 +187,15 @@
         }
         if (mKeyguardUserSwitcher == null) {
             // If we have no keyguard switcher, the screen width is under 600dp. In this case,
-            // we don't show the multi-user avatar unless there is more than 1 user on the device.
-            if (mUserSwitcherController != null
-                    && mUserSwitcherController.getSwitchableUserCount() > 1) {
+            // we only show the multi-user switch if it's enabled through UserManager as well as
+            // by the user.
+            if (mMultiUserSwitch.isMultiUserEnabled()) {
                 mMultiUserSwitch.setVisibility(View.VISIBLE);
             } else {
                 mMultiUserSwitch.setVisibility(View.GONE);
             }
         }
-        mBatteryView.setForceShowPercent(mBatteryCharging && mShowPercentAvailable || mDozing);
+        mBatteryView.setForceShowPercent(mBatteryCharging && mShowPercentAvailable);
     }
 
     private void updateSystemIconsLayoutParams() {
@@ -348,7 +332,6 @@
         mIconManager = new TintedIconManager(findViewById(R.id.statusIcons));
         Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
         onThemeChanged();
-        updateDarkState();
     }
 
     @Override
@@ -492,7 +475,7 @@
             mIconManager.setTint(iconColor);
         }
 
-        applyDarkness(R.id.battery, mEmptyRect, intensity * (1f - mDarkAmount), iconColor);
+        applyDarkness(R.id.battery, mEmptyRect, intensity, iconColor);
         applyDarkness(R.id.clock, mEmptyRect, intensity, iconColor);
     }
 
@@ -513,48 +496,4 @@
             mBatteryView.dump(fd, pw, args);
         }
     }
-
-    public void setDozing(boolean dozing) {
-        if (mDozing == dozing) {
-            return;
-        }
-        mDozing = dozing;
-        setClipChildren(!dozing);
-        setClipToPadding(!dozing);
-        updateVisibilities();
-    }
-
-    public void setDarkAmount(float darkAmount) {
-        mDarkAmount = darkAmount;
-        if (darkAmount == 0) {
-            dozeTimeTick();
-        }
-        updateDarkState();
-    }
-
-    public void dozeTimeTick() {
-        mCurrentBurnInOffsetX = getBurnInOffset(mBurnInOffset, true /* xAxis */);
-        mCurrentBurnInOffsetY = getBurnInOffset(mBurnInOffset, false /* xAxis */);
-        updateDarkState();
-    }
-
-    private void updateDarkState() {
-        float alpha = 1f - mDarkAmount;
-        int visibility = alpha != 0f ? VISIBLE : INVISIBLE;
-        mCarrierLabel.setAlpha(alpha * alpha);
-        mStatusIconContainer.setAlpha(alpha);
-        mStatusIconContainer.setVisibility(visibility);
-
-        float iconsX = -mCurrentBurnInOffsetX;
-        if (mMultiUserSwitch.getVisibility() == VISIBLE) {
-            // Squared alpha to add a nice easing curve and avoid overlap during animation.
-            mMultiUserAvatar.setAlpha(alpha * alpha);
-            iconsX += mMultiUserAvatar.getPaddingLeft() + mMultiUserAvatar.getWidth()
-                    + mMultiUserAvatar.getPaddingRight();
-        }
-        mSystemIconsContainer.setTranslationX(iconsX * mDarkAmount);
-        mSystemIconsContainer.setTranslationY(mCurrentBurnInOffsetY * mDarkAmount);
-        updateIconsAndTextColors();
-    }
-
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index b622688..d709730 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -16,9 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.systemui.statusbar.phone.NavBarTintController.DEFAULT_COLOR_ADAPT_TRANSITION_TIME;
-import static com.android.systemui.statusbar.phone.NavBarTintController.MIN_COLOR_ADAPT_TRANSITION_TIME;
-
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.os.Bundle;
@@ -52,7 +49,6 @@
     private final DarkIntensityApplier mApplier;
     private final KeyguardMonitor mKeyguardMonitor;
     private final StatusBarStateController mStatusBarStateController;
-    private NavBarTintController mColorAdaptionController;
 
     private boolean mTransitionDeferring;
     private long mTransitionDeferringStartTime;
@@ -118,7 +114,8 @@
         }
         if (mTransitionPending && mTintChangePending) {
             mTintChangePending = false;
-            animateIconTint(mPendingDarkIntensity, 0 /* delay */, getTintAnimationDuration());
+            animateIconTint(mPendingDarkIntensity, 0 /* delay */,
+                    mApplier.getTintAnimationDuration());
         }
         mTransitionPending = false;
     }
@@ -159,17 +156,10 @@
                     Math.max(0, mTransitionDeferringStartTime - SystemClock.uptimeMillis()),
                     mTransitionDeferringDuration);
         } else {
-            animateIconTint(dark ? 1.0f : 0.0f, 0 /* delay */, getTintAnimationDuration());
+            animateIconTint(dark ? 1.0f : 0.0f, 0 /* delay */, mApplier.getTintAnimationDuration());
         }
     }
 
-    public long getTintAnimationDuration() {
-        if (NavBarTintController.isEnabled(mContext)) {
-            return Math.max(DEFAULT_COLOR_ADAPT_TRANSITION_TIME, MIN_COLOR_ADAPT_TRANSITION_TIME);
-        }
-        return DEFAULT_TINT_ANIMATION_DURATION;
-    }
-
     public float getCurrentDarkIntensity() {
         return mDarkIntensity;
     }
@@ -243,5 +233,6 @@
      */
     public interface DarkIntensityApplier {
         void applyDarkIntensity(float darkIntensity);
+        int getTintAnimationDuration();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index f393dcd..1d87a8b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -16,10 +16,10 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.admin.DevicePolicyManager;
 import android.content.Context;
-import android.content.Intent;
 import android.os.UserManager;
-import android.provider.ContactsContract;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
@@ -33,7 +33,6 @@
 import com.android.systemui.Prefs;
 import com.android.systemui.Prefs.Key;
 import com.android.systemui.R;
-import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
@@ -95,6 +94,26 @@
         registerListener();
     }
 
+    public boolean isMultiUserEnabled() {
+        // Short-circuiting from UserManager. Needs to be extracted because of SystemUI boolean flag
+        // qs_show_user_switcher_for_single_user
+
+        final boolean userSwitcherEnabled = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.USER_SWITCHER_ENABLED, 1) != 0;
+
+        if (!UserManager.supportsMultipleUsers()
+                || mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)
+                || UserManager.isDeviceInDemoMode(mContext)
+                || !userSwitcherEnabled) {
+            return false;
+        }
+
+        final boolean guestEnabled = !mContext.getSystemService(DevicePolicyManager.class)
+                .getGuestUserDisabled(null);
+        return mUserSwitcherController.getSwitchableUserCount() > 1 || guestEnabled
+                || mContext.getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user);
+    }
+
     private void registerListener() {
         if (mUserManager.isUserSwitcherEnabled() && mUserListener == null) {
 
@@ -118,29 +137,20 @@
 
     @Override
     public void onClick(View v) {
-        if (mUserManager.isUserSwitcherEnabled()) {
-            if (mKeyguardMode) {
-                if (mKeyguardUserSwitcher != null) {
-                    mKeyguardUserSwitcher.show(true /* animate */);
-                }
-            } else if (mQsPanel != null && mUserSwitcherController != null) {
-                View center = getChildCount() > 0 ? getChildAt(0) : this;
-
-                center.getLocationInWindow(mTmpInt2);
-                mTmpInt2[0] += center.getWidth() / 2;
-                mTmpInt2[1] += center.getHeight() / 2;
-
-                mQsPanel.showDetailAdapter(true,
-                        getUserDetailAdapter(),
-                        mTmpInt2);
+        if (mKeyguardMode) {
+            if (mKeyguardUserSwitcher != null) {
+                mKeyguardUserSwitcher.show(true /* animate */);
             }
-        } else {
-            if (mQsPanel != null) {
-                Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent(
-                        getContext(), v, ContactsContract.Profile.CONTENT_URI,
-                        ContactsContract.QuickContact.MODE_LARGE, null);
-                Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(intent, 0);
-            }
+        } else if (mQsPanel != null && mUserSwitcherController != null) {
+            View center = getChildCount() > 0 ? getChildAt(0) : this;
+
+            center.getLocationInWindow(mTmpInt2);
+            mTmpInt2[0] += center.getWidth() / 2;
+            mTmpInt2[1] += center.getHeight() / 2;
+
+            mQsPanel.showDetailAdapter(true,
+                    getUserDetailAdapter(),
+                    mTmpInt2);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
index 9cfb1aa..bf5b60a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
@@ -19,11 +19,14 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Handler;
 import android.view.CompositionSamplingListener;
 import android.view.View;
 
+import com.android.systemui.R;
 import com.android.systemui.shared.system.QuickStepContract;
 
 import java.io.PrintWriter;
@@ -37,9 +40,6 @@
     public static final int MIN_COLOR_ADAPT_TRANSITION_TIME = 400;
     public static final int DEFAULT_COLOR_ADAPT_TRANSITION_TIME = 1700;
 
-    // Passing the threshold of this luminance value will make the button black otherwise white
-    private static final float LUMINANCE_THRESHOLD = 0.3f;
-
     private final Handler mHandler = new Handler();
     private final NavigationBarView mNavigationBarView;
     private final LightBarTransitionsController mLightBarController;
@@ -50,9 +50,17 @@
     private boolean mSamplingEnabled = false;
     private boolean mSamplingListenerRegistered = false;
 
-    private float mLastMediaLuma;
+    private float mLastMedianLuma;
+    private float mCurrentMedianLuma;
     private boolean mUpdateOnNextDraw;
 
+    private final int mNavBarHeight;
+    private final int mNavColorSampleMargin;
+
+    // Passing the threshold of this luminance value will make the button black otherwise white
+    private final float mLuminanceThreshold;
+    private final float mLuminanceChangeThreshold;
+
     public NavBarTintController(NavigationBarView navigationBarView,
             LightBarTransitionsController lightBarController) {
         mSamplingListener = new CompositionSamplingListener(
@@ -66,6 +74,13 @@
         mNavigationBarView.addOnAttachStateChangeListener(this);
         mNavigationBarView.addOnLayoutChangeListener(this);
         mLightBarController = lightBarController;
+
+        final Resources res = navigationBarView.getResources();
+        mNavBarHeight = res.getDimensionPixelSize(R.dimen.navigation_bar_height);
+        mNavColorSampleMargin =
+                res.getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin);
+        mLuminanceThreshold = res.getFloat(R.dimen.navigation_luminance_threshold);
+        mLuminanceChangeThreshold = res.getFloat(R.dimen.navigation_luminance_change_threshold);
     }
 
     void onDraw() {
@@ -109,8 +124,11 @@
         if (view != null) {
             int[] pos = new int[2];
             view.getLocationOnScreen(pos);
-            final Rect samplingBounds = new Rect(pos[0], pos[1],
-                    pos[0] + view.getWidth(), pos[1] + view.getHeight());
+            Point displaySize = new Point();
+            view.getContext().getDisplay().getRealSize(displaySize);
+            final Rect samplingBounds = new Rect(pos[0] - mNavColorSampleMargin,
+                    displaySize.y - mNavBarHeight, pos[0] + view.getWidth() + mNavColorSampleMargin,
+                    displaySize.y);
             if (!samplingBounds.equals(mSamplingBounds)) {
                 mSamplingBounds.set(samplingBounds);
                 requestUpdateSamplingListener();
@@ -144,13 +162,19 @@
     }
 
     private void updateTint(float medianLuma) {
-        mLastMediaLuma = medianLuma;
-        if (medianLuma > LUMINANCE_THRESHOLD) {
-            // Black
-            mLightBarController.setIconsDark(true /* dark */, true /* animate */);
-        } else {
-            // White
-            mLightBarController.setIconsDark(false /* dark */, true /* animate */);
+        mLastMedianLuma = medianLuma;
+
+        // If the difference between the new luma and the current luma is larger than threshold
+        // then apply the current luma, this is to prevent small changes causing colors to flicker
+        if (Math.abs(mCurrentMedianLuma - mLastMedianLuma) > mLuminanceChangeThreshold) {
+            if (medianLuma > mLuminanceThreshold) {
+                // Black
+                mLightBarController.setIconsDark(true /* dark */, true /* animate */);
+            } else {
+                // White
+                mLightBarController.setIconsDark(false /* dark */, true /* animate */);
+            }
+            mCurrentMedianLuma = medianLuma;
         }
     }
 
@@ -162,7 +186,8 @@
                 : "false"));
         pw.println("  mSamplingListenerRegistered: " + mSamplingListenerRegistered);
         pw.println("  mSamplingBounds: " + mSamplingBounds);
-        pw.println("  mLastMediaLuma: " + mLastMediaLuma);
+        pw.println("  mLastMedianLuma: " + mLastMedianLuma);
+        pw.println("  mCurrentMedianLuma: " + mCurrentMedianLuma);
     }
 
     public static boolean isEnabled(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationAssistantAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationAssistantAction.java
deleted file mode 100644
index 323e776..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationAssistantAction.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import android.annotation.NonNull;
-import android.os.Bundle;
-import android.view.MotionEvent;
-
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.recents.OverviewProxyService;
-
-/**
- * Assistant is triggered with this action
- */
-public class NavigationAssistantAction extends NavigationGestureAction {
-    private static final String TAG = "NavigationAssistantActions";
-
-    private final AssistManager mAssistManager;
-
-    public NavigationAssistantAction(@NonNull NavigationBarView navigationBarView,
-            @NonNull OverviewProxyService service, AssistManager assistManager) {
-        super(navigationBarView, service);
-        mAssistManager = assistManager;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-
-    @Override
-    public boolean disableProxyEvents() {
-        return true;
-    }
-
-    @Override
-    public void onGestureStart(MotionEvent event) {
-        mAssistManager.startAssist(new Bundle());
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
deleted file mode 100644
index c77b16b..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import android.annotation.NonNull;
-import android.hardware.input.InputManager;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-import com.android.systemui.recents.OverviewProxyService;
-
-/**
- * A back action when triggered will execute a back command
- */
-public class NavigationBackAction extends NavigationGestureAction {
-
-    private static final String BACK_AFTER_END_PROP =
-            "quickstepcontroller_homegoesbackwhenend";
-    private static final long BACK_BUTTON_FADE_OUT_ALPHA = 60;
-    private static final long BACK_GESTURE_POLL_TIMEOUT = 1000;
-
-    private final Handler mHandler = new Handler();
-
-    private final Runnable mExecuteBackRunnable = new Runnable() {
-        @Override
-        public void run() {
-            if (isEnabled() && canPerformAction()) {
-                performBack();
-                mHandler.postDelayed(this, BACK_GESTURE_POLL_TIMEOUT);
-            }
-        }
-    };
-
-    public NavigationBackAction(@NonNull NavigationBarView navigationBarView,
-            @NonNull OverviewProxyService service) {
-        super(navigationBarView, service);
-    }
-
-    @Override
-    public boolean allowHitTargetToMoveOverDrag() {
-        return true;
-    }
-
-    @Override
-    public boolean canPerformAction() {
-        return mProxySender.getBackButtonAlpha() > 0;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-
-    @Override
-    protected void onGestureStart(MotionEvent event) {
-        if (!QuickStepController.shouldHideBackButton(getContext())) {
-            mNavigationBarView.getBackButton().setAlpha(0 /* alpha */, true /* animate */,
-                    BACK_BUTTON_FADE_OUT_ALPHA);
-        }
-        mHandler.removeCallbacks(mExecuteBackRunnable);
-        if (!shouldExecuteBackOnUp()) {
-            performBack();
-            mHandler.postDelayed(mExecuteBackRunnable, BACK_GESTURE_POLL_TIMEOUT);
-        }
-    }
-
-    @Override
-    protected void onGestureEnd() {
-        mHandler.removeCallbacks(mExecuteBackRunnable);
-        if (!QuickStepController.shouldHideBackButton(getContext())) {
-            mNavigationBarView.getBackButton().setAlpha(
-                    mProxySender.getBackButtonAlpha(), true /* animate */);
-        }
-        if (shouldExecuteBackOnUp()) {
-            performBack();
-        }
-    }
-
-    @Override
-    public boolean disableProxyEvents() {
-        return true;
-    }
-
-    private void performBack() {
-        sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
-        sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
-    }
-
-    private boolean shouldExecuteBackOnUp() {
-        return getGlobalBoolean(BACK_AFTER_END_PROP);
-    }
-
-    private void sendEvent(int action, int code) {
-        long when = SystemClock.uptimeMillis();
-        final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,
-                0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
-                KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
-                InputDevice.SOURCE_KEYBOARD);
-        InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
index 4c7fdb0..86b5344 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
@@ -17,25 +17,22 @@
 package com.android.systemui.statusbar.phone;
 
 import android.animation.ObjectAnimator;
-import android.annotation.NonNull;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.graphics.PixelFormat;
 import android.os.SystemClock;
+import android.os.VibrationEffect;
 import android.util.FloatProperty;
 import android.util.MathUtils;
-import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.WindowManager;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.statusbar.VibratorHelper;
 
 public class NavigationBarEdgePanel extends View {
-    private static final String TAG = "NavigationBarEdgePanel";
 
     // TODO: read from resources once drawing is finalized.
     private static final boolean SHOW_PROTECTION_STROKE = true;
@@ -52,6 +49,8 @@
     private static final int ANIM_DURATION_MS = 150;
     private static final long HAPTIC_TIMEOUT_MS = 200;
 
+    private final VibratorHelper mVibratorHelper;
+
     private final Paint mPaint = new Paint();
     private final Paint mProtectionPaint = new Paint();
 
@@ -63,9 +62,11 @@
     private final float mPointExtent;
     private final float mHeight;
     private final float mStrokeThickness;
-    private final boolean mIsLeftPanel;
 
-    private float mStartY;
+    private final float mSwipeThreshold;
+
+    private boolean mIsLeftPanel;
+
     private float mStartX;
 
     private boolean mDragSlopPassed;
@@ -105,28 +106,11 @@
                 }
             };
 
-    public static NavigationBarEdgePanel create(@NonNull Context context, int width, int height,
-            int gravity) {
-        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
-                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
-                WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
-                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                PixelFormat.TRANSLUCENT);
-        lp.gravity = gravity;
-        lp.setTitle(TAG + context.getDisplayId());
-        lp.accessibilityTitle = context.getString(R.string.nav_bar_edge_panel);
-        lp.windowAnimations = 0;
-        NavigationBarEdgePanel panel = new NavigationBarEdgePanel(
-                context, (gravity & Gravity.LEFT) == Gravity.LEFT);
-        panel.setLayoutParams(lp);
-        return panel;
-    }
-
-    private NavigationBarEdgePanel(Context context, boolean isLeftPanel) {
+    public NavigationBarEdgePanel(Context context) {
         super(context);
 
+        mVibratorHelper = Dependency.get(VibratorHelper.class);
+
         mEndAnimator = ObjectAnimator.ofFloat(this, DRAG_PROGRESS, 1f);
         mEndAnimator.setAutoCancel(true);
         mEndAnimator.setDuration(ANIM_DURATION_MS);
@@ -154,45 +138,16 @@
 
         // Both panels arrow point the same way
         mArrowsPointLeft = getLayoutDirection() == LAYOUT_DIRECTION_LTR;
+
+        mSwipeThreshold = context.getResources()
+                .getDimension(R.dimen.navigation_edge_action_drag_threshold);
+        setVisibility(GONE);
+    }
+
+    public void setIsLeftPanel(boolean isLeftPanel) {
         mIsLeftPanel = isLeftPanel;
     }
 
-    public void setWindowFlag(int flags, boolean enable) {
-        WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
-        if (lp == null || enable == ((lp.flags & flags) != 0)) {
-            return;
-        }
-        if (enable) {
-            lp.flags |= flags;
-        } else {
-            lp.flags &= ~flags;
-        }
-        updateLayout(lp);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN : {
-                mDragSlopPassed = false;
-                show(event.getX(), event.getY());
-                break;
-            }
-            case MotionEvent.ACTION_MOVE: {
-                handleNewSwipePoint(event.getX());
-                break;
-            }
-            // Fall through
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL: {
-                hide();
-                break;
-            }
-        }
-
-        return false;
-    }
-
     @Override
     protected void onDraw(Canvas canvas) {
         float edgeOffset = mBaseExtent * mDragProgress - mStrokeThickness;
@@ -200,7 +155,7 @@
         canvas.save();
         canvas.translate(
                 mIsLeftPanel ? edgeOffset : getWidth() - edgeOffset,
-                mStartY - mHeight * 0.5f);
+                (getHeight() - mHeight) * 0.5f);
 
         float outsideX = mArrowsPointLeft ? animatedOffset : 0;
         float middleX = mArrowsPointLeft ? 0 : animatedOffset;
@@ -223,15 +178,6 @@
         mGestureLength = getWidth();
     }
 
-    public void setDimensions(int width, int height) {
-        final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
-        if (lp.width != width || lp.height != height) {
-            lp.width = width;
-            lp.height = height;
-            updateLayout(lp);
-        }
-    }
-
     private void setLegProgress(float progress) {
         mLegProgress = progress;
         invalidate();
@@ -251,29 +197,48 @@
     }
 
     private void hide() {
-        animate().alpha(0f).setDuration(ANIM_DURATION_MS);
+        animate().alpha(0f).setDuration(ANIM_DURATION_MS)
+                .withEndAction(() -> setVisibility(GONE));
     }
 
-    private void show(float x, float y) {
-        mEndAnimator.cancel();
-        mLegAnimator.cancel();
-        setLegProgress(0f);
-        setDragProgress(0f);
-        setAlpha(1f);
-
-        float halfHeight = mHeight * 0.5f;
-        mStartY = MathUtils.constrain(y, halfHeight, getHeight() - halfHeight);
-        mStartX = x;
+    /**
+     * Updates the UI based on the motion events passed in device co-ordinates
+     */
+    public void handleTouch(MotionEvent event) {
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN : {
+                mDragSlopPassed = false;
+                mEndAnimator.cancel();
+                mLegAnimator.cancel();
+                animate().cancel();
+                setLegProgress(0f);
+                setDragProgress(0f);
+                mStartX = event.getX();
+                setVisibility(VISIBLE);
+                break;
+            }
+            case MotionEvent.ACTION_MOVE: {
+                handleNewSwipePoint(event.getX());
+                break;
+            }
+            // Fall through
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL: {
+                hide();
+                break;
+            }
+        }
     }
 
     private void handleNewSwipePoint(float x) {
         float dist = MathUtils.abs(x - mStartX);
 
         // Apply a haptic on drag slop passed
-        if (!mDragSlopPassed && dist > QuickStepContract.getQuickStepDragSlopPx()) {
+        if (!mDragSlopPassed && dist > mSwipeThreshold) {
             mDragSlopPassed = true;
-            performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+            mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
             mLastSlopHapticTime = SystemClock.uptimeMillis();
+            setAlpha(1f);
         }
 
         setDragProgress(MathUtils.constrainedMap(
@@ -311,11 +276,6 @@
         }
     }
 
-    private void updateLayout(WindowManager.LayoutParams lp) {
-        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
-        wm.updateViewLayout(this, lp);
-    }
-
     private float dp(float dp) {
         return mDensity * dp;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index cbb5d54..3dcadf1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -91,6 +91,7 @@
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
@@ -201,7 +202,7 @@
         @Override
         public void onBackButtonAlphaChanged(float alpha, boolean animate) {
             final ButtonDispatcher backButton = mNavigationBarView.getBackButton();
-            if (QuickStepController.shouldHideBackButton(getContext())) {
+            if (QuickStepContract.isGesturalMode(getContext())) {
                 // If property was changed to hide/show back button, going home will trigger
                 // launcher to to change the back button alpha to reflect property change
                 backButton.setVisibility(View.GONE);
@@ -988,11 +989,11 @@
                 if (Intent.ACTION_SCREEN_ON.equals(action)) {
                     // Enabled and screen is on, start it again if enabled
                     if (NavBarTintController.isEnabled(getContext())) {
-                        mNavigationBarView.getColorAdaptionController().start();
+                        mNavigationBarView.getTintController().start();
                     }
                 } else {
                     // Screen off disable it
-                    mNavigationBarView.getColorAdaptionController().stop();
+                    mNavigationBarView.getTintController().stop();
                 }
             }
             if (Intent.ACTION_USER_SWITCHED.equals(action)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index 3984405..8ff6cc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -16,7 +16,11 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.statusbar.phone.NavBarTintController.DEFAULT_COLOR_ADAPT_TRANSITION_TIME;
+import static com.android.systemui.statusbar.phone.NavBarTintController.MIN_COLOR_ADAPT_TRANSITION_TIME;
+
 import android.content.Context;
+import android.graphics.Rect;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -30,7 +34,8 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 
-public final class NavigationBarTransitions extends BarTransitions {
+public final class NavigationBarTransitions extends BarTransitions implements
+        LightBarTransitionsController.DarkIntensityApplier {
 
     private final NavigationBarView mView;
     private final IStatusBarService mBarService;
@@ -58,8 +63,7 @@
         mView = view;
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-        mLightTransitionsController = new LightBarTransitionsController(view.getContext(),
-                this::applyDarkIntensity);
+        mLightTransitionsController = new LightBarTransitionsController(view.getContext(), this);
         mAllowAutoDimWallpaperNotVisible = view.getContext().getResources()
                 .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper);
 
@@ -105,6 +109,10 @@
         applyLightsOut(true, false);
     }
 
+    void setBackgroundFrame(Rect frame) {
+        mBarBackground.setFrame(frame);
+    }
+
     @Override
     protected boolean isLightsOut(int mode) {
         return super.isLightsOut(mode) || (mAllowAutoDimWallpaperNotVisible && mAutoDim
@@ -119,6 +127,7 @@
     protected void onTransition(int oldMode, int newMode, boolean animate) {
         super.onTransition(oldMode, newMode, animate);
         applyLightsOut(animate, false /*force*/);
+        mView.onBarTransition(newMode);
     }
 
     private void applyLightsOut(boolean animate, boolean force) {
@@ -164,4 +173,12 @@
         }
         mView.onDarkIntensityChange(darkIntensity);
     }
+
+    @Override
+    public int getTintAnimationDuration() {
+        if (NavBarTintController.isEnabled(mView.getContext())) {
+            return Math.max(DEFAULT_COLOR_ADAPT_TRANSITION_TIME, MIN_COLOR_ADAPT_TRANSITION_TIME);
+        }
+        return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index f809b62..4fd6a71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -17,19 +17,10 @@
 package com.android.systemui.statusbar.phone;
 
 import static android.content.Intent.ACTION_OVERLAY_CHANGED;
-import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
 
-import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_DEAD_ZONE;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
 import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_VIEWS;
 
 import android.animation.LayoutTransition;
@@ -39,14 +30,11 @@
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.annotation.DrawableRes;
-import android.annotation.IntDef;
-import android.annotation.SuppressLint;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.ParceledListSlice;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Point;
@@ -55,15 +43,11 @@
 import android.graphics.Region.Op;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
-import android.view.Gravity;
-import android.view.IPinnedStackController;
-import android.view.IPinnedStackListener;
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.View;
@@ -91,31 +75,19 @@
 import com.android.systemui.recents.RecentsOnboarding;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.NavigationBarCompat;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.statusbar.phone.NavigationPrototypeController.GestureAction;
-import com.android.systemui.statusbar.phone.NavigationPrototypeController.OnPrototypeChangedListener;
 import com.android.systemui.statusbar.policy.DeadZone;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.function.Consumer;
 
 public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> {
     final static boolean DEBUG = false;
     final static String TAG = "StatusBar/NavBarView";
 
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({WINDOW_TARGET_BOTTOM, WINDOW_TARGET_LEFT, WINDOW_TARGET_RIGHT})
-    public @interface WindowTarget{}
-    public static final int WINDOW_TARGET_BOTTOM = 0;
-    public static final int WINDOW_TARGET_LEFT = 1;
-    public static final int WINDOW_TARGET_RIGHT = 2;
-
     // slippery nav bar when everything is disabled, e.g. during setup
     final static boolean SLIPPERY_WHEN_DISABLED = true;
 
@@ -133,8 +105,6 @@
     int mDisabledFlags = 0;
     int mNavigationIconHints = 0;
 
-    private @NavigationBarCompat.HitTarget int mDownHitTarget = HIT_TARGET_NONE;
-    private @WindowTarget int mWindowHitTarget = WINDOW_TARGET_BOTTOM;
     private Rect mHomeButtonBounds = new Rect();
     private Rect mBackButtonBounds = new Rect();
     private Rect mRecentsButtonBounds = new Rect();
@@ -147,6 +117,7 @@
     private KeyButtonDrawable mRecentIcon;
     private KeyButtonDrawable mDockedIcon;
 
+    private final EdgeBackGestureHandler mEdgeBackGestureHandler;
     private GestureHelper mGestureHelper;
     private final DeadZone mDeadZone;
     private boolean mDeadZoneConsuming = false;
@@ -172,18 +143,8 @@
     private RecentsOnboarding mRecentsOnboarding;
     private NotificationPanelView mPanelView;
 
-    private NavBarTintController mColorAdaptionController;
+    private NavBarTintController mTintController;
     private boolean mAssistantAvailable;
-    private NavigationPrototypeController mPrototypeController;
-    private NavigationGestureAction[] mDefaultGestureMap;
-    private QuickScrubAction mQuickScrubAction;
-    private QuickStepAction mQuickStepAction;
-    private NavigationBackAction mBackAction;
-    private QuickSwitchAction mQuickSwitchAction;
-    private NavigationAssistantAction mAssistantAction;
-
-    private NavigationBarEdgePanel mLeftEdgePanel;
-    private NavigationBarEdgePanel mRightEdgePanel;
 
     /**
      * Helper that is responsible for showing the right toast when a disallowed activity operation
@@ -247,18 +208,6 @@
         }
     };
 
-    private final OnTouchListener mEdgePanelTouchListener = new OnTouchListener() {
-        @SuppressLint("ClickableViewAccessibility")
-        @Override
-        public boolean onTouch(View v, MotionEvent event) {
-            if (event.getActionMasked() == ACTION_DOWN) {
-                mWindowHitTarget = v == mLeftEdgePanel ? WINDOW_TARGET_LEFT : WINDOW_TARGET_RIGHT;
-                mDownHitTarget = HIT_TARGET_NONE;
-            }
-            return mGestureHelper.onTouchEvent(event);
-        }
-    };
-
     private final AccessibilityDelegate mQuickStepAccessibilityDelegate
             = new AccessibilityDelegate() {
         private AccessibilityAction mToggleOverviewAction;
@@ -285,101 +234,10 @@
         }
     };
 
-    // TODO(b/112934365): To be removed
-    private OnPrototypeChangedListener mPrototypeListener = new OnPrototypeChangedListener() {
-        @Override
-        public void onGestureRemap(int[] actions) {
-            updateNavigationGestures();
-        }
-
-        @Override
-        public void onBackButtonVisibilityChanged(boolean visible) {
-            if (!inScreenPinning()) {
-                getBackButton().setVisibility(QuickStepController.shouldHideBackButton(getContext())
-                        ? GONE : VISIBLE);
-            }
-        }
-
-        @Override
-        public void onHomeButtonVisibilityChanged(boolean visible) {
-            getHomeButton().setVisibility(QuickStepController.shouldHideHomeButton(getContext())
-                    ? GONE : VISIBLE);
-        }
-
-        @Override
-        public void onColorAdaptChanged(boolean enabled) {
-            if (enabled) {
-                mColorAdaptionController.start();
-            } else {
-                mColorAdaptionController.stop();
-            }
-        }
-
-        @Override
-        public void onEdgeSensitivityChanged(int width, int height) {
-            if (mLeftEdgePanel != null) {
-                mLeftEdgePanel.setDimensions(width, height);
-            }
-            if (mRightEdgePanel != null) {
-                mRightEdgePanel.setDimensions(width, height);
-            }
-        }
-
-        @Override
-        public void onHomeHandleVisiblilityChanged(boolean visible) {
-            showHomeHandle(QuickStepController.showHomeHandle(getContext()));
-        }
-
-        @Override
-        public void onAssistantGestureEnabled(boolean enabled) {
-            updateAssistantAvailability();
-        }
-    };
-
-    private final IPinnedStackListener.Stub mImeChangedListener = new IPinnedStackListener.Stub() {
-        @Override
-        public void onListenerRegistered(IPinnedStackController controller) {
-        }
-
-        @Override
-        public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
-            post(() -> {
-                // When the ime changes visibility, resize the edge panels to not cover the ime
-                final int width = mPrototypeController.getEdgeSensitivityWidth();
-                final int height = mContext.getDisplay().getHeight() - imeHeight
-                        - getResources().getDimensionPixelOffset(R.dimen.status_bar_height);
-                if (mLeftEdgePanel != null) {
-                    mLeftEdgePanel.setDimensions(width, height);
-                }
-                if (mRightEdgePanel != null) {
-                    mRightEdgePanel.setDimensions(width, height);
-                }
-            });
-        }
-
-        @Override
-        public void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
-        }
-
-        @Override
-        public void onMinimizedStateChanged(boolean isMinimized) {
-        }
-
-        @Override
-        public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
-                Rect animatingBounds, boolean fromImeAdjustment, boolean fromShelfAdjustment,
-                int displayRotation) {
-        }
-
-        @Override
-        public void onActionsChanged(ParceledListSlice actions) {
-        }
-    };
-
     private BroadcastReceiver mOverlaysChangedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            showHomeHandle(QuickStepController.showHomeHandle(getContext()));
+            onOverlaysChanged();
         }
     };
 
@@ -427,27 +285,13 @@
         mButtonDispatchers.put(R.id.menu_container, mContextualButtonGroup);
         mDeadZone = new DeadZone(this);
 
-        mQuickScrubAction = new QuickScrubAction(this, mOverviewProxyService);
-        mQuickStepAction = new QuickStepAction(this, mOverviewProxyService);
-        mBackAction = new NavigationBackAction(this, mOverviewProxyService);
-        mQuickSwitchAction = new QuickSwitchAction(this, mOverviewProxyService);
-        mDefaultGestureMap = new NavigationGestureAction[] {
-                mQuickStepAction, null /* swipeDownAction*/, null /* swipeLeftAction */,
-                mQuickScrubAction, null /* swipeLeftEdgeAction */, null /* swipeRightEdgeAction */
-        };
+        mEdgeBackGestureHandler = new EdgeBackGestureHandler(context);
+        mTintController = new NavBarTintController(this, getLightTransitionsController());
 
-        mPrototypeController = new NavigationPrototypeController(context);
-        mPrototypeController.register();
-        mPrototypeController.setOnPrototypeChangedListener(mPrototypeListener);
-        mColorAdaptionController = new NavBarTintController(this, getLightTransitionsController());
-
-        IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED);
-        filter.addDataScheme("package");
-        context.registerReceiver(mOverlaysChangedReceiver, filter);
     }
 
-    public NavBarTintController getColorAdaptionController() {
-        return mColorAdaptionController;
+    public NavBarTintController getTintController() {
+        return mTintController;
     }
 
     public BarTransitions getBarTransitions() {
@@ -460,58 +304,12 @@
 
     public void setComponents(NotificationPanelView panel, AssistManager assistManager) {
         mPanelView = panel;
-        if (mAssistantAction == null) {
-            mAssistantAction = new NavigationAssistantAction(this, mOverviewProxyService,
-                    assistManager);
-        }
-        if (mGestureHelper instanceof QuickStepController) {
-            ((QuickStepController) mGestureHelper).setComponents(this);
-            updateNavigationGestures();
-        }
     }
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
-        mColorAdaptionController.onDraw();
-    }
-
-    private void updateNavigationGestures() {
-        if (mGestureHelper instanceof QuickStepController) {
-            // TODO: Clarify this when we remove the prototype controller
-            final int[] gesturalMap = {0, 7, 1, 1, 3, 3};
-            final int[] normalMap = {0, 0, 0, 0, 0, 0};
-            final int[] assignedMap = QuickStepContract.isGesturalMode(getContext())
-                    ? gesturalMap
-                    : normalMap;
-            ((QuickStepController) mGestureHelper).setGestureActions(
-                    getNavigationActionFromType(assignedMap[0], mDefaultGestureMap[0]),
-                    getNavigationActionFromType(assignedMap[1], mDefaultGestureMap[1]),
-                    getNavigationActionFromType(assignedMap[2], mDefaultGestureMap[2]),
-                    getNavigationActionFromType(assignedMap[3], mDefaultGestureMap[3]),
-                    getNavigationActionFromType(assignedMap[4], mDefaultGestureMap[4]),
-                    getNavigationActionFromType(assignedMap[5], mDefaultGestureMap[5]));
-        }
-    }
-
-    private NavigationGestureAction getNavigationActionFromType(@GestureAction int actionType,
-            NavigationGestureAction defaultAction) {
-        switch(actionType) {
-            case NavigationPrototypeController.ACTION_QUICKSTEP:
-                return mQuickStepAction;
-            case NavigationPrototypeController.ACTION_QUICKSCRUB:
-                return mQuickScrubAction;
-            case NavigationPrototypeController.ACTION_BACK:
-                return mBackAction;
-            case NavigationPrototypeController.ACTION_QUICKSWITCH:
-                return mQuickSwitchAction;
-            case NavigationPrototypeController.ACTION_ASSISTANT:
-                return mAssistantAction;
-            case NavigationPrototypeController.ACTION_NOTHING:
-                return null;
-            default:
-                return defaultAction;
-        }
+        mTintController.onDraw();
     }
 
     public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
@@ -521,28 +319,7 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
-        final boolean deadZoneConsumed = shouldDeadZoneConsumeTouchEvents(event);
-        switch (event.getActionMasked()) {
-            case ACTION_DOWN:
-                int x = (int) event.getX();
-                int y = (int) event.getY();
-                mDownHitTarget = HIT_TARGET_NONE;
-                mWindowHitTarget = WINDOW_TARGET_BOTTOM;
-                if (deadZoneConsumed) {
-                    mDownHitTarget = HIT_TARGET_DEAD_ZONE;
-                } else if (getBackButton().isVisible() && mBackButtonBounds.contains(x, y)) {
-                    mDownHitTarget = HIT_TARGET_BACK;
-                } else if (getHomeButton().isVisible() && mHomeButtonBounds.contains(x, y)) {
-                    mDownHitTarget = HIT_TARGET_HOME;
-                } else if (getRecentsButton().isVisible() && mRecentsButtonBounds.contains(x, y)) {
-                    mDownHitTarget = HIT_TARGET_OVERVIEW;
-                } else if (getRotateSuggestionButton().isVisible()
-                        && mRotationButtonBounds.contains(x, y)) {
-                    mDownHitTarget = HIT_TARGET_ROTATION;
-                }
-                break;
-        }
-        return mGestureHelper.onInterceptTouchEvent(event);
+        return shouldDeadZoneConsumeTouchEvents(event) || super.onInterceptTouchEvent(event);
     }
 
     @Override
@@ -554,9 +331,24 @@
         return super.onTouchEvent(event);
     }
 
+    void onBarTransition(int newMode) {
+        if (newMode == MODE_OPAQUE) {
+            // If the nav bar background is opaque, stop auto tinting since we know the icons are
+            // showing over a dark background
+            mTintController.stop();
+            getLightTransitionsController().setIconsDark(false /* dark */, true /* animate */);
+        } else {
+            mTintController.start();
+        }
+    }
+
     private boolean shouldDeadZoneConsumeTouchEvents(MotionEvent event) {
+        int action = event.getActionMasked();
+        if (action == MotionEvent.ACTION_DOWN) {
+            mDeadZoneConsuming = false;
+        }
         if (mDeadZone.onTouchEvent(event) || mDeadZoneConsuming) {
-            switch (event.getActionMasked()) {
+            switch (action) {
                 case MotionEvent.ACTION_DOWN:
                     // Allow gestures starting in the deadzone to be slippery
                     setSlippery(true);
@@ -574,14 +366,6 @@
         return false;
     }
 
-    public @NavigationBarCompat.HitTarget int getDownHitTarget() {
-        return mDownHitTarget;
-    }
-
-    public @WindowTarget int getWindowTarget() {
-        return mWindowHitTarget;
-    }
-
     public void abortCurrentGesture() {
         getHomeButton().abortCurrentGesture();
     }
@@ -639,13 +423,6 @@
         return mOverviewProxyService.shouldShowSwipeUpUI() && isOverviewEnabled();
     }
 
-    public boolean isQuickScrubEnabled() {
-        // TODO(b/112934365): Remove this sys prop flag
-        return SystemProperties.getBoolean("persist.quickstep.scrub.enabled", true)
-                && mOverviewProxyService.isEnabled() && isOverviewEnabled()
-                && ((mOverviewProxyService.getInteractionFlags() & FLAG_DISABLE_QUICK_SCRUB) == 0);
-    }
-
     private void reloadNavIcons() {
         updateIcons(Configuration.EMPTY);
     }
@@ -787,7 +564,7 @@
 
         mBarTransitions.reapplyDarkIntensity();
 
-        boolean disableHome = QuickStepController.shouldHideHomeButton(getContext())
+        boolean disableHome = QuickStepContract.isGesturalMode(getContext())
                 || ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
 
         // TODO(b/113914868): investigation log for disappearing home button
@@ -797,7 +574,7 @@
         // Always disable recents when alternate car mode UI is active and for secondary displays.
         boolean disableRecent = isRecentsButtonDisabled();
 
-        boolean disableBack = QuickStepController.shouldHideBackButton(getContext())
+        boolean disableBack = QuickStepContract.isGesturalMode(getContext())
                 || (((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0) && !useAltBack);
 
         // When screen pinning, don't hide back and home when connected service or back and
@@ -906,10 +683,6 @@
         final boolean showSwipeUpUI = mOverviewProxyService.shouldShowSwipeUpUI();
 
         if (mNavigationInflaterView != null) {
-            if (mPrototypeController.showHomeHandle()) {
-                showHomeHandle(true /* visible */);
-            }
-
             // Reinflate the navbar if needed, no-op unless the swipe up state changes
             mNavigationInflaterView.onLikelyDefaultLayoutChange();
         }
@@ -942,16 +715,6 @@
         setWindowFlag(WindowManager.LayoutParams.FLAG_SLIPPERY, slippery);
     }
 
-    public void setWindowTouchable(boolean flag) {
-        setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag);
-        if (mLeftEdgePanel != null) {
-            mLeftEdgePanel.setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag);
-        }
-        if (mRightEdgePanel != null) {
-            mRightEdgePanel.setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag);
-        }
-    }
-
     private void setWindowFlag(int flags, boolean enable) {
         final ViewGroup navbarView = ((ViewGroup) getParent());
         if (navbarView == null) {
@@ -970,15 +733,16 @@
         wm.updateViewLayout(navbarView, lp);
     }
 
-    private void showHomeHandle(boolean visible) {
+    private void onOverlaysChanged() {
         mNavigationInflaterView.onTuningChanged(NAV_BAR_VIEWS, null);
 
         // Color adaption is tied with showing home handle, only avaliable if visible
-        if (visible) {
-            mColorAdaptionController.start();
+        if (QuickStepContract.isGesturalMode(getContext())) {
+            mTintController.start();
         } else {
-            mColorAdaptionController.stop();
+            mTintController.stop();
         }
+        mEdgeBackGestureHandler.onOverlaysChanged();
     }
 
     public void setAssistantAvailable(boolean available) {
@@ -1171,17 +935,6 @@
         } catch (RemoteException e) {
             Slog.e(TAG, "Failed to get nav bar position.", e);
         }
-
-        // For landscape, hide the panel that would interfere with navigation bar layout
-        if (mLeftEdgePanel != null && mRightEdgePanel != null) {
-            mLeftEdgePanel.setVisibility(VISIBLE);
-            mRightEdgePanel.setVisibility(VISIBLE);
-            if (navBarPos == NAV_BAR_LEFT) {
-                mLeftEdgePanel.setVisibility(GONE);
-            } else if (navBarPos == NAV_BAR_RIGHT) {
-                mRightEdgePanel.setVisibility(GONE);
-            }
-        }
         mGestureHelper.setBarState(isRtl, navBarPos);
     }
 
@@ -1192,7 +945,8 @@
         if (DEBUG) Log.d(TAG, String.format(
                 "onMeasure: (%dx%d) old: (%dx%d)", w, h, getMeasuredWidth(), getMeasuredHeight()));
 
-        final boolean newVertical = w > 0 && h > w;
+        final boolean newVertical = w > 0 && h > w
+                && !QuickStepContract.isGesturalMode(getContext());
         if (newVertical != mIsVertical) {
             mIsVertical = newVertical;
             if (DEBUG) {
@@ -1202,6 +956,19 @@
             reorient();
             notifyVerticalChangedListener(newVertical);
         }
+
+        if (QuickStepContract.isGesturalMode(getContext())) {
+            // Update the nav bar background to match the height of the visible nav bar
+            int height = mIsVertical
+                    ? getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.navigation_bar_height_landscape)
+                    : getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.navigation_bar_height);
+            int frameHeight = getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.navigation_bar_frame_height);
+            mBarTransitions.setBackgroundFrame(new Rect(0, frameHeight - height, w, h));
+        }
+
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     }
 
@@ -1228,9 +995,9 @@
         }
 
         if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
-            mColorAdaptionController.start();
+            mTintController.start();
         } else {
-            mColorAdaptionController.stop();
+            mTintController.stop();
         }
     }
 
@@ -1291,27 +1058,10 @@
                 NavGesture.class, false /* Only one */);
         setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
 
-        if (QuickStepContract.isGesturalMode(getContext())) {
-            WindowManager wm = (WindowManager) getContext()
-                    .getSystemService(Context.WINDOW_SERVICE);
-            int width = mPrototypeController.getEdgeSensitivityWidth();
-            int height = mPrototypeController.getEdgeSensitivityHeight();
-            // Explicitly left and right, not start and end as this is device relative.
-            mLeftEdgePanel = NavigationBarEdgePanel.create(getContext(), width, height,
-                    Gravity.LEFT | Gravity.TOP);
-            mRightEdgePanel = NavigationBarEdgePanel.create(getContext(), width, height,
-                    Gravity.RIGHT | Gravity.TOP);
-            mLeftEdgePanel.setOnTouchListener(mEdgePanelTouchListener);
-            mRightEdgePanel.setOnTouchListener(mEdgePanelTouchListener);
-            wm.addView(mLeftEdgePanel, mLeftEdgePanel.getLayoutParams());
-            wm.addView(mRightEdgePanel, mRightEdgePanel.getLayoutParams());
-
-            try {
-                WindowManagerWrapper.getInstance().addPinnedStackListener(mImeChangedListener);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to register pinned stack listener", e);
-            }
-        }
+        IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+        filter.addDataScheme("package");
+        getContext().registerReceiver(mOverlaysChangedReceiver, filter);
+        mEdgeBackGestureHandler.onNavBarAttached();
     }
 
     @Override
@@ -1321,21 +1071,13 @@
         if (mGestureHelper != null) {
             mGestureHelper.destroy();
         }
-        mPrototypeController.unregister();
-        getContext().unregisterReceiver(mOverlaysChangedReceiver);
         setUpSwipeUpOnboarding(false);
         for (int i = 0; i < mButtonDispatchers.size(); ++i) {
             mButtonDispatchers.valueAt(i).onDestroy();
         }
 
-        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
-        if (mLeftEdgePanel != null) {
-            wm.removeView(mLeftEdgePanel);
-        }
-        if (mRightEdgePanel != null) {
-            wm.removeView(mRightEdgePanel);
-        }
-        WindowManagerWrapper.getInstance().removePinnedStackListener(mImeChangedListener);
+        getContext().unregisterReceiver(mOverlaysChangedReceiver);
+        mEdgeBackGestureHandler.onNavBarDetached();
     }
 
     private void setUpSwipeUpOnboarding(boolean connectedToOverviewProxy) {
@@ -1354,12 +1096,10 @@
 
     @Override
     public void onPluginDisconnected(NavGesture plugin) {
-        QuickStepController defaultHelper = new QuickStepController(getContext());
-        defaultHelper.setComponents(this);
         if (mGestureHelper != null) {
             mGestureHelper.destroy();
+            mGestureHelper = null;
         }
-        mGestureHelper = defaultHelper;
         updateTaskSwitchHelper();
     }
 
@@ -1402,18 +1142,10 @@
 
         mContextualButtonGroup.dump(pw);
         if (mGestureHelper != null) {
-            pw.println("Navigation Gesture Actions {");
-            pw.print("    "); pw.println("QuickScrub Enabled=" + mQuickScrubAction.isEnabled());
-            pw.print("    "); pw.println("QuickScrub Active=" + mQuickScrubAction.isActive());
-            pw.print("    "); pw.println("QuickStep Enabled=" + mQuickStepAction.isEnabled());
-            pw.print("    "); pw.println("QuickStep Active=" + mQuickStepAction.isActive());
-            pw.print("    "); pw.println("Back Gesture Enabled=" + mBackAction.isEnabled());
-            pw.print("    "); pw.println("Back Gesture Active=" + mBackAction.isActive());
-            pw.println("}");
             mGestureHelper.dump(pw);
         }
         mRecentsOnboarding.dump(pw);
-        mColorAdaptionController.dump(pw);
+        mTintController.dump(pw);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
deleted file mode 100644
index eca14eb..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
-
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.view.MotionEvent;
-
-import com.android.systemui.recents.OverviewProxyService;
-
-/**
- * A gesture action that would be triggered and reassigned by {@link QuickStepController}
- */
-public abstract class NavigationGestureAction {
-    protected final NavigationBarView mNavigationBarView;
-    protected final OverviewProxyService mProxySender;
-
-    protected int mNavigationBarPosition;
-    protected boolean mDragHorizontalPositive;
-    protected boolean mDragVerticalPositive;
-    private boolean mIsActive;
-
-    public NavigationGestureAction(@NonNull NavigationBarView navigationBarView,
-            @NonNull OverviewProxyService service) {
-        mNavigationBarView = navigationBarView;
-        mProxySender = service;
-    }
-
-    /**
-     * Pass event that the state of the bar (such as rotation) has changed
-     * @param changed if rotation or drag positive direction (such as ltr) has changed
-     * @param navBarPos position of navigation bar
-     * @param dragHorPositive direction of positive horizontal drag, could change with ltr changes
-     * @param dragVerPositive direction of positive vertical drag, could change with ltr changes
-     */
-    public void setBarState(boolean changed, int navBarPos, boolean dragHorPositive,
-            boolean dragVerPositive) {
-        mNavigationBarPosition = navBarPos;
-        mDragHorizontalPositive = dragHorPositive;
-        mDragVerticalPositive = dragVerPositive;
-    }
-
-    /**
-     * Resets the state of the action. Called when touch down occurs over the Navigation Bar.
-     */
-    public void reset() {
-        mIsActive = false;
-    }
-
-    /**
-     * Start the gesture and the action will be active
-     * @param event the event that caused the gesture
-     */
-    public void startGesture(MotionEvent event) {
-        mIsActive = true;
-        onGestureStart(event);
-    }
-
-    /**
-     * Gesture has ended with action cancel or up and this action will not be active
-     */
-    public void endGesture() {
-        mIsActive = false;
-        onGestureEnd();
-    }
-
-    /**
-     * If the action is currently active based on the gesture that triggered it. Only one action
-     * can occur at a time
-     * @return whether or not if this action has been triggered
-     */
-    public boolean isActive() {
-        return mIsActive;
-    }
-
-    /**
-     * @return whether or not this action can run if notification shade is shown
-     */
-    public boolean canRunWhenNotificationsShowing() {
-        return true;
-    }
-
-    /**
-     * @return whether or not this action triggers when starting a gesture from a certain hit target
-     * If {@link HIT_TARGET_NONE} is specified then action does not need to be triggered by button
-     */
-    public int requiresTouchDownHitTarget() {
-        return HIT_TARGET_NONE;
-    }
-
-    /**
-     * @return whether or not to move the button that started gesture over with user input drag
-     */
-    public boolean allowHitTargetToMoveOverDrag() {
-        return false;
-    }
-
-    /**
-     * Tell if the action is able to execute. Note that {@link #isEnabled()} must be true for this
-     * to be checked. The difference between this and {@link #isEnabled()} is that this dependent
-     * on the state of the navigation bar
-     * @return true if action can execute after gesture activates based on current states
-     */
-    public boolean canPerformAction() {
-        return true;
-    }
-
-    /**
-     * Decide if the controller should not send the current motion event to launcher via
-     * {@link OverviewProxyService}
-     * @return if controller should not proxy
-     */
-    public boolean disableProxyEvents() {
-        return false;
-    }
-
-    /**
-     * Tell if action is enabled. Compared to {@link #canPerformAction()} this is based on settings
-     * if the action is disabled for a particular gesture. For example a back action can be enabled
-     * however if there is nothing to back to then {@link #canPerformAction()} should return false.
-     * In this way if the action requires {@link #allowHitTargetToMoveOverDrag()} then if enabled,
-     * the button can be dragged with a large dampening factor during the gesture but will not
-     * activate the action.
-     * @return true if this action is enabled and can run
-     */
-    public abstract boolean isEnabled();
-
-    protected void onDarkIntensityChange(float intensity) {
-    }
-
-    protected void onDraw(Canvas canvas) {
-    }
-
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-    }
-
-    /**
-     * When gesture starts, this will run to execute the action
-     * @param event the event that triggered the gesture
-     */
-    protected abstract void onGestureStart(MotionEvent event);
-
-    /**
-     * Channels motion move events to the action to track the user inputs
-     * @param x the x position
-     * @param y the y position
-     */
-    public void onGestureMove(int x, int y) {
-    }
-
-    /**
-     * When gesture ends, this will run from action up or cancel
-     */
-    protected void onGestureEnd() {
-    }
-
-    protected Context getContext() {
-        return mNavigationBarView.getContext();
-    }
-
-    protected boolean isNavBarVertical() {
-        return mNavigationBarPosition == NAV_BAR_LEFT || mNavigationBarPosition == NAV_BAR_RIGHT;
-    }
-
-    protected boolean getGlobalBoolean(@NonNull String key) {
-        return QuickStepController.getBoolGlobalSetting(getContext(), key);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java
index 968074c..7dc71f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java
@@ -57,6 +57,7 @@
         mLightColor = Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor);
         mDarkColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor);
         mPaint.setAntiAlias(true);
+        setFocusable(false);
     }
 
     @Override
@@ -68,7 +69,7 @@
         int height = mRadius * 2;
         int width = getWidth();
         int y = (navHeight - mBottom - height);
-        canvas.drawRoundRect(mRadius, y, width - mRadius, y + height, mRadius, mRadius, mPaint);
+        canvas.drawRoundRect(0, y, width, y + height, mRadius, mRadius, mPaint);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
index 7ea72c7..47a1054 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
@@ -17,7 +17,9 @@
 package com.android.systemui.statusbar.phone;
 
 import android.annotation.IntDef;
+import android.content.ComponentCallbacks;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.Point;
@@ -25,6 +27,8 @@
 import android.os.Handler;
 import android.provider.Settings;
 
+import com.android.systemui.shared.system.QuickStepContract;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -33,7 +37,7 @@
  * prototypes to run in the system. The class will handle communication changes from the settings
  * app and call back to listeners.
  */
-public class NavigationPrototypeController extends ContentObserver {
+public class NavigationPrototypeController extends ContentObserver implements ComponentCallbacks {
     private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback";
     private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome";
     private static final String PROTOTYPE_ENABLED = "prototype_enabled";
@@ -85,9 +89,9 @@
         registerObserver(HIDE_HOME_BUTTON_SETTING);
         registerObserver(GESTURE_MATCH_SETTING);
         registerObserver(NAV_COLOR_ADAPT_ENABLE_SETTING);
-        registerObserver(EDGE_SENSITIVITY_WIDTH_SETTING);
         registerObserver(SHOW_HOME_HANDLE_SETTING);
         registerObserver(ENABLE_ASSISTANT_GESTURE);
+        mContext.registerComponentCallbacks(this);
     }
 
     /**
@@ -95,6 +99,7 @@
      */
     public void unregister() {
         mContext.getContentResolver().unregisterContentObserver(this);
+        mContext.unregisterComponentCallbacks(this);
     }
 
     @Override
@@ -115,9 +120,6 @@
             } else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) {
                 mListener.onColorAdaptChanged(
                         NavBarTintController.isEnabled(mContext));
-            } else if (path.endsWith(EDGE_SENSITIVITY_WIDTH_SETTING)) {
-                mListener.onEdgeSensitivityChanged(getEdgeSensitivityWidth(),
-                        getEdgeSensitivityHeight());
             } else if (path.endsWith(SHOW_HOME_HANDLE_SETTING)) {
                 mListener.onHomeHandleVisiblilityChanged(showHomeHandle());
             } else if (path.endsWith(ENABLE_ASSISTANT_GESTURE)) {
@@ -130,8 +132,7 @@
      * @return the width for edge swipe
      */
     public int getEdgeSensitivityWidth() {
-        // TODO: Move into resource
-        return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 48));
+        return QuickStepContract.getEdgeSensitivityWidth(mContext);
     }
 
     /**
@@ -203,6 +204,18 @@
         return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
     }
 
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        if (mListener != null) {
+            mListener.onEdgeSensitivityChanged(getEdgeSensitivityWidth(),
+                    getEdgeSensitivityHeight());
+        }
+    }
+
+    @Override
+    public void onLowMemory() {
+    }
+
     public interface OnPrototypeChangedListener {
         void onGestureRemap(@GestureAction int[] actions);
         void onBackButtonVisibilityChanged(boolean visible);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index b902e43..cff3855 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -152,9 +152,11 @@
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
     @VisibleForTesting
     protected KeyguardStatusBarView mKeyguardStatusBar;
-    private ViewGroup mBigClockContainer;
+    @VisibleForTesting
+    protected ViewGroup mBigClockContainer;
     private QS mQs;
-    private FrameLayout mQsFrame;
+    @VisibleForTesting
+    protected FrameLayout mQsFrame;
     @VisibleForTesting
     protected KeyguardStatusView mKeyguardStatusView;
     private View mQsNavbarScrim;
@@ -266,6 +268,7 @@
     private int mIndicationBottomPadding;
     private int mAmbientIndicationBottomPadding;
     private boolean mIsFullWidth;
+    private boolean mBlockingExpansionForCurrentTouch;
 
     /**
      * Current dark amount that follows regular interpolation curve of animation.
@@ -635,6 +638,7 @@
         }
         mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding);
         mNotificationStackScroller.setAntiBurnInOffsetX(mClockPositionResult.clockX);
+        mKeyguardBottomArea.setAntiBurnInOffsetX(mClockPositionResult.clockX);
 
         mStackScrollerMeasuringPass++;
         requestScrollerTopPaddingUpdate(animate);
@@ -982,6 +986,11 @@
             return false;
         }
         initDownStates(event);
+        // Make sure the next touch won't the blocked after the current ends.
+        if (event.getAction() == MotionEvent.ACTION_UP
+                || event.getAction() == MotionEvent.ACTION_CANCEL) {
+            mBlockingExpansionForCurrentTouch = false;
+        }
         if (!mIsExpanding && mPulseExpansionHandler.onTouchEvent(event)) {
             // We're expanding all the other ones shouldn't get this anymore
             return true;
@@ -1661,7 +1670,7 @@
         if (!mQsExpansionEnabled || mCollapsedOnDown) {
             return false;
         }
-        View header = mKeyguardShowing ? mKeyguardStatusBar : mQs.getHeader();
+        View header = mKeyguardShowing || mQs == null ? mKeyguardStatusBar : mQs.getHeader();
         final boolean onHeader = x >= mQsFrame.getX()
                 && x <= mQsFrame.getX() + mQsFrame.getWidth()
                 && y >= header.getTop() && y <= header.getBottom();
@@ -1886,7 +1895,7 @@
         float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
                 * mKeyguardStatusBarAnimateAlpha;
         mKeyguardStatusBar.setAlpha(newAlpha);
-        mKeyguardStatusBar.setVisibility(newAlpha != 0f ? VISIBLE : INVISIBLE);
+        mKeyguardStatusBar.setVisibility(newAlpha != 0f && !mDozing ? VISIBLE : INVISIBLE);
     }
 
     private void updateKeyguardBottomAreaAlpha() {
@@ -2336,7 +2345,7 @@
 
     @Override
     protected boolean isTrackingBlocked() {
-        return mConflictingQsExpansionGesture && mQsExpanded;
+        return mConflictingQsExpansionGesture && mQsExpanded || mBlockingExpansionForCurrentTouch;
     }
 
     public boolean isQsExpanded() {
@@ -2373,12 +2382,11 @@
         positionClockAndNotifications();
     }
 
-    private static float interpolate(float t, float start, float end) {
-        return (1 - t) * start + t * end;
-    }
-
     private void updateDozingVisibilities(boolean animate) {
         mKeyguardBottomArea.setDozing(mDozing, animate);
+        if (!mDozing && animate) {
+            animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+        }
     }
 
     @Override
@@ -2814,7 +2822,7 @@
         if (mDozing) {
             mNotificationStackScroller.setShowDarkShelf(!hasCustomClock());
         }
-        mKeyguardStatusBar.setDozing(mDozing);
+        mKeyguardBottomArea.setDozing(mDozing, animate);
 
         if (mBarState == StatusBarState.KEYGUARD
                 || mBarState == StatusBarState.SHADE_LOCKED) {
@@ -2829,7 +2837,6 @@
     public void onDozeAmountChanged(float linearAmount, float amount) {
         mInterpolatedDarkAmount = amount;
         mLinearDarkAmount = linearAmount;
-        mKeyguardStatusBar.setDarkAmount(mInterpolatedDarkAmount);
         mKeyguardStatusView.setDarkAmount(mInterpolatedDarkAmount);
         mKeyguardBottomArea.setDarkAmount(mInterpolatedDarkAmount);
         positionClockAndNotifications();
@@ -2861,7 +2868,7 @@
     }
 
     public void dozeTimeTick() {
-        mKeyguardStatusBar.dozeTimeTick();
+        mKeyguardBottomArea.dozeTimeTick();
         mKeyguardStatusView.dozeTimeTick();
         if (mInterpolatedDarkAmount > 0) {
             positionClockAndNotifications();
@@ -2938,6 +2945,14 @@
         updateLockIcon();
     }
 
+    /**
+     * Do not let the user drag the shade up and down for the current touch session.
+     * This is necessary to avoid shade expansion while/after the bouncer is dismissed.
+     */
+    public void blockExpansionForCurrentTouch() {
+        mBlockingExpansionForCurrentTouch = mTracking;
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         super.dump(fd, pw, args);
@@ -3040,6 +3055,7 @@
         }
 
         ViewGroup bouncerContainer = mBouncer.getLockIconContainer();
+        ViewGroup bottomContainer = mKeyguardBottomArea.getLockIconContainer();
         LockIcon lockIcon = mKeyguardBottomArea.getLockIcon();
 
         if (mBouncer.isAnimatingAway()) {
@@ -3051,9 +3067,21 @@
             return;
         }
 
+        // Lock icon needs to be re-parented in case of a scrimmed bouncer,
+        // otherwise it would be under the scrim.
+        if (mBouncer.isScrimmed() && bouncerContainer != null
+                && lockIcon.getParent() != bouncerContainer) {
+            ((ViewGroup) lockIcon.getParent()).removeView(lockIcon);
+            bouncerContainer.addView(lockIcon);
+        } else if (!mBouncer.isScrimmed() && bottomContainer != null
+                && lockIcon.getParent() != bottomContainer) {
+            ((ViewGroup) lockIcon.getParent()).removeView(lockIcon);
+            bottomContainer.addView(lockIcon);
+        }
+
         float translation = 0;
-        if (bouncerContainer != null) {
-            float bottomAreaContainerY = getCommonTop(lockIcon);
+        if (bouncerContainer != null && bottomContainer != null && !mBouncer.isScrimmed()) {
+            float bottomAreaContainerY = getCommonTop(bottomContainer);
             float bouncerLockY = getCommonTop(bouncerContainer);
             if (bouncerLockY < bottomAreaContainerY) {
                 translation = bouncerLockY - bottomAreaContainerY;
@@ -3069,7 +3097,7 @@
     private static float getCommonTop(View view) {
         float y = view.getTop();
         ViewGroup parent = (ViewGroup) view.getParent();
-        while (!(parent instanceof StatusBarWindowView)) {
+        while (!(parent instanceof StatusBarWindowView) && parent != null) {
             y += parent.getY();
             parent = (ViewGroup) parent.getParent();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index b7a7873..183fdb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -201,7 +201,7 @@
         mIconController.setIconVisibility(mSlotAlarmClock, false);
 
         // zen
-        mIconController.setIcon(mSlotZen, R.drawable.stat_sys_zen_important, null);
+        mIconController.setIcon(mSlotZen, R.drawable.stat_sys_dnd, null);
         mIconController.setIconVisibility(mSlotZen, false);
 
         // volume
@@ -339,11 +339,11 @@
             zenDescription = mContext.getString(R.string.quick_settings_dnd_label);
         } else if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
             zenVisible = true;
-            zenIconId = R.drawable.stat_sys_zen_none;
+            zenIconId = R.drawable.stat_sys_dnd;
             zenDescription = mContext.getString(R.string.interruption_level_none);
         } else if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
             zenVisible = true;
-            zenIconId = R.drawable.stat_sys_zen_important;
+            zenIconId = R.drawable.stat_sys_dnd;
             zenDescription = mContext.getString(R.string.interruption_level_priority);
         }
 
@@ -388,13 +388,12 @@
     }
 
     private final void updateBluetooth() {
-        int iconId = R.drawable.stat_sys_data_bluetooth;
+        int iconId = R.drawable.stat_sys_data_bluetooth_connected;
         String contentDescription =
                 mContext.getString(R.string.accessibility_quick_settings_bluetooth_on);
         boolean bluetoothVisible = false;
         if (mBluetooth != null) {
             if (mBluetooth.isBluetoothConnected()) {
-                iconId = R.drawable.stat_sys_data_bluetooth_connected;
                 contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected);
                 bluetoothVisible = mBluetooth.isBluetoothEnabled();
             }
@@ -582,8 +581,8 @@
             String contentDescription = mContext.getString(hasMic
                     ? R.string.accessibility_status_bar_headset
                     : R.string.accessibility_status_bar_headphones);
-            mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.ic_headset_mic
-                    : R.drawable.ic_headset, contentDescription);
+            mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.stat_sys_headset_mic
+                    : R.drawable.stat_sys_headset, contentDescription);
             mIconController.setIconVisibility(mSlotHeadset, true);
         } else {
             mIconController.setIconVisibility(mSlotHeadset, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
deleted file mode 100644
index bbfd51a..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import static com.android.systemui.Interpolators.ALPHA_IN;
-import static com.android.systemui.Interpolators.ALPHA_OUT;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.annotation.NonNull;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RadialGradient;
-import android.graphics.Shader;
-import android.util.FloatProperty;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.systemui.R;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.shared.recents.utilities.Utilities;
-
-/**
- * QuickScrub action to send to launcher to start quickscrub gesture
- */
-public class QuickScrubAction extends QuickSwitchAction {
-    private static final String TAG = "QuickScrubAction";
-
-    private static final float TRACK_SCALE = 0.95f;
-    private static final float GRADIENT_WIDTH = .75f;
-    private static final int ANIM_IN_DURATION_MS = 150;
-    private static final int ANIM_OUT_DURATION_MS = 134;
-
-    private AnimatorSet mTrackAnimator;
-    private View mCurrentNavigationBarView;
-
-    private float mTrackScale = TRACK_SCALE;
-    private float mTrackAlpha;
-    private float mHighlightCenter;
-    private float mDarkIntensity;
-
-    private final int mTrackThickness;
-    private final int mTrackEndPadding;
-    private final Paint mTrackPaint = new Paint();
-
-    private final FloatProperty<QuickScrubAction> mTrackAlphaProperty =
-            new FloatProperty<QuickScrubAction>("TrackAlpha") {
-        @Override
-        public void setValue(QuickScrubAction action, float alpha) {
-            mTrackAlpha = alpha;
-            mNavigationBarView.invalidate();
-        }
-
-        @Override
-        public Float get(QuickScrubAction action) {
-            return mTrackAlpha;
-        }
-    };
-
-    private final FloatProperty<QuickScrubAction> mTrackScaleProperty =
-            new FloatProperty<QuickScrubAction>("TrackScale") {
-        @Override
-        public void setValue(QuickScrubAction action, float scale) {
-            mTrackScale = scale;
-            mNavigationBarView.invalidate();
-        }
-
-        @Override
-        public Float get(QuickScrubAction action) {
-            return mTrackScale;
-        }
-    };
-
-    private final FloatProperty<QuickScrubAction> mNavBarAlphaProperty =
-            new FloatProperty<QuickScrubAction>("NavBarAlpha") {
-        @Override
-        public void setValue(QuickScrubAction action, float alpha) {
-            if (mCurrentNavigationBarView != null) {
-                mCurrentNavigationBarView.setAlpha(alpha);
-            }
-        }
-
-        @Override
-        public Float get(QuickScrubAction action) {
-            if (mCurrentNavigationBarView != null) {
-                return mCurrentNavigationBarView.getAlpha();
-            }
-            return 1f;
-        }
-    };
-
-    private AnimatorListenerAdapter mQuickScrubEndListener = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (mCurrentNavigationBarView != null) {
-                mCurrentNavigationBarView.setAlpha(1f);
-            }
-            mCurrentNavigationBarView = null;
-            updateHighlight();
-        }
-    };
-
-    public QuickScrubAction(@NonNull NavigationBarView navigationBarView,
-            @NonNull OverviewProxyService service) {
-        super(navigationBarView, service);
-        mTrackPaint.setAntiAlias(true);
-        mTrackPaint.setDither(true);
-
-        final Resources res = navigationBarView.getResources();
-        mTrackThickness = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_thickness);
-        mTrackEndPadding = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_edge_padding);
-    }
-
-    @Override
-    public void setBarState(boolean changed, int navBarPos, boolean dragHorPositive,
-            boolean dragVerPositive) {
-        super.setBarState(changed, navBarPos, dragHorPositive, dragVerPositive);
-        if (changed && isActive()) {
-            // End quickscrub if the state changes mid-transition
-            endQuickScrub(false /* animate */);
-        }
-    }
-
-    @Override
-    public void reset() {
-        super.reset();
-
-        // End any existing quickscrub animations before starting the new transition
-        if (mTrackAnimator != null) {
-            mTrackAnimator.end();
-            mTrackAnimator = null;
-        }
-        mCurrentNavigationBarView = mNavigationBarView.getCurrentView();
-    }
-
-    @Override
-    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        final int paddingLeft = mNavigationBarView.getPaddingLeft();
-        final int paddingTop = mNavigationBarView.getPaddingTop();
-        final int paddingRight = mNavigationBarView.getPaddingRight();
-        final int paddingBottom = mNavigationBarView.getPaddingBottom();
-        final int width = (right - left) - paddingRight - paddingLeft;
-        final int height = (bottom - top) - paddingBottom - paddingTop;
-        final int x1, x2, y1, y2;
-        if (isNavBarVertical()) {
-            x1 = (width - mTrackThickness) / 2 + paddingLeft;
-            x2 = x1 + mTrackThickness;
-            y1 = paddingTop + mTrackEndPadding;
-            y2 = y1 + height - 2 * mTrackEndPadding;
-        } else {
-            y1 = (height - mTrackThickness) / 2 + paddingTop;
-            y2 = y1 + mTrackThickness;
-            x1 = mNavigationBarView.getPaddingStart() + mTrackEndPadding;
-            x2 = x1 + width - 2 * mTrackEndPadding;
-        }
-        mDragOverRect.set(x1, y1, x2, y2);
-    }
-
-    @Override
-    public void onDarkIntensityChange(float intensity) {
-        mDarkIntensity = intensity;
-        updateHighlight();
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        if (!isEnabled()) {
-            return;
-        }
-        mTrackPaint.setAlpha(Math.round(255f * mTrackAlpha));
-
-        // Scale the track, but apply the inverse scale from the nav bar
-        final float radius = mDragOverRect.height() / 2;
-        canvas.save();
-        float translate = Utilities.clamp(mHighlightCenter, mDragOverRect.left,
-                mDragOverRect.right);
-        canvas.translate(translate, 0);
-        canvas.scale(mTrackScale / mNavigationBarView.getScaleX(),
-                1f / mNavigationBarView.getScaleY(),
-                mDragOverRect.centerX(), mDragOverRect.centerY());
-        canvas.drawRoundRect(mDragOverRect.left - translate, mDragOverRect.top,
-                mDragOverRect.right - translate, mDragOverRect.bottom, radius, radius, mTrackPaint);
-        canvas.restore();
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return mNavigationBarView.isQuickScrubEnabled();
-    }
-
-    @Override
-    protected void onGestureStart(MotionEvent event) {
-        updateHighlight();
-        ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
-                PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 1f),
-                PropertyValuesHolder.ofFloat(mTrackScaleProperty, 1f));
-        trackAnimator.setInterpolator(ALPHA_IN);
-        trackAnimator.setDuration(ANIM_IN_DURATION_MS);
-        ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 0f);
-        navBarAnimator.setInterpolator(ALPHA_OUT);
-        navBarAnimator.setDuration(ANIM_OUT_DURATION_MS);
-        mTrackAnimator = new AnimatorSet();
-        mTrackAnimator.playTogether(trackAnimator, navBarAnimator);
-        mTrackAnimator.start();
-
-        startQuickGesture(event);
-    }
-
-    @Override
-    public void onGestureMove(int x, int y) {
-        super.onGestureMove(x, y);
-        mHighlightCenter = x;
-        mNavigationBarView.invalidate();
-    }
-
-    @Override
-    protected void onGestureEnd() {
-        endQuickScrub(true /* animate */);
-    }
-
-    private void endQuickScrub(boolean animate) {
-        animateEnd();
-        endQuickGesture(animate);
-        if (!animate) {
-            if (mTrackAnimator != null) {
-                mTrackAnimator.end();
-                mTrackAnimator = null;
-            }
-        }
-    }
-
-    private void updateHighlight() {
-        if (mDragOverRect.isEmpty()) {
-            return;
-        }
-        int colorBase, colorGrad;
-        if (mDarkIntensity > 0.5f) {
-            colorBase = getContext().getColor(R.color.quick_step_track_background_background_dark);
-            colorGrad = getContext().getColor(R.color.quick_step_track_background_foreground_dark);
-        } else {
-            colorBase = getContext().getColor(R.color.quick_step_track_background_background_light);
-            colorGrad = getContext().getColor(R.color.quick_step_track_background_foreground_light);
-        }
-        final RadialGradient mHighlight = new RadialGradient(0, mDragOverRect.height() / 2,
-                mDragOverRect.width() * GRADIENT_WIDTH, colorGrad, colorBase,
-                Shader.TileMode.CLAMP);
-        mTrackPaint.setShader(mHighlight);
-    }
-
-    private void animateEnd() {
-        if (mTrackAnimator != null) {
-            mTrackAnimator.cancel();
-        }
-
-        ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
-                PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 0f),
-                PropertyValuesHolder.ofFloat(mTrackScaleProperty, TRACK_SCALE));
-        trackAnimator.setInterpolator(ALPHA_OUT);
-        trackAnimator.setDuration(ANIM_OUT_DURATION_MS);
-        ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 1f);
-        navBarAnimator.setInterpolator(ALPHA_IN);
-        navBarAnimator.setDuration(ANIM_IN_DURATION_MS);
-        mTrackAnimator = new AnimatorSet();
-        mTrackAnimator.playTogether(trackAnimator, navBarAnimator);
-        mTrackAnimator.addListener(mQuickScrubEndListener);
-        mTrackAnimator.start();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java
deleted file mode 100644
index b18b79e..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import static com.android.systemui.recents.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
-import static com.android.systemui.recents.OverviewProxyService.TAG_OPS;
-
-import android.annotation.NonNull;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.systemui.recents.OverviewProxyService;
-
-/**
- * QuickStep action to send to launcher to start overview
- */
-public class QuickStepAction extends NavigationGestureAction {
-    private static final String TAG = "QuickStepAction";
-
-    public QuickStepAction(@NonNull NavigationBarView navigationBarView,
-            @NonNull OverviewProxyService service) {
-        super(navigationBarView, service);
-    }
-
-    @Override
-    public boolean canRunWhenNotificationsShowing() {
-        return false;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return mNavigationBarView.isQuickStepSwipeUpEnabled();
-    }
-
-    @Override
-    public void onGestureStart(MotionEvent event) {
-        try {
-            mProxySender.getProxy().onQuickStep(event);
-            if (DEBUG_OVERVIEW_PROXY) {
-                Log.d(TAG_OPS, "Quick Step Start");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to send quick step started.", e);
-        }
-        mProxySender.notifyQuickStepStarted();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
deleted file mode 100644
index 25cb7d0..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ /dev/null
@@ -1,735 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar.phone;
-
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
-
-import static com.android.systemui.recents.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
-import static com.android.systemui.recents.OverviewProxyService.TAG_OPS;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_DEAD_ZONE;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
-import static com.android.systemui.statusbar.phone.NavigationBarView.WINDOW_TARGET_BOTTOM;
-import static com.android.systemui.statusbar.phone.NavigationPrototypeController.EDGE_SENSITIVITY_WIDTH_SETTING;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.hardware.input.InputManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewPropertyAnimator;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.SysUiServiceProvider;
-import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.shared.recents.IOverviewProxy;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher;
-import com.android.systemui.shared.system.NavigationBarCompat;
-import com.android.systemui.shared.system.QuickStepContract;
-
-import java.io.PrintWriter;
-
-/**
- * Class to detect gestures on the navigation bar and implement quick scrub.
- * Note that the variables in this class horizontal and vertical represents horizontal always
- * aligned with along the navigation bar.
- */
-public class QuickStepController implements GestureHelper {
-
-    private static final String TAG = "QuickStepController";
-
-    /** Experiment to swipe home button left to execute a back key press */
-    private static final String HIDE_BACK_BUTTON_PROP = "quickstepcontroller_hideback";
-    private static final String HIDE_HOME_BUTTON_PROP = "quickstepcontroller_hidehome";
-    private static final String ENABLE_CLICK_THROUGH_NAV_PROP = "quickstepcontroller_clickthrough";
-    private static final String GESTURE_REGION_THRESHOLD_SETTING = "gesture_region_threshold";
-    private static final long BACK_BUTTON_FADE_IN_ALPHA = 150;
-    private static final long CLICK_THROUGH_TAP_DELAY = 70;
-    private static final long CLICK_THROUGH_TAP_RESET_DELAY = 100;
-
-    /** When the home-swipe-back gesture is disallowed, make it harder to pull */
-    private static final float HORIZONTAL_GESTURE_DAMPING = 0.3f;
-    private static final float VERTICAL_GESTURE_DAMPING = 0.15f;
-    private static final float HORIZONTAL_DISABLED_GESTURE_DAMPING = 0.16f;
-    private static final float VERTICAL_DISABLED_GESTURE_DAMPING = 0.06f;
-
-    private static final int ACTION_SWIPE_UP_INDEX = 0;
-    private static final int ACTION_SWIPE_DOWN_INDEX = 1;
-    private static final int ACTION_SWIPE_LEFT_INDEX = 2;
-    private static final int ACTION_SWIPE_RIGHT_INDEX = 3;
-    private static final int ACTION_SWIPE_LEFT_FROM_EDGE_INDEX = 4;
-    private static final int ACTION_SWIPE_RIGHT_FROM_EDGE_INDEX = 5;
-    private static final int MAX_GESTURES = 6;
-
-    private NavigationBarView mNavigationBarView;
-
-    private boolean mAllowGestureDetection;
-    private boolean mNotificationsVisibleOnDown;
-    private int mTouchDownX;
-    private int mTouchDownY;
-    private boolean mDragHPositive;
-    private boolean mDragVPositive;
-    private boolean mIsRTL;
-    private int mNavBarPosition;
-    private float mDarkIntensity;
-    private ViewPropertyAnimator mDragBtnAnimator;
-    private ButtonDispatcher mHitTarget;
-    private boolean mIsInScreenPinning;
-    private boolean mGestureHorizontalDragsButton;
-    private boolean mGestureVerticalDragsButton;
-    private float mMaxDragLimit;
-    private float mMinDragLimit;
-    private float mDragDampeningFactor;
-    private boolean mClickThroughPressed;
-    private float mClickThroughPressX;
-    private float mClickThroughPressY;
-    private int mGestureRegionThreshold;
-
-    private NavigationGestureAction mCurrentAction;
-    private NavigationGestureAction[] mGestureActions = new NavigationGestureAction[MAX_GESTURES];
-
-    private final Rect mLastLayoutRect = new Rect();
-    private final OverviewProxyService mOverviewEventSender;
-    private final Context mContext;
-    private final StatusBar mStatusBar;
-    private final Matrix mTransformGlobalMatrix = new Matrix();
-    private final Matrix mTransformLocalMatrix = new Matrix();
-
-    public QuickStepController(Context context) {
-        mContext = context;
-        mStatusBar = SysUiServiceProvider.getComponent(context, StatusBar.class);
-        mOverviewEventSender = Dependency.get(OverviewProxyService.class);
-    }
-
-    private final Runnable mClickThroughSendTap = new Runnable() {
-        @Override
-        public void run() {
-            sendTap(mClickThroughPressX, mClickThroughPressY);
-            mNavigationBarView.postDelayed(mClickThroughResetTap, CLICK_THROUGH_TAP_RESET_DELAY);
-        }
-    };
-
-    private final Runnable mClickThroughResetTap = () -> {
-        mNavigationBarView.setWindowTouchable(true);
-        mClickThroughPressed = false;
-    };
-
-    public void setComponents(NavigationBarView navigationBarView) {
-        mNavigationBarView = navigationBarView;
-
-        mNavigationBarView.getBackButton().setVisibility(shouldHideBackButton(mContext)
-                ? View.GONE
-                : View.VISIBLE);
-    }
-
-    /**
-     * Set each gesture an action. After set the gestures triggered will run the actions attached.
-     * @param swipeUpAction action after swiping up
-     * @param swipeDownAction action after swiping down
-     * @param swipeLeftAction action after swiping left
-     * @param swipeRightAction action after swiping right
-     * @param swipeLeftFromEdgeAction action swiping left starting from the right side
-     * @param swipeRightFromEdgeAction action swiping right starting from the left side
-     */
-    public void setGestureActions(@Nullable NavigationGestureAction swipeUpAction,
-            @Nullable NavigationGestureAction swipeDownAction,
-            @Nullable NavigationGestureAction swipeLeftAction,
-            @Nullable NavigationGestureAction swipeRightAction,
-            @Nullable NavigationGestureAction swipeLeftFromEdgeAction,
-            @Nullable NavigationGestureAction swipeRightFromEdgeAction) {
-        mGestureActions[ACTION_SWIPE_UP_INDEX] = swipeUpAction;
-        mGestureActions[ACTION_SWIPE_DOWN_INDEX] = swipeDownAction;
-        mGestureActions[ACTION_SWIPE_LEFT_INDEX] = swipeLeftAction;
-        mGestureActions[ACTION_SWIPE_RIGHT_INDEX] = swipeRightAction;
-        mGestureActions[ACTION_SWIPE_LEFT_FROM_EDGE_INDEX] = swipeLeftFromEdgeAction;
-        mGestureActions[ACTION_SWIPE_RIGHT_FROM_EDGE_INDEX] = swipeRightFromEdgeAction;
-
-        // Set the current state to all actions
-        for (NavigationGestureAction action: mGestureActions) {
-            if (action != null) {
-                action.setBarState(true, mNavBarPosition, mDragHPositive, mDragVPositive);
-                action.onDarkIntensityChange(mDarkIntensity);
-                action.onLayout(true /* changed */, mLastLayoutRect.left, mLastLayoutRect.top,
-                        mLastLayoutRect.right, mLastLayoutRect.bottom);
-            }
-        }
-    }
-
-    /**
-     * @return true if we want to intercept touch events for quick scrub and prevent proxying the
-     *         event to the overview service.
-     */
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent event) {
-        return handleTouchEvent(event);
-    }
-
-    /**
-     * @return true if we want to handle touch events for quick scrub or if down event (that will
-     *         get consumed and ignored). No events will be proxied to the overview service.
-     */
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        // The same down event was just sent on intercept and therefore can be ignored here
-        final boolean ignoreProxyDownEvent = event.getAction() == MotionEvent.ACTION_DOWN
-                && mOverviewEventSender.getProxy() != null
-                && mNavigationBarView.getWindowTarget() == WINDOW_TARGET_BOTTOM;
-        return ignoreProxyDownEvent || handleTouchEvent(event);
-    }
-
-    private boolean handleTouchEvent(MotionEvent event) {
-        final boolean deadZoneConsumed =
-                mNavigationBarView.getDownHitTarget() == HIT_TARGET_DEAD_ZONE;
-
-        // Requires proxy and an active gesture or able to perform any gesture to continue
-        if (mOverviewEventSender.getProxy() == null
-                || !mOverviewEventSender.shouldShowSwipeUpUI()
-                || (mCurrentAction == null && !canPerformAnyAction())) {
-            return deadZoneConsumed;
-        }
-        mNavigationBarView.requestUnbufferedDispatch(event);
-
-        int action = event.getActionMasked();
-        switch (action) {
-            case MotionEvent.ACTION_DOWN: {
-                int x = (int) event.getX();
-                int y = (int) event.getY();
-                mIsInScreenPinning = mNavigationBarView.inScreenPinning();
-
-                for (NavigationGestureAction gestureAction: mGestureActions) {
-                    if (gestureAction != null) {
-                        gestureAction.reset();
-                    }
-                }
-
-                // Valid buttons to drag over
-                switch (mNavigationBarView.getDownHitTarget()) {
-                    case HIT_TARGET_BACK:
-                        mHitTarget = mNavigationBarView.getBackButton();
-                        break;
-                    case HIT_TARGET_HOME:
-                        mHitTarget = mNavigationBarView.getHomeButton();
-                        break;
-                    case HIT_TARGET_OVERVIEW:
-                        mHitTarget = mNavigationBarView.getRecentsButton();
-                        break;
-                    default:
-                        mHitTarget = null;
-                        break;
-                }
-                if (mHitTarget != null) {
-                    // Pre-emptively delay the touch feedback for the button that we just touched
-                    mHitTarget.setDelayTouchFeedback(true);
-                }
-                mTouchDownX = x;
-                mTouchDownY = y;
-                mGestureHorizontalDragsButton = false;
-                mGestureVerticalDragsButton = false;
-                mTransformGlobalMatrix.set(Matrix.IDENTITY_MATRIX);
-                mTransformLocalMatrix.set(Matrix.IDENTITY_MATRIX);
-                mNavigationBarView.transformMatrixToGlobal(mTransformGlobalMatrix);
-                mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix);
-                mAllowGestureDetection = true;
-                mNotificationsVisibleOnDown = !mNavigationBarView.isNotificationsFullyCollapsed();
-                final int defaultRegionThreshold = mContext.getResources()
-                        .getDimensionPixelOffset(R.dimen.navigation_bar_default_edge_width);
-                mGestureRegionThreshold = convertDpToPixel(getIntGlobalSetting(mContext,
-                        EDGE_SENSITIVITY_WIDTH_SETTING, defaultRegionThreshold));
-                break;
-            }
-            case MotionEvent.ACTION_MOVE: {
-                if (!mAllowGestureDetection
-                        || mNavigationBarView.getWindowTarget() != WINDOW_TARGET_BOTTOM) {
-                    break;
-                }
-                int x = (int) event.getX();
-                int y = (int) event.getY();
-                int xDiff = Math.abs(x - mTouchDownX);
-                int yDiff = Math.abs(y - mTouchDownY);
-
-                boolean exceededSwipeHorizontalTouchSlop, exceededSwipeVerticalTouchSlop,
-                        exceededSwipeVerticalDragSlop;
-                int posH, touchDownH, posV, touchDownV;
-
-                if (isNavBarVertical()) {
-                    exceededSwipeHorizontalTouchSlop =
-                            yDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && yDiff > xDiff;
-                    exceededSwipeVerticalTouchSlop =
-                            xDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && xDiff > yDiff;
-                    exceededSwipeVerticalDragSlop =
-                            xDiff > NavigationBarCompat.getQuickStepDragSlopPx() && xDiff > yDiff;
-                    posH = y;
-                    touchDownH = mTouchDownY;
-                    posV = x;
-                    touchDownV = mTouchDownX;
-                } else {
-                    exceededSwipeHorizontalTouchSlop =
-                            xDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && xDiff > yDiff;
-                    exceededSwipeVerticalTouchSlop =
-                            yDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && yDiff > xDiff;
-                    exceededSwipeVerticalDragSlop =
-                            yDiff > NavigationBarCompat.getQuickStepDragSlopPx() && yDiff > xDiff;
-                    posH = x;
-                    touchDownH = mTouchDownX;
-                    posV = y;
-                    touchDownV = mTouchDownY;
-                }
-
-                if (mCurrentAction != null) {
-                    // Gesture started, provide positions to the current action
-                    mCurrentAction.onGestureMove(x, y);
-                } else {
-                    // Detect gesture and try to execute an action, only one can run at a time
-                    if (exceededSwipeVerticalTouchSlop || exceededSwipeVerticalDragSlop) {
-                        if (mDragVPositive ? (posV < touchDownV) : (posV > touchDownV)) {
-                            // Swipe up gesture must use the larger slop
-                            if (exceededSwipeVerticalTouchSlop) {
-                                // Swiping up gesture
-                                tryToStartGesture(mGestureActions[ACTION_SWIPE_UP_INDEX],
-                                        false /* alignedWithNavBar */, event);
-                            }
-                        } else {
-                            // Swiping down gesture
-                            tryToStartGesture(mGestureActions[ACTION_SWIPE_DOWN_INDEX],
-                                    false /* alignedWithNavBar */, event);
-                        }
-                    } else if (exceededSwipeHorizontalTouchSlop) {
-                        if (mDragHPositive ? (posH < touchDownH) : (posH > touchDownH)) {
-                            // Swiping left (rtl) gesture
-                            tryToStartGesture(mGestureActions[ACTION_SWIPE_LEFT_INDEX],
-                                    true /* alignedWithNavBar */, event);
-                        } else {
-                            // Swiping right (ltr) gesture
-                            tryToStartGesture(mGestureActions[ACTION_SWIPE_RIGHT_INDEX],
-                                    true /* alignedWithNavBar */, event);
-                        }
-                    }
-                }
-
-                handleDragHitTarget(mGestureHorizontalDragsButton ? posH : posV,
-                        mGestureHorizontalDragsButton ? touchDownH : touchDownV);
-                break;
-            }
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-                if (mCurrentAction != null) {
-                    mCurrentAction.endGesture();
-                } else if (action == MotionEvent.ACTION_UP) {
-                    if (canTriggerEdgeSwipe(event)) {
-                        int index = mNavigationBarView.getWindowTarget() == NAV_BAR_LEFT
-                                ? ACTION_SWIPE_RIGHT_FROM_EDGE_INDEX
-                                : ACTION_SWIPE_LEFT_FROM_EDGE_INDEX;
-                        tryToStartGesture(mGestureActions[index], false /* alignedWithNavBar */,
-                                event);
-                        if (mCurrentAction != null) {
-                            mCurrentAction.endGesture();
-                        }
-                    } else if (QuickStepContract.isGesturalMode(mContext)
-                            && !mClickThroughPressed) {
-                        // Enable click through functionality where no gesture has been detected and
-                        // not passed the drag slop so inject a touch event at the same location
-                        // after making the navigation bar window untouchable. After a some time,
-                        // the navigation bar will be able to take input events again
-                        float diffX = Math.abs(event.getX() - mTouchDownX);
-                        float diffY = Math.abs(event.getY() - mTouchDownY);
-
-                        if ((diffX <= NavigationBarCompat.getQuickStepDragSlopPx()
-                                && diffY <= NavigationBarCompat.getQuickStepDragSlopPx())) {
-                            mNavigationBarView.setWindowTouchable(false);
-                            mClickThroughPressX = event.getRawX();
-                            mClickThroughPressY = event.getRawY();
-                            mClickThroughPressed = true;
-                            mNavigationBarView.postDelayed(mClickThroughSendTap,
-                                    CLICK_THROUGH_TAP_DELAY);
-                        }
-                    }
-                }
-
-                // Return the hit target back to its original position
-                if (mHitTarget != null) {
-                    final View button = mHitTarget.getCurrentView();
-                    if (mGestureHorizontalDragsButton || mGestureVerticalDragsButton) {
-                        mDragBtnAnimator = button.animate().setDuration(BACK_BUTTON_FADE_IN_ALPHA)
-                                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-                        if (mGestureVerticalDragsButton ^ isNavBarVertical()) {
-                            mDragBtnAnimator.translationY(0);
-                        } else {
-                            mDragBtnAnimator.translationX(0);
-                        }
-                        mDragBtnAnimator.start();
-                    }
-                }
-                break;
-        }
-
-        if (shouldProxyEvents(action)) {
-            proxyMotionEvents(event);
-        }
-
-        // Clear action when gesture and event proxy finishes
-        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
-            mCurrentAction = null;
-        }
-        return mCurrentAction != null || deadZoneConsumed;
-    }
-
-    private void handleDragHitTarget(int position, int touchDown) {
-        // Drag the hit target if gesture action requires it
-        if (mHitTarget != null && (mGestureVerticalDragsButton || mGestureHorizontalDragsButton)) {
-            final View button = mHitTarget.getCurrentView();
-            if (mDragBtnAnimator != null) {
-                mDragBtnAnimator.cancel();
-                mDragBtnAnimator = null;
-            }
-
-            // Clamp drag to the bounding box of the navigation bar
-            float diff = (position - touchDown) * mDragDampeningFactor;
-            diff = Utilities.clamp(diff, mMinDragLimit, mMaxDragLimit);
-            if (mGestureVerticalDragsButton ^ isNavBarVertical()) {
-                button.setTranslationY(diff);
-            } else {
-                button.setTranslationX(diff);
-            }
-        }
-    }
-
-    private boolean shouldProxyEvents(int action) {
-        // Do not send events for side navigation bar panels
-        if (mNavigationBarView.getWindowTarget() != WINDOW_TARGET_BOTTOM) {
-            return false;
-        }
-        final boolean actionValid = (mCurrentAction == null
-                || !mCurrentAction.disableProxyEvents());
-        if (actionValid && !mIsInScreenPinning) {
-            // Allow down, cancel and up events, move and other events are passed if notifications
-            // are not showing and disabled gestures (such as long press) are not executed
-            switch (action) {
-                case MotionEvent.ACTION_DOWN:
-                case MotionEvent.ACTION_CANCEL:
-                case MotionEvent.ACTION_UP:
-                    return true;
-                default:
-                    return !mNotificationsVisibleOnDown && mAllowGestureDetection;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        if (mCurrentAction != null) {
-            mCurrentAction.onDraw(canvas);
-        }
-    }
-
-    @Override
-    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        for (NavigationGestureAction action: mGestureActions) {
-            if (action != null) {
-                action.onLayout(changed, left, top, right, bottom);
-            }
-        }
-        mLastLayoutRect.set(left, top, right, bottom);
-    }
-
-    @Override
-    public void onDarkIntensityChange(float intensity) {
-        final float oldIntensity = mDarkIntensity;
-        mDarkIntensity = intensity;
-
-        // When in quick scrub, invalidate gradient if changing intensity from black to white and
-        // vice-versa
-        if (mCurrentAction != null && mNavigationBarView.isQuickScrubEnabled()
-                && Math.round(intensity) != Math.round(oldIntensity)) {
-            mCurrentAction.onDarkIntensityChange(mDarkIntensity);
-        }
-        mNavigationBarView.invalidate();
-    }
-
-    @Override
-    public void setBarState(boolean isRTL, int navBarPosition) {
-        final boolean changed = (mIsRTL != isRTL) || (mNavBarPosition != navBarPosition);
-        mIsRTL = isRTL;
-        mNavBarPosition = navBarPosition;
-
-        // Determine the drag directions depending on location of nav bar
-        switch (navBarPosition) {
-            case NAV_BAR_LEFT:
-                mDragHPositive = !isRTL;
-                mDragVPositive = false;
-                break;
-            case NAV_BAR_RIGHT:
-                mDragHPositive = isRTL;
-                mDragVPositive = true;
-                break;
-            case NAV_BAR_BOTTOM:
-                mDragHPositive = !isRTL;
-                mDragVPositive = true;
-                break;
-            case NAV_BAR_INVALID:
-                Log.e(TAG, "Invalid nav bar position");
-                break;
-        }
-
-        for (NavigationGestureAction action: mGestureActions) {
-            if (action != null) {
-                action.setBarState(changed, mNavBarPosition, mDragHPositive, mDragVPositive);
-            }
-        }
-    }
-
-    @Override
-    public void onNavigationButtonLongPress(View v) {
-        mAllowGestureDetection = false;
-    }
-
-    @Override
-    public void dump(PrintWriter pw) {
-        pw.println("QuickStepController {");
-        pw.print("    "); pw.println("mAllowGestureDetection=" + mAllowGestureDetection);
-        pw.print("    "); pw.println("mNotificationsVisibleOnDown=" + mNotificationsVisibleOnDown);
-        pw.print("    "); pw.println("mNavBarPosition=" + mNavBarPosition);
-        pw.print("    "); pw.println("mIsRTL=" + mIsRTL);
-        pw.print("    "); pw.println("mIsInScreenPinning=" + mIsInScreenPinning);
-        pw.println("}");
-    }
-
-    public NavigationGestureAction getCurrentAction() {
-        return mCurrentAction;
-    }
-
-    private void tryToStartGesture(NavigationGestureAction action, boolean alignedWithNavBar,
-            MotionEvent event) {
-        if (action == null) {
-            return;
-        }
-        if (mIsInScreenPinning) {
-            mNavigationBarView.showPinningEscapeToast();
-            mAllowGestureDetection = false;
-            return;
-        }
-
-        // Start new action from gesture if is able to start and depending on notifications
-        // visibility and starting touch down target. If the action is enabled, then also check if
-        // can perform the action so that if action requires the button to be dragged, then the
-        // gesture will have a large dampening factor and prevent action from running.
-        final boolean validHitTarget = action.requiresTouchDownHitTarget() == HIT_TARGET_NONE
-                || action.requiresTouchDownHitTarget() == mNavigationBarView.getDownHitTarget();
-        if (mCurrentAction == null && validHitTarget && action.isEnabled()
-                && (!mNotificationsVisibleOnDown || action.canRunWhenNotificationsShowing())) {
-            if (action.canPerformAction()) {
-                mCurrentAction = action;
-                event.transform(mTransformGlobalMatrix);
-                action.startGesture(event);
-                event.transform(mTransformLocalMatrix);
-
-                // Calculate the bounding limits of drag to avoid dragging off nav bar's window
-                if (action.allowHitTargetToMoveOverDrag() && mHitTarget != null) {
-                    final int[] buttonCenter = new int[2];
-                    View button = mHitTarget.getCurrentView();
-                    button.getLocationInWindow(buttonCenter);
-                    buttonCenter[0] += button.getWidth() / 2;
-                    buttonCenter[1] += button.getHeight() / 2;
-                    final int x = isNavBarVertical() ? buttonCenter[1] : buttonCenter[0];
-                    final int y = isNavBarVertical() ? buttonCenter[0] : buttonCenter[1];
-                    final int iconHalfSize = mContext.getResources()
-                            .getDimensionPixelSize(R.dimen.navigation_icon_size) / 2;
-
-                    if (alignedWithNavBar) {
-                        mMinDragLimit =  iconHalfSize - x;
-                        mMaxDragLimit = -x - iconHalfSize + (isNavBarVertical()
-                                ? mNavigationBarView.getHeight() : mNavigationBarView.getWidth());
-                    } else {
-                        mMinDragLimit = iconHalfSize - y;
-                        mMaxDragLimit =  -y - iconHalfSize + (isNavBarVertical()
-                                ? mNavigationBarView.getWidth() : mNavigationBarView.getHeight());
-                    }
-                }
-            }
-
-            // Handle direction of the hit target drag from the axis that started the gesture
-            // Also calculate the dampening factor, weaker dampening if there is an active action
-            if (action.allowHitTargetToMoveOverDrag()) {
-                if (alignedWithNavBar) {
-                    mGestureHorizontalDragsButton = true;
-                    mGestureVerticalDragsButton = false;
-                    mDragDampeningFactor = action.isActive()
-                            ? HORIZONTAL_GESTURE_DAMPING : HORIZONTAL_DISABLED_GESTURE_DAMPING;
-                } else {
-                    mGestureVerticalDragsButton = true;
-                    mGestureHorizontalDragsButton = false;
-                    mDragDampeningFactor = action.isActive()
-                            ? VERTICAL_GESTURE_DAMPING : VERTICAL_DISABLED_GESTURE_DAMPING;
-                }
-            }
-
-            if (mHitTarget != null) {
-                mHitTarget.abortCurrentGesture();
-            }
-        }
-    }
-
-    /**
-     * To trigger an edge swipe, the user must start from the left or right edges of certain height
-     * from the bottom then past the drag slope towards the center of the screen, followed by either
-     * a timed trigger for fast swipes or distance if held on the screen longer.
-     * For time, user must swipe up quickly before the Tap Timeout (typically 100ms) and for
-     * distance, the user can drag back to cancel if the touch up has not past the threshold.
-     * @param event Touch up event
-     * @return whether or not edge swipe gesture occurs
-     */
-    private boolean canTriggerEdgeSwipe(MotionEvent event) {
-        if (mNavigationBarView.getWindowTarget() == WINDOW_TARGET_BOTTOM) {
-            return false;
-        }
-        int x = (int) event.getX();
-        int y = (int) event.getY();
-        int xDiff = Math.abs(x - mTouchDownX);
-        int yDiff = Math.abs(y - mTouchDownY);
-        final boolean exceededSwipeTouchSlop = xDiff > NavigationBarCompat.getQuickStepDragSlopPx()
-                && xDiff > yDiff;
-        if (exceededSwipeTouchSlop) {
-            long timeDiff = event.getEventTime() - event.getDownTime();
-            return xDiff > mGestureRegionThreshold || timeDiff < ViewConfiguration.getTapTimeout();
-        }
-        return false;
-    }
-
-    private boolean canPerformAnyAction() {
-        for (NavigationGestureAction action: mGestureActions) {
-            if (action != null && action.isEnabled()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void sendTap(float x, float y) {
-        long now = SystemClock.uptimeMillis();
-        injectMotionEvent(InputDevice.SOURCE_TOUCHSCREEN, MotionEvent.ACTION_DOWN, now, x, y, 1.0f);
-        injectMotionEvent(InputDevice.SOURCE_TOUCHSCREEN, MotionEvent.ACTION_UP, now, x, y, 0.0f);
-    }
-
-    private int getInputDeviceId(int inputSource) {
-        int[] devIds = InputDevice.getDeviceIds();
-        for (int devId : devIds) {
-            InputDevice inputDev = InputDevice.getDevice(devId);
-            if (inputDev.supportsSource(inputSource)) {
-                return devId;
-            }
-        }
-        return 0;
-    }
-
-    private void injectMotionEvent(int inputSource, int action, long when, float x, float y,
-            float pressure) {
-        final float defaultSize = 1.0f;
-        final int defaultMetaState = 0;
-        final float defaultPrecisionX = 1.0f;
-        final float defaultPrecisionY = 1.0f;
-        final int defaultEdgeFlags = 0;
-        MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure, defaultSize,
-                defaultMetaState, defaultPrecisionX, defaultPrecisionY,
-                getInputDeviceId(inputSource), defaultEdgeFlags);
-        event.setSource(inputSource);
-        InputManager.getInstance().injectInputEvent(event,
-                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
-    }
-
-    private boolean proxyMotionEvents(MotionEvent event) {
-        event.transform(mTransformGlobalMatrix);
-        InputEventDispatcher dispatcher = mOverviewEventSender.getInputEventDispatcher();
-        if (dispatcher != null) {
-            dispatcher.dispatch(event);
-        }
-
-        final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
-        try {
-            if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-                overviewProxy.onPreMotionEvent(mNavigationBarView.getDownHitTarget());
-            }
-            overviewProxy.onMotionEvent(event);
-            if (DEBUG_OVERVIEW_PROXY) {
-                Log.d(TAG_OPS, "Send MotionEvent: " + event.toString());
-            }
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG, "Callback failed", e);
-        } finally {
-            event.transform(mTransformLocalMatrix);
-        }
-        return false;
-    }
-
-    protected boolean isNavBarVertical() {
-        return mNavBarPosition == NAV_BAR_LEFT || mNavBarPosition == NAV_BAR_RIGHT;
-    }
-
-    private static int convertDpToPixel(float dp) {
-        return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
-    }
-
-    // TODO(112934365): Clean up following methods when cleaning up nav bar experiments
-
-    static boolean getBoolGlobalSetting(Context context, String key) {
-        return Settings.Global.getInt(context.getContentResolver(), key, 0) != 0;
-    }
-
-    static int getIntGlobalSetting(Context context, String key, int defaultValue) {
-        return Settings.Global.getInt(context.getContentResolver(), key, defaultValue);
-    }
-
-    /**
-     * @return whether to hide the back button.
-     */
-    public static boolean shouldHideBackButton(Context context) {
-        return QuickStepContract.isGesturalMode(context);
-    }
-
-    /**
-     * @return whether to hide the home button.
-     */
-    public static boolean shouldHideHomeButton(Context context) {
-        return QuickStepContract.isGesturalMode(context);
-    }
-
-    /**
-     * @return whether to show the home handle.
-     */
-    public static boolean showHomeHandle(Context context) {
-        return QuickStepContract.isGesturalMode(context);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java
deleted file mode 100644
index 974de4b..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import static com.android.systemui.recents.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
-import static com.android.systemui.recents.OverviewProxyService.TAG_OPS;
-
-import android.annotation.NonNull;
-import android.graphics.Rect;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.shared.recents.utilities.Utilities;
-
-/**
- * QuickSwitch action to send to launcher
- */
-public class QuickSwitchAction extends NavigationGestureAction {
-    private static final String TAG = "QuickSwitchAction";
-
-    protected final Rect mDragOverRect = new Rect();
-
-    public QuickSwitchAction(@NonNull NavigationBarView navigationBar,
-            @NonNull OverviewProxyService service) {
-        super(navigationBar, service);
-    }
-
-    @Override
-    public void setBarState(boolean changed, int navBarPos, boolean dragHorPositive,
-            boolean dragVerPositive) {
-        super.setBarState(changed, navBarPos, dragHorPositive, dragVerPositive);
-        if (changed && isActive()) {
-            // End quickscrub if the state changes mid-transition
-            endQuickGesture(false /* animate */);
-        }
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return mNavigationBarView.isQuickScrubEnabled();
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        mDragOverRect.set(top, left, right, bottom);
-    }
-
-    @Override
-    public boolean disableProxyEvents() {
-        return true;
-    }
-
-    @Override
-    protected void onGestureStart(MotionEvent event) {
-        startQuickGesture(event);
-    }
-
-    @Override
-    public void onGestureMove(int x, int y) {
-        int dragLength, offset;
-        if (isNavBarVertical()) {
-            dragLength = mDragOverRect.height();
-            offset = y - mDragOverRect.top;
-        } else {
-            offset = x - mDragOverRect.left;
-            dragLength = mDragOverRect.width();
-        }
-        if (!mDragHorizontalPositive || !mDragVerticalPositive) {
-            offset -= dragLength;
-        }
-        float scrubFraction = Utilities.clamp(Math.abs(offset) * 1f / dragLength, 0, 1);
-        try {
-            mProxySender.getProxy().onQuickScrubProgress(scrubFraction);
-            if (DEBUG_OVERVIEW_PROXY) {
-                Log.d(TAG_OPS, "Quick Switch Progress:" + scrubFraction);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to send progress of quick switch.", e);
-        }
-    }
-
-    @Override
-    protected void onGestureEnd() {
-        endQuickGesture(true /* animate */);
-    }
-
-    protected void startQuickGesture(MotionEvent event) {
-        // Disable slippery for quick scrub to not cancel outside the nav bar
-        mNavigationBarView.updateSlippery();
-
-        try {
-            mProxySender.getProxy().onQuickScrubStart();
-            if (DEBUG_OVERVIEW_PROXY) {
-                Log.d(TAG_OPS, "Quick Scrub Start");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to send start of quick scrub.", e);
-        }
-        mProxySender.notifyQuickScrubStarted();
-    }
-
-    protected void endQuickGesture(boolean animate) {
-        try {
-            mProxySender.getProxy().onQuickScrubEnd();
-            if (DEBUG_OVERVIEW_PROXY) {
-                Log.d(TAG_OPS, "Quick Scrub End");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to send end of quick scrub.", e);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 1949bad..0d2fe13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -92,7 +92,7 @@
     /**
      * Scrim opacity when the phone is about to wake-up.
      */
-    public static final float AOD2_SCRIM_ALPHA = 0.6f;
+    public static final float WAKE_SENSOR_SCRIM_ALPHA = 0.6f;
     /**
      * A scrim varies its opacity based on a busyness factor, for example
      * how many notifications are currently visible.
@@ -458,6 +458,23 @@
         mState.AOD.setAodFrontScrimAlpha(alpha);
     }
 
+    /**
+     * If the lock screen sensor is active.
+     */
+    public void setWakeLockScreenSensorActive(boolean active) {
+        for (ScrimState state : ScrimState.values()) {
+            state.setWakeLockScreenSensorActive(active);
+        }
+
+        if (mState == ScrimState.PULSING) {
+            float newBehindAlpha = mState.getBehindAlpha();
+            if (mCurrentBehindAlpha != newBehindAlpha) {
+                mCurrentBehindAlpha = newBehindAlpha;
+                updateScrims();
+            }
+        }
+    }
+
     protected void scheduleUpdate() {
         if (mUpdatePending) return;
 
@@ -904,10 +921,6 @@
         }
     }
 
-    public void setPulseReason(int pulseReason) {
-        ScrimState.PULSING.setPulseReason(pulseReason);
-    }
-
     public interface Callback {
         default void onStart() {
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 2f161d5..d152ecd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -19,7 +19,6 @@
 import android.graphics.Color;
 import android.os.Trace;
 
-import com.android.systemui.doze.DozeLog;
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 
@@ -129,16 +128,15 @@
         @Override
         public void prepare(ScrimState previousState) {
             mCurrentInFrontAlpha = 0f;
-            if (mPulseReason == DozeLog.PULSE_REASON_NOTIFICATION
-                    || mPulseReason == DozeLog.PULSE_REASON_DOCKING
-                    || mPulseReason == DozeLog.PULSE_REASON_INTENT) {
-                mCurrentBehindAlpha = previousState.getBehindAlpha();
-            } else {
-                mCurrentBehindAlpha = ScrimController.AOD2_SCRIM_ALPHA;
-            }
             mCurrentBehindTint = Color.BLACK;
             mBlankScreen = mDisplayRequiresBlanking;
         }
+
+        @Override
+        public float getBehindAlpha() {
+            return mWakeLockScreenSensorActive ? ScrimController.WAKE_SENSOR_SCRIM_ALPHA
+                    : AOD.getBehindAlpha();
+        }
     },
 
     /**
@@ -199,7 +197,7 @@
     int mIndex;
     boolean mHasBackdrop;
     boolean mLaunchingAffordanceWithPreview;
-    int mPulseReason;
+    boolean mWakeLockScreenSensorActive;
 
     ScrimState(int index) {
         mIndex = index;
@@ -264,10 +262,6 @@
         mAodFrontScrimAlpha = aodFrontScrimAlpha;
     }
 
-    public void setPulseReason(int pulseReason) {
-        mPulseReason = pulseReason;
-    }
-
     public void setScrimBehindAlphaKeyguard(float scrimBehindAlphaKeyguard) {
         mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
     }
@@ -287,4 +281,8 @@
     public void setHasBackdrop(boolean hasBackdrop) {
         mHasBackdrop = hasBackdrop;
     }
+
+    public void setWakeLockScreenSensorActive(boolean active) {
+        mWakeLockScreenSensorActive = active;
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 5d52359..e5defae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -25,6 +25,7 @@
 import static android.app.StatusBarManager.windowStateToString;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
 
+import static com.android.systemui.Dependency.BG_HANDLER;
 import static com.android.systemui.Dependency.MAIN_HANDLER;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
@@ -434,6 +435,9 @@
         public void onUserSetupChanged() {
             final boolean userSetup = mDeviceProvisionedController.isUserSetup(
                     mDeviceProvisionedController.getCurrentUser());
+            // STOPSHIP(kozynski, b/129405675) Remove log
+            Log.d(TAG, "mUserSetupObserver - DeviceProvisionedListener called for user "
+                    + mDeviceProvisionedController.getCurrentUser());
             if (MULTIUSER_DEBUG) {
                 Log.d(TAG, String.format("User setup changed: userSetup=%s mUserSetup=%s",
                         userSetup, mUserSetup));
@@ -1073,7 +1077,7 @@
                 mLockscreenUserManager, shadeController, mKeyguardMonitor,
                 mNotificationInterruptionStateProvider, mMetricsLogger,
                 new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER),
-                mActivityIntentHelper);
+                Dependency.get(BG_HANDLER), mActivityIntentHelper, mBubbleController);
 
         mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
 
@@ -1297,13 +1301,16 @@
      * the user intends to use the lock screen user switcher, QS in not needed.
      */
     private void updateQsExpansionEnabled() {
-        mNotificationPanel.setQsExpansionEnabled(mDeviceProvisionedController.isDeviceProvisioned()
+        final boolean expandEnabled = mDeviceProvisionedController.isDeviceProvisioned()
                 && (mUserSetup || mUserSwitcherController == null
                         || !mUserSwitcherController.isSimpleUserSwitcher())
                 && ((mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0)
                 && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
                 && !mDozing
-                && !ONLY_CORE_APPS);
+                && !ONLY_CORE_APPS;
+        mNotificationPanel.setQsExpansionEnabled(expandEnabled);
+        // STOPSHIP(kozynski, b/129405675) Remove log
+        Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled);
     }
 
     public void addQsTile(ComponentName tile) {
@@ -2477,6 +2484,14 @@
                 options.setRotationAnimationHint(
                         WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
             }
+            if (intent.getAction() == Settings.Panel.ACTION_VOLUME) {
+                // Settings Panel is implemented as activity(not a dialog), so
+                // underlying app is paused and may enter picture-in-picture mode
+                // as a result.
+                // So we need to disable picture-in-picture mode here
+                // if it is volume panel.
+                options.setDisallowEnterPictureInPictureWhileLaunching(true);
+            }
             try {
                 result = ActivityTaskManager.getService().startActivityAsUser(
                         null, mContext.getBasePackageName(),
@@ -3575,6 +3590,9 @@
         updateHideIconsForBouncer(true /* animate */);
         mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
         updateScrimController();
+        if (!mBouncerShowing) {
+            updatePanelExpansionForKeyguard();
+        }
     }
 
     /**
@@ -3902,7 +3920,6 @@
 
         @Override
         public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
-            mScrimController.setPulseReason(reason);
             if (reason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS) {
                 mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
                         "com.android.systemui:LONG_PRESS");
@@ -3910,6 +3927,10 @@
                 return;
             }
 
+            if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
+                mScrimController.setWakeLockScreenSensorActive(true);
+            }
+
             boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_NOTIFICATION;
             // Set the state to pulsing, so ScrimController will know what to do once we ask it to
             // execute the transition. The pulse callback will then be invoked when the scrims
@@ -3928,6 +3949,7 @@
                     mPulsing = false;
                     callback.onPulseFinished();
                     updateNotificationPanelTouchState();
+                    mScrimController.setWakeLockScreenSensorActive(false);
                     setPulsing(false);
                 }
 
@@ -4004,7 +4026,10 @@
         }
 
         @Override
-        public void extendPulse() {
+        public void extendPulse(int reason) {
+            if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
+                mScrimController.setWakeLockScreenSensorActive(true);
+            }
             if (mDozeScrimController.isPulsing() && mAmbientPulseManager.hasNotifications()) {
                 mAmbientPulseManager.extendPulse();
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 4412851..92cd280 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -86,6 +86,7 @@
         public void onFullyShown() {
             updateStates();
             mStatusBar.wakeUpIfDozing(SystemClock.uptimeMillis(), mContainer, "BOUNCER_VISIBLE");
+            mNotificationPanelView.updateLockIcon();
         }
 
         @Override
@@ -96,6 +97,7 @@
         @Override
         public void onFullyHidden() {
             updateStates();
+            mNotificationPanelView.updateLockIcon();
         }
 
         @Override
@@ -417,6 +419,7 @@
         } else if (finishRunnable != null) {
             finishRunnable.run();
         }
+        mNotificationPanelView.blockExpansionForCurrentTouch();
     }
 
     /**
@@ -570,6 +573,10 @@
         return mBouncer.isShowing();
     }
 
+    public boolean isBouncerPartiallyVisible() {
+        return mBouncer.isPartiallyVisible();
+    }
+
     public boolean isFullscreenBouncer() {
         return mBouncer.isFullscreenBouncer();
     }
@@ -758,8 +765,10 @@
     }
 
     public boolean bouncerNeedsScrimming() {
-        return mOccluded || mBouncer.willDismissWithAction()  || mBouncer.needsFullscreenBouncer()
-                || mStatusBar.isFullScreenUserSwitcherState() || mBouncer.isShowingScrimmed();
+        return mOccluded || mBouncer.willDismissWithAction()
+                || mStatusBar.isFullScreenUserSwitcherState()
+                || (mBouncer.isShowing() && mBouncer.isScrimmed())
+                || mBouncer.isFullscreenBouncer();
     }
 
     public void dump(PrintWriter pw) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 215f5c4..e4af15c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -48,6 +48,7 @@
 import com.android.systemui.EventLogTags;
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.assist.AssistManager;
+import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -98,7 +99,9 @@
     private final CommandQueue mCommandQueue;
     private final IDreamManager mDreamManager;
     private final Handler mMainThreadHandler;
+    private final Handler mBackgroundHandler;
     private final ActivityIntentHelper mActivityIntentHelper;
+    private final BubbleController mBubbleController;
 
     private boolean mIsCollapsingToShowActivityOverLockscreen;
 
@@ -125,7 +128,9 @@
             MetricsLogger metricsLogger,
             LockPatternUtils lockPatternUtils,
             Handler mainThreadHandler,
-            ActivityIntentHelper activityIntentHelper) {
+            Handler backgroundHandler,
+            ActivityIntentHelper activityIntentHelper,
+            BubbleController bubbleController) {
         mContext = context;
         mNotificationPanel = panel;
         mPresenter = presenter;
@@ -147,6 +152,7 @@
         mAssistManager = assistManager;
         mGroupManager = groupManager;
         mLockPatternUtils = lockPatternUtils;
+        mBackgroundHandler = backgroundHandler;
         mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
             @Override
             public void onPendingEntryAdded(NotificationEntry entry) {
@@ -156,6 +162,7 @@
         mStatusBarRemoteInputCallback = remoteInputCallback;
         mMainThreadHandler = mainThreadHandler;
         mActivityIntentHelper = activityIntentHelper;
+        mBubbleController = bubbleController;
     }
 
     /**
@@ -178,14 +185,24 @@
         final PendingIntent intent = notification.contentIntent != null
                 ? notification.contentIntent
                 : notification.fullScreenIntent;
+        final boolean isBubble = row.getEntry().isBubble();
+
+        // This code path is now executed for notification without a contentIntent.
+        // The only valid case is Bubble notifications. Guard against other cases
+        // entering here.
+        if (intent == null && !isBubble) {
+            Log.e(TAG, "onNotificationClicked called for non-clickable notification!");
+            return;
+        }
+
         final String notificationKey = sbn.getKey();
 
-        boolean isActivityIntent = intent.isActivity();
+        boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
         final boolean afterKeyguardGone = isActivityIntent
                 && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
                 mLockscreenUserManager.getCurrentUserId());
         final boolean wasOccluded = mShadeController.isOccluded();
-        boolean showOverLockscreen = mKeyguardMonitor.isShowing()
+        boolean showOverLockscreen = mKeyguardMonitor.isShowing() && intent != null
                 && mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
                 mLockscreenUserManager.getCurrentUserId());
         ActivityStarter.OnDismissAction postKeyguardAction =
@@ -244,9 +261,8 @@
             mShadeController.addAfterKeyguardGoneRunnable(runnable);
             mShadeController.collapsePanel();
         } else {
-            new Thread(runnable).start();
+            mBackgroundHandler.postAtFrontOfQueue(runnable);
         }
-
         return !mNotificationPanel.isFullyCollapsed();
     }
 
@@ -287,6 +303,7 @@
         }
         Intent fillInIntent = null;
         NotificationEntry entry = row.getEntry();
+        final boolean isBubble = entry.isBubble();
         CharSequence remoteInputText = null;
         if (!TextUtils.isEmpty(entry.remoteInputText)) {
             remoteInputText = entry.remoteInputText;
@@ -295,8 +312,12 @@
             fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT,
                     remoteInputText.toString());
         }
-        startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent);
-        if (isActivityIntent) {
+        if (isBubble) {
+            expandBubbleStackOnMainThread(notificationKey);
+        } else {
+            startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent);
+        }
+        if (isActivityIntent || isBubble) {
             mAssistManager.hideAssist();
         }
         if (shouldCollapse()) {
@@ -316,18 +337,29 @@
         } catch (RemoteException ex) {
             // system process is dead if we're here.
         }
-        if (parentToCancelFinal != null) {
-            removeNotification(parentToCancelFinal);
-        }
-        if (shouldAutoCancel(sbn)
-                || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
-                notificationKey)) {
-            // Automatically remove all notifications that we may have kept around longer
-            removeNotification(sbn);
+        if (!isBubble) {
+            if (parentToCancelFinal != null) {
+                removeNotification(parentToCancelFinal);
+            }
+            if (shouldAutoCancel(sbn)
+                    || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
+                    notificationKey)) {
+                // Automatically remove all notifications that we may have kept around longer
+                removeNotification(sbn);
+            }
         }
         mIsCollapsingToShowActivityOverLockscreen = false;
     }
 
+    private void expandBubbleStackOnMainThread(String notificationKey) {
+        if (Looper.getMainLooper().isCurrentThread()) {
+            mBubbleController.expandStackAndSelectBubble(notificationKey);
+        } else {
+            mMainThreadHandler.post(
+                    () -> mBubbleController.expandStackAndSelectBubble(notificationKey));
+        }
+    }
+
     private void startNotificationIntent(PendingIntent intent, Intent fillInIntent,
             ExpandableNotificationRow row, boolean wasOccluded, boolean isActivityIntent) {
         RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(row,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
index 97be6ed..98cde2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
@@ -19,12 +19,12 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.statusbar.policy.CastController.Callback;
 
-import java.util.Set;
+import java.util.List;
 
 public interface CastController extends CallbackController<Callback>, Dumpable {
     void setDiscovering(boolean request);
     void setCurrentUserId(int currentUserId);
-    Set<CastDevice> getCastDevices();
+    List<CastDevice> getCastDevices();
     void startCasting(CastDevice device);
     void stopCasting(CastDevice device);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index c7d337a..505dd16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -29,7 +29,6 @@
 import android.os.Handler;
 import android.text.TextUtils;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -40,8 +39,8 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
-import java.util.Set;
 import java.util.UUID;
 
 import javax.inject.Inject;
@@ -150,8 +149,31 @@
     }
 
     @Override
-    public Set<CastDevice> getCastDevices() {
-        final ArraySet<CastDevice> devices = new ArraySet<CastDevice>();
+    public List<CastDevice> getCastDevices() {
+        final ArrayList<CastDevice> devices = new ArrayList<>();
+        synchronized(mRoutes) {
+            for (RouteInfo route : mRoutes.values()) {
+                final CastDevice device = new CastDevice();
+                device.id = route.getTag().toString();
+                final CharSequence name = route.getName(mContext);
+                device.name = name != null ? name.toString() : null;
+                final CharSequence description = route.getDescription();
+                device.description = description != null ? description.toString() : null;
+
+                int statusCode = route.getStatusCode();
+                if (statusCode == RouteInfo.STATUS_CONNECTING) {
+                    device.state = CastDevice.STATE_CONNECTING;
+                } else if (route.isSelected() || statusCode == RouteInfo.STATUS_CONNECTED) {
+                    device.state = CastDevice.STATE_CONNECTED;
+                } else {
+                    device.state = CastDevice.STATE_DISCONNECTED;
+                }
+
+                device.tag = route;
+                devices.add(device);
+            }
+        }
+
         synchronized (mProjectionLock) {
             if (mProjection != null) {
                 final CastDevice device = new CastDevice();
@@ -161,24 +183,9 @@
                 device.state = CastDevice.STATE_CONNECTED;
                 device.tag = mProjection;
                 devices.add(device);
-                return devices;
             }
         }
-        synchronized(mRoutes) {
-            for (RouteInfo route : mRoutes.values()) {
-                final CastDevice device = new CastDevice();
-                device.id = route.getTag().toString();
-                final CharSequence name = route.getName(mContext);
-                device.name = name != null ? name.toString() : null;
-                final CharSequence description = route.getDescription();
-                device.description = description != null ? description.toString() : null;
-                device.state = route.isConnecting() ? CastDevice.STATE_CONNECTING
-                        : route.isSelected() ? CastDevice.STATE_CONNECTED
-                        : CastDevice.STATE_DISCONNECTED;
-                device.tag = route;
-                devices.add(device);
-            }
-        }
+
         return devices;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
index f5e745f..db2523e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
@@ -21,9 +21,10 @@
 import android.content.Context;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.Handler;
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
-import android.os.Handler;
+import android.util.Log;
 
 import com.android.systemui.settings.CurrentUserTracker;
 
@@ -39,6 +40,7 @@
 public class DeviceProvisionedControllerImpl extends CurrentUserTracker implements
         DeviceProvisionedController {
 
+    private static final String TAG = DeviceProvisionedControllerImpl.class.getSimpleName();
     private final ArrayList<DeviceProvisionedListener> mListeners = new ArrayList<>();
     private final ContentResolver mContentResolver;
     private final Context mContext;
@@ -59,6 +61,8 @@
         mSettingsObserver = new ContentObserver(mainHandler) {
             @Override
             public void onChange(boolean selfChange, Uri uri, int userId) {
+                // STOPSHIP(kozynski, b/129405675) Remove log
+                Log.d(TAG, "Setting change: " + uri);
                 if (mUserSetupUri.equals(uri)) {
                     notifySetupChanged();
                 } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 5bd394f..c5996a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -470,10 +470,16 @@
             mNetworkController.recalculateEmergency();
         }
         // Fill in the network name if we think we have it.
-        if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null
+        if (mCurrentState.networkName.equals(mNetworkNameDefault) && mServiceState != null
                 && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {
             mCurrentState.networkName = mServiceState.getOperatorAlphaShort();
         }
+        // If this is the data subscription, update the currentState data name
+        if (mCurrentState.networkNameData.equals(mNetworkNameDefault) && mServiceState != null
+                && mCurrentState.dataSim
+                && !TextUtils.isEmpty(mServiceState.getDataOperatorAlphaShort())) {
+            mCurrentState.networkNameData = mServiceState.getDataOperatorAlphaShort();
+        }
 
         notifyListenersIfNecessary();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 51fef7d..71db618 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -37,6 +37,7 @@
     DataUsageController getMobileDataController();
     DataSaverController getDataSaverController();
     String getMobileDataNetworkName();
+    int getNumberSubscriptions();
 
     boolean hasVoiceCallingFeature();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index ef39912..d01430a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -376,6 +376,11 @@
         return controller != null ? controller.getState().networkNameData : "";
     }
 
+    @Override
+    public int getNumberSubscriptions() {
+        return mMobileSignalControllers.size();
+    }
+
     public boolean isEmergencyOnly() {
         if (mMobileSignalControllers.size() == 0) {
             // When there are no active subscriptions, determine emengency state from last
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 1e09063..c1950a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -146,7 +146,11 @@
         Intent fillInIntent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         RemoteInput.addResultsToIntent(mRemoteInputs, fillInIntent,
                 results);
-        RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_FREE_FORM_INPUT);
+        if (mEntry.editedSuggestionInfo == null) {
+            RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_FREE_FORM_INPUT);
+        } else {
+            RemoteInput.setResultsSource(fillInIntent, RemoteInput.SOURCE_CHOICE);
+        }
 
         mEditText.setEnabled(false);
         mSendButton.setVisibility(INVISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 9343bf1..f726321 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -403,7 +403,7 @@
         final int N = mUsers.size();
         for (int i = 0; i < N; ++i) {
             UserRecord record = mUsers.get(i);
-            if (record.info != null && record.info.supportsSwitchTo()) {
+            if (record.info != null && record.info.supportsSwitchToByUser()) {
                 count++;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
index 8ec66e4..45fc756 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
@@ -17,7 +17,10 @@
 package com.android.systemui.volume;
 
 import android.content.Context;
+import android.os.Handler;
 import android.util.AttributeSet;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
 
 import com.android.keyguard.AlphaOptimizedImageButton;
 import com.android.systemui.R;
@@ -27,14 +30,34 @@
 
     private static final int[] OPTED_OUT_STATE = new int[] { R.attr.optedOut };
 
+    private ConfirmedTapListener mConfirmedTapListener;
     private boolean mComponentEnabled = false;
     private boolean mOptedOut = false;
 
+    private GestureDetector mGestureDetector;
+    private GestureDetector.SimpleOnGestureListener mGestureListener =
+            new GestureDetector.SimpleOnGestureListener() {
+        @Override
+        public boolean onSingleTapConfirmed(MotionEvent e) {
+            if (mConfirmedTapListener != null) {
+                mConfirmedTapListener.onConfirmedTap();
+                return true;
+            }
+            return false;
+        }
+    };
+
     public CaptionsToggleImageButton(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
     @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (mGestureDetector != null) mGestureDetector.onTouchEvent(event);
+        return super.onTouchEvent(event);
+    }
+
+    @Override
     public int[] onCreateDrawableState(int extraSpace) {
         int[] state = super.onCreateDrawableState(extraSpace + 1);
         if (mOptedOut) {
@@ -64,4 +87,17 @@
     boolean getOptedOut() {
         return this.mOptedOut;
     }
+
+    void setOnConfirmedTapListener(ConfirmedTapListener listener, Handler handler) {
+        mConfirmedTapListener = listener;
+
+        if (mGestureDetector == null) {
+            this.mGestureDetector = new GestureDetector(getContext(), mGestureListener, handler);
+        }
+    }
+
+    /** Listener for confirmed taps rather than normal on click listener. */
+    interface ConfirmedTapListener {
+        void onConfirmedTap();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index bd7824d..2094b36 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -95,6 +95,7 @@
 import com.android.systemui.plugins.VolumeDialogController.State;
 import com.android.systemui.plugins.VolumeDialogController.StreamState;
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 
 import java.io.PrintWriter;
@@ -108,7 +109,8 @@
  *
  * Methods ending in "H" must be called on the (ui) handler.
  */
-public class VolumeDialogImpl implements VolumeDialog {
+public class VolumeDialogImpl implements VolumeDialog,
+        ConfigurationController.ConfigurationListener {
     private static final String TAG = Util.logTag(VolumeDialogImpl.class);
 
     private static final long USER_ATTEMPT_GRACE_PERIOD = 1000;
@@ -175,6 +177,11 @@
                 Prefs.getBoolean(context, Prefs.Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP, false);
     }
 
+    @Override
+    public void onUiModeChanged() {
+        mContext.getTheme().applyStyle(mContext.getThemeResId(), true);
+    }
+
     public void init(int windowType, Callback callback) {
         initDialog();
 
@@ -182,12 +189,15 @@
 
         mController.addCallback(mControllerCallbackH, mHandler);
         mController.getState();
+
+        Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
     @Override
     public void destroy() {
         mController.removeCallback(mControllerCallbackH);
         mHandler.removeCallbacksAndMessages(null);
+        Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
     private void initDialog() {
@@ -278,7 +288,7 @@
                 addRow(AudioManager.STREAM_RING,
                         R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true, false);
                 addRow(STREAM_ALARM,
-                        R.drawable.ic_volume_alarm, R.drawable.ic_volume_alarm_mute, true, false);
+                        R.drawable.ic_alarm, R.drawable.ic_volume_alarm_mute, true, false);
                 addRow(AudioManager.STREAM_VOICE_CALL,
                         com.android.internal.R.drawable.ic_phone,
                         com.android.internal.R.drawable.ic_phone, false, false);
@@ -409,8 +419,9 @@
             row.header.setFilters(new InputFilter[] {new InputFilter.LengthFilter(13)});
         }
         row.dndIcon = row.view.findViewById(R.id.dnd_icon);
-        row.slider =  row.view.findViewById(R.id.volume_row_slider);
+        row.slider = row.view.findViewById(R.id.volume_row_slider);
         row.slider.setOnSeekBarChangeListener(new VolumeSeekBarChangeListener(row));
+
         row.anim = null;
 
         row.icon = row.view.findViewById(R.id.volume_row_icon);
@@ -505,11 +516,11 @@
 
     private void initODICaptionsH() {
         if (mODICaptionsIcon != null) {
-            mODICaptionsIcon.setOnClickListener(v -> {
+            mODICaptionsIcon.setOnConfirmedTapListener(() -> {
                 onCaptionIconClicked();
                 Events.writeEvent(mContext, Events.EVENT_ODI_CAPTIONS_CLICK);
                 dismissH(DISMISS_REASON_ODI_CAPTIONS_CLICKED);
-            });
+            }, mHandler);
         }
 
         mController.getCaptionsComponentState(false);
@@ -1383,6 +1394,7 @@
             if (mRow.ss.level != userLevel || mRow.ss.muted && userLevel > 0) {
                 mRow.userAttempt = SystemClock.uptimeMillis();
                 if (mRow.requestedLevel != userLevel) {
+                    mController.setActiveStream(mRow.stream);
                     mController.setStreamVolume(mRow.stream, userLevel);
                     mRow.requestedLevel = userLevel;
                     Events.writeEvent(mContext, Events.EVENT_TOUCH_LEVEL_CHANGED, mRow.stream,
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 83ec33c..5412cde 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -71,8 +71,8 @@
 # This appends a * to all classes and replace the space separators with commas.
 jacoco_exclude := $(subst $(space),$(comma),$(patsubst %,%*,$(local_classes)))
 
-LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.systemui.*
-LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := com.android.systemui.tests.*,$(jacoco_exclude)
+LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.systemui.*,com.android.keyguard.*
+LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := $(jacoco_exclude)
 
 ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
     include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 632b0c0..f01c0b4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -211,6 +211,19 @@
     }
 
     @Test
+    public void onPluginDisconnected_onDestroyView() {
+        // GIVEN a plugin is connected
+        ClockPlugin clockPlugin = mock(ClockPlugin.class);
+        when(clockPlugin.getView()).thenReturn(new TextClock(getContext()));
+        ClockManager.ClockChangedListener listener = mKeyguardClockSwitch.getClockChangedListener();
+        listener.onClockChanged(clockPlugin);
+        // WHEN the plugin is disconnected
+        listener.onClockChanged(null);
+        // THEN onDestroyView is called on the plugin
+        verify(clockPlugin).onDestroyView();
+    }
+
+    @Test
     public void setTextColor_defaultClockSetTextColor() {
         mKeyguardClockSwitch.setTextColor(Color.YELLOW);
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
index 267468f..f03c234 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
@@ -27,10 +27,13 @@
 import android.widget.TextView;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -38,12 +41,15 @@
 public final class BubbleClockControllerTest extends SysuiTestCase {
 
     private BubbleClockController mClockController;
+    @Mock SysuiColorExtractor mMockColorExtractor;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
         Resources res = getContext().getResources();
         LayoutInflater layoutInflater = LayoutInflater.from(getContext());
-        mClockController = new BubbleClockController(res, layoutInflater);
+        mClockController = new BubbleClockController(res, layoutInflater, mMockColorExtractor);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java
index 36265d4..f2ad958 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java
@@ -18,6 +18,8 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.ContentResolver;
@@ -31,6 +33,7 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerFake;
+import com.android.systemui.plugins.ClockPlugin;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.util.InjectionInflationController;
 
@@ -38,6 +41,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -57,7 +61,8 @@
     @Mock SysuiColorExtractor mMockColorExtractor;
     @Mock ContentResolver mMockContentResolver;
     @Mock SettingsWrapper mMockSettingsWrapper;
-    @Mock ClockManager.ClockChangedListener mMockListener;
+    @Mock ClockManager.ClockChangedListener mMockListener1;
+    @Mock ClockManager.ClockChangedListener mMockListener2;
 
     @Before
     public void setUp() {
@@ -67,17 +72,23 @@
         when(mMockInjectionInflationController.injectable(any())).thenReturn(inflater);
 
         mFakeDockManager = new DockManagerFake();
+        getContext().putComponent(DockManager.class, mFakeDockManager);
+
         mClockManager = new ClockManager(getContext(), mMockInjectionInflationController,
-                mMockPluginManager, mFakeDockManager, mMockColorExtractor, mMockContentResolver,
+                mMockPluginManager, mMockColorExtractor, mMockContentResolver,
                 mMockSettingsWrapper);
 
-        mClockManager.addOnClockChangedListener(mMockListener);
+        mClockManager.addOnClockChangedListener(mMockListener1);
+        mClockManager.addOnClockChangedListener(mMockListener2);
+        reset(mMockListener1, mMockListener2);
+
         mContentObserver = mClockManager.getContentObserver();
     }
 
     @After
     public void tearDown() {
-        mClockManager.removeOnClockChangedListener(mMockListener);
+        mClockManager.removeOnClockChangedListener(mMockListener1);
+        mClockManager.removeOnClockChangedListener(mMockListener2);
     }
 
     @Test
@@ -114,6 +125,34 @@
     }
 
     @Test
+    public void onClockChanged_customClock() {
+        // GIVEN that settings is set to the bubble clock face
+        when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK);
+        // WHEN settings change event is fired
+        mContentObserver.onChange(false);
+        // THEN the plugin is the bubble clock face.
+        ArgumentCaptor<ClockPlugin> captor = ArgumentCaptor.forClass(ClockPlugin.class);
+        verify(mMockListener1).onClockChanged(captor.capture());
+        assertThat(captor.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+    }
+
+    @Test
+    public void onClockChanged_uniqueInstances() {
+        // GIVEN that settings is set to the bubble clock face
+        when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK);
+        // WHEN settings change event is fired
+        mContentObserver.onChange(false);
+        // THEN the listeners receive separate instances of the Bubble clock plugin.
+        ArgumentCaptor<ClockPlugin> captor1 = ArgumentCaptor.forClass(ClockPlugin.class);
+        ArgumentCaptor<ClockPlugin> captor2 = ArgumentCaptor.forClass(ClockPlugin.class);
+        verify(mMockListener1).onClockChanged(captor1.capture());
+        verify(mMockListener2).onClockChanged(captor2.capture());
+        assertThat(captor1.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+        assertThat(captor2.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+        assertThat(captor1.getValue()).isNotSameAs(captor2.getValue());
+    }
+
+    @Test
     public void getCurrentClock_badSettingsValue() {
         // GIVEN that settings contains a value that doesn't correspond to a
         // custom clock face.
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/StretchAnalogClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/StretchAnalogClockControllerTest.java
index 0659b4f..26fa62b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/StretchAnalogClockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/StretchAnalogClockControllerTest.java
@@ -27,10 +27,13 @@
 import android.widget.TextView;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -38,12 +41,16 @@
 public final class StretchAnalogClockControllerTest extends SysuiTestCase {
 
     private StretchAnalogClockController mClockController;
+    @Mock SysuiColorExtractor mMockColorExtractor;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
         Resources res = getContext().getResources();
         LayoutInflater layoutInflater = LayoutInflater.from(getContext());
-        mClockController = new StretchAnalogClockController(res, layoutInflater);
+        mClockController = new StretchAnalogClockController(res, layoutInflater,
+                mMockColorExtractor);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt
new file mode 100644
index 0000000..d9ef7fa
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard.clock
+
+import android.content.Context
+import com.google.common.truth.Truth.assertThat
+
+import android.graphics.Canvas
+import android.graphics.Color
+import android.testing.AndroidTestingRunner
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ViewPreviewerTest : SysuiTestCase() {
+
+    private lateinit var previewer: ViewPreviewer
+    private lateinit var view: View
+
+    @Before
+    fun setUp() {
+        previewer = ViewPreviewer()
+        view = TestView(context)
+    }
+
+    @Test
+    fun testCreatePreview() {
+        val width = 100
+        val height = 100
+        // WHEN a preview image is created
+        val bitmap = previewer.createPreview(view, width, height)
+        // THEN the bitmap has the expected width and height
+        assertThat(bitmap.height).isEqualTo(height)
+        assertThat(bitmap.width).isEqualTo(width)
+        assertThat(bitmap.getPixel(0, 0)).isEqualTo(Color.RED)
+    }
+
+    class TestView(context: Context) : View(context) {
+        override fun onDraw(canvas: Canvas?) {
+            super.onDraw(canvas)
+            canvas?.drawColor(Color.RED)
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index c9b550c..5e16721 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -16,9 +16,14 @@
 
 package com.android.systemui.bubbles;
 
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
@@ -26,8 +31,13 @@
 import static org.mockito.Mockito.when;
 
 import android.app.IActivityManager;
+import android.app.Notification;
 import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.drawable.Icon;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.WindowManager;
@@ -35,7 +45,7 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.statusbar.NotificationVisibility;
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
@@ -55,11 +65,17 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class BubbleControllerTest extends SysuiTestCase {
 
+    // Some APIs rely on the app being foreground, check is via pkg name
+    private static final String FOREGROUND_TEST_PKG_NAME = "com.android.systemui.tests";
+
     @Mock
     private NotificationEntryManager mNotificationEntryManager;
     @Mock
@@ -82,7 +98,9 @@
     private NotificationTestHelper mNotificationTestHelper;
     private ExpandableNotificationRow mRow;
     private ExpandableNotificationRow mRow2;
-    private ExpandableNotificationRow mNoChannelRow;
+    private ExpandableNotificationRow mAutoExpandRow;
+    private ExpandableNotificationRow mSuppressNotifRow;
+    private ExpandableNotificationRow mNonBubbleNotifRow;
 
     @Mock
     private NotificationData mNotificationData;
@@ -91,9 +109,6 @@
     @Mock
     private BubbleController.BubbleExpandListener mBubbleExpandListener;
     @Mock
-    NotificationVisibility mNotificationVisibility;
-
-    @Mock
     private PendingIntent mDeleteIntent;
 
     private BubbleData mBubbleData;
@@ -104,7 +119,6 @@
         mStatusBarView = new FrameLayout(mContext);
         mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
 
-
         // Bubbles get added to status bar window view
         mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
                 mActivityManager, mDozeParameters);
@@ -114,12 +128,23 @@
         mNotificationTestHelper = new NotificationTestHelper(mContext);
         mRow = mNotificationTestHelper.createBubble(mDeleteIntent);
         mRow2 = mNotificationTestHelper.createBubble(mDeleteIntent);
-        mNoChannelRow = mNotificationTestHelper.createBubble(mDeleteIntent);
+        mNonBubbleNotifRow = mNotificationTestHelper.createRow();
+
+        // Some bubbles want to auto expand
+        Notification.BubbleMetadata autoExpandMetadata =
+                getBuilder().setAutoExpandBubble(true).build();
+        mAutoExpandRow = mNotificationTestHelper.createBubble(autoExpandMetadata,
+                FOREGROUND_TEST_PKG_NAME);
+
+        // Some bubbles want to suppress notifs
+        Notification.BubbleMetadata suppressNotifMetadata =
+                getBuilder().setSuppressInitialNotification(true).build();
+        mSuppressNotifRow = mNotificationTestHelper.createBubble(suppressNotifMetadata,
+                FOREGROUND_TEST_PKG_NAME);
 
         // Return non-null notification data from the NEM
         when(mNotificationEntryManager.getNotificationData()).thenReturn(mNotificationData);
         when(mNotificationData.getChannel(mRow.getEntry().key)).thenReturn(mRow.getEntry().channel);
-        when(mNotificationData.getChannel(mNoChannelRow.getEntry().key)).thenReturn(null);
 
         mBubbleData = new BubbleData();
         mBubbleController = new TestableBubbleController(mContext, mStatusBarWindowController,
@@ -303,9 +328,123 @@
     }
 
     @Test
-    public void testMarkNewNotificationAsBubble() {
+    public void testAutoExpand_FailsNotForeground() {
+        assertFalse(mBubbleController.isStackExpanded());
+
+        // Add the auto expand bubble
+        mEntryListener.onPendingEntryAdded(mAutoExpandRow.getEntry());
+        mBubbleController.updateBubble(mAutoExpandRow.getEntry(), true /* updatePosition */);
+
+        // Expansion shouldn't change
+        verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */,
+                mAutoExpandRow.getEntry().key);
+        assertFalse(mBubbleController.isStackExpanded());
+
+        // # of bubbles should change
+        verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
+    }
+
+    @Test
+    public void testAutoExpand_SucceedsForeground() {
+        final CountDownLatch latch = new CountDownLatch(1);
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                latch.countDown();
+            }
+        };
+        IntentFilter filter = new IntentFilter(BubblesTestActivity.BUBBLE_ACTIVITY_OPENED);
+        mContext.registerReceiver(receiver, filter);
+
+        assertFalse(mBubbleController.isStackExpanded());
+
+        // Make ourselves foreground
+        Intent i = new Intent(mContext, BubblesTestActivity.class);
+        i.setFlags(FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(i);
+
+        try {
+            latch.await(100, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+        // Add the auto expand bubble
+        mEntryListener.onPendingEntryAdded(mAutoExpandRow.getEntry());
+        mBubbleController.updateBubble(mAutoExpandRow.getEntry(), true /* updatePosition */);
+
+        // Expansion should change
+        verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */,
+                mAutoExpandRow.getEntry().key);
+        assertTrue(mBubbleController.isStackExpanded());
+
+        // # of bubbles should change
+        verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
+        mContext.unregisterReceiver(receiver);
+    }
+
+    @Test
+    public void testSuppressNotif_FailsNotForeground() {
+        // Add the suppress notif bubble
+        mEntryListener.onPendingEntryAdded(mSuppressNotifRow.getEntry());
+        mBubbleController.updateBubble(mSuppressNotifRow.getEntry(), true /* updatePosition */);
+
+        // Should show in shade because we weren't forground
+        assertTrue(mSuppressNotifRow.getEntry().showInShadeWhenBubble());
+
+        // # of bubbles should change
+        verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
+    }
+
+    @Test
+    public void testSuppressNotif_SucceedsForeground() {
+        final CountDownLatch latch = new CountDownLatch(1);
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                latch.countDown();
+            }
+        };
+        IntentFilter filter = new IntentFilter(BubblesTestActivity.BUBBLE_ACTIVITY_OPENED);
+        mContext.registerReceiver(receiver, filter);
+
+        assertFalse(mBubbleController.isStackExpanded());
+
+        // Make ourselves foreground
+        Intent i = new Intent(mContext, BubblesTestActivity.class);
+        i.setFlags(FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(i);
+
+        try {
+            latch.await(100, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+        // Add the suppress notif bubble
+        mEntryListener.onPendingEntryAdded(mSuppressNotifRow.getEntry());
+        mBubbleController.updateBubble(mSuppressNotifRow.getEntry(), true /* updatePosition */);
+
+        // Should NOT show in shade because we were foreground
+        assertFalse(mSuppressNotifRow.getEntry().showInShadeWhenBubble());
+
+        // # of bubbles should change
+        verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
+        mContext.unregisterReceiver(receiver);
+    }
+
+    @Test
+    public void testExpandStackAndSelectBubble_removedFirst() {
+        final String key = mRow.getEntry().key;
+
         mEntryListener.onPendingEntryAdded(mRow.getEntry());
-        assertTrue(mRow.getEntry().isBubble());
+        mBubbleController.updateBubble(mRow.getEntry(), true /* updatePosition */);
+
+        // Simulate notification cancellation.
+        mEntryListener.onEntryRemoved(mRow.getEntry(), null /* notificationVisibility (unused) */,
+                false /* removedbyUser */);
+
+        mBubbleController.expandStackAndSelectBubble(key);
     }
 
     @Test
@@ -315,6 +454,15 @@
     }
 
     @Test
+    public void testAddNotif_notBubble() {
+        mEntryListener.onPendingEntryAdded(mNonBubbleNotifRow.getEntry());
+        mEntryListener.onPreEntryUpdated(mNonBubbleNotifRow.getEntry());
+
+        verify(mBubbleStateChangeListener, never()).onHasBubblesChanged(anyBoolean());
+        assertThat(mBubbleController.hasBubbles()).isFalse();
+    }
+
+    @Test
     public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException {
         mBubbleController.updateBubble(mRow.getEntry(), true /* updatePosition */);
         mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_AGED);
@@ -349,4 +497,15 @@
             return entry.notification.getNotification().getBubbleMetadata() != null;
         }
     }
+
+    /**
+     * @return basic {@link android.app.Notification.BubbleMetadata.Builder}
+     */
+    private Notification.BubbleMetadata.Builder getBuilder() {
+        Intent target = new Intent(mContext, BubblesTestActivity.class);
+        PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, target, 0);
+        return new Notification.BubbleMetadata.Builder()
+                .setIntent(bubbleIntent)
+                .setIcon(Icon.createWithResource(mContext, R.drawable.android));
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleStackViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleStackViewTest.java
new file mode 100644
index 0000000..801308f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleStackViewTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bubbles;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class BubbleStackViewTest extends SysuiTestCase {
+    private BubbleStackView mStackView;
+    @Mock private Bubble mBubble;
+    @Mock private NotificationEntry mNotifEntry;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mStackView = new BubbleStackView(mContext, new BubbleData(), null);
+        mBubble.entry = mNotifEntry;
+    }
+
+    @Test
+    public void testAnimateInFlyoutForBubble() throws InterruptedException {
+        when(mNotifEntry.getUpdateMessage(any())).thenReturn("Test Flyout Message.");
+        mStackView.animateInFlyoutForBubble(mBubble);
+
+        // Wait for the fade in.
+        Thread.sleep(200);
+
+        // Flyout should be visible and showing our text.
+        assertEquals(1f, mStackView.findViewById(R.id.bubble_flyout).getAlpha(), .01f);
+        assertEquals("Test Flyout Message.",
+                ((TextView) mStackView.findViewById(R.id.bubble_flyout_text)).getText());
+
+        // Wait until it should have gone away.
+        Thread.sleep(BubbleStackView.FLYOUT_HIDE_AFTER + 200);
+
+        // Flyout should be gone.
+        assertEquals(View.GONE, mStackView.findViewById(R.id.bubble_flyout).getVisibility());
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
index ea472da..43d2ad1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java
@@ -17,6 +17,7 @@
 package com.android.systemui.bubbles;
 
 import android.app.Activity;
+import android.content.Intent;
 import android.os.Bundle;
 
 import com.android.systemui.R;
@@ -26,9 +27,15 @@
  */
 public class BubblesTestActivity extends Activity {
 
+    public static final String BUBBLE_ACTIVITY_OPENED =
+            "com.android.systemui.bubbles.BUBBLE_ACTIVITY_OPENED";
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
+
+        Intent i = new Intent(BUBBLE_ACTIVITY_OPENED);
+        sendBroadcast(i);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
index 096f205..910cee3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
@@ -57,6 +57,7 @@
      * direction is correct.
      */
     @Test
+    @Ignore("Flaking")
     public void testMoveFirstBubbleWithStackFollowing() throws InterruptedException {
         mStackController.moveFirstBubbleWithStackFollowing(200, 100);
 
@@ -199,6 +200,7 @@
     }
 
     @Test
+    @Ignore("Flaky")
     public void testRestoredAtRestingPosition() throws InterruptedException {
         mStackController.flingStackThenSpringToEdge(0, 5000, 5000);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
index dc42872..abfa755 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -86,7 +86,7 @@
     }
 
     @Override
-    public void extendPulse() {
+    public void extendPulse(int reason) {
         pulseExtended = true;
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index cde3398..392c677 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -237,6 +237,18 @@
     }
 
     @Test
+    public void screenOff_softBlanks() throws Exception {
+        mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+        mScreen.transitionTo(INITIALIZED, DOZE_AOD);
+        mScreen.transitionTo(DOZE_AOD, DOZE);
+        assertEquals(1f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
+
+        mScreen.transitionTo(DOZE, DOZE_AOD);
+        mSensor.sendSensorEvent(2);
+        assertEquals(0f, mHostFake.aodDimmingScrimOpacity, 0.001f /* delta */);
+    }
+
+    @Test
     public void pausingAod_unblanksAfterSensor() throws Exception {
         mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
         mScreen.transitionTo(INITIALIZED, DOZE_AOD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
index beba905..87ae85f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
@@ -45,12 +45,11 @@
     private DozeWallpaperState mDozeWallpaperState;
     @Mock IWallpaperManager mIWallpaperManager;
     @Mock DozeParameters mDozeParameters;
-    @Mock DozeMachine mMachine;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mDozeWallpaperState = new DozeWallpaperState(mMachine, mIWallpaperManager, mDozeParameters);
+        mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mDozeParameters);
     }
 
     @Test
@@ -110,28 +109,18 @@
     }
 
     @Test
-    public void testTransitionTo_notificationPulseIsAmbientMode() throws RemoteException {
-        when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_NOTIFICATION);
-        mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE,
-                DozeMachine.State.DOZE_PULSING);
-        verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(0L));
-    }
-
-    @Test
     public void testTransitionTo_wakeFromPulseIsNotAmbientMode() throws RemoteException {
-        when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN);
         mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD,
                 DozeMachine.State.DOZE_REQUEST_PULSE);
         reset(mIWallpaperManager);
 
         mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE,
-                DozeMachine.State.DOZE_PULSING);
+                DozeMachine.State.DOZE_PULSING_BRIGHT);
         verify(mIWallpaperManager).setInAmbientMode(eq(false), anyLong());
     }
 
     @Test
     public void testTransitionTo_animatesWhenWakingUpFromPulse() throws RemoteException {
-        when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_NOTIFICATION);
         mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE,
                 DozeMachine.State.DOZE_PULSING);
         reset(mIWallpaperManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index f51e473..5928a07 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -265,6 +265,12 @@
         state.mIsPowerSaver = true;
         shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
         assertThat(shouldShow).isFalse();
+
+        state.mIsPowerSaver = false;
+        // if disabled we should not show the low warning.
+        state.mIsLowLevelWarningEnabled = false;
+        shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+        assertThat(shouldShow).isFalse();
     }
 
     @Test
@@ -365,7 +371,7 @@
         assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_HYBRID_THRESHOLD);
         BatteryStateSnapshot snapshot = new BatteryStateSnapshot(
                 BATTERY_LEVEL_10, false, false, 0, BatteryManager.BATTERY_HEALTH_GOOD,
-                0, 0, -1, 0, 0, false);
+                0, 0, -1, 0, 0, false, true);
         mPowerUI.mLastBatteryStateSnapshot = snapshot;
 
         // query again since the estimate was -1
@@ -375,7 +381,7 @@
         assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_SEVERE_HYBRID_THRESHOLD);
         snapshot = new BatteryStateSnapshot(
                 BATTERY_LEVEL_10, false, false, 0, BatteryManager.BATTERY_HEALTH_GOOD, 0,
-                0, BELOW_SEVERE_HYBRID_THRESHOLD, 0, 0, false);
+                0, BELOW_SEVERE_HYBRID_THRESHOLD, 0, 0, false, true);
         mPowerUI.mLastBatteryStateSnapshot = snapshot;
 
         // Battery level hasn't changed, so we don't query again
@@ -536,13 +542,14 @@
         public long mTimeRemainingMillis = Duration.ofHours(24).toMillis();
         public boolean mIsBasedOnUsage = true;
         public boolean mIsHybrid = true;
+        public boolean mIsLowLevelWarningEnabled = true;
 
         public BatteryStateSnapshot get() {
             if (mIsHybrid) {
                 return new BatteryStateSnapshot(mBatteryLevel, mIsPowerSaver, mPlugged, mBucket,
                         mBatteryStatus, mSevereLevelThreshold, mLowLevelThreshold,
                         mTimeRemainingMillis, mSevereThresholdMillis, mLowThresholdMillis,
-                        mIsBasedOnUsage);
+                        mIsBasedOnUsage, mIsLowLevelWarningEnabled);
             } else {
                 return new BatteryStateSnapshot(mBatteryLevel, mIsPowerSaver, mPlugged, mBucket,
                         mBatteryStatus, mSevereLevelThreshold, mLowLevelThreshold);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index fd31013..47933ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -194,7 +194,7 @@
                                         VPN_PACKAGE),
                      mFooterText.getText());
         assertEquals(View.VISIBLE, mFooterIcon.getVisibility());
-        assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
+        assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource());
 
         // Same situation, but with organization name set
         when(mSecurityController.getDeviceOwnerOrganizationName())
@@ -220,7 +220,7 @@
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_vpns),
                      mFooterText.getText());
         assertEquals(View.VISIBLE, mFooterIcon.getVisibility());
-        assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
+        assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource());
 
         // Same situation, but with organization name set
         when(mSecurityController.getDeviceOwnerOrganizationName())
@@ -243,7 +243,7 @@
 
         TestableLooper.get(this).processAllMessages();
         assertEquals(View.VISIBLE, mFooterIcon.getVisibility());
-        assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
+        assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_management_monitoring),
                 mFooterText.getText());
     }
@@ -294,7 +294,7 @@
         mFooter.refreshState();
 
         TestableLooper.get(this).processAllMessages();
-        assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
+        assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_vpns),
                      mFooterText.getText());
     }
@@ -306,7 +306,7 @@
         mFooter.refreshState();
 
         TestableLooper.get(this).processAllMessages();
-        assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
+        assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(
                              R.string.quick_settings_disclosure_managed_profile_named_vpn,
                              VPN_PACKAGE_2),
@@ -320,7 +320,7 @@
         mFooter.refreshState();
 
         TestableLooper.get(this).processAllMessages();
-        assertEquals(R.drawable.ic_qs_vpn, mFooterIcon.getLastImageResource());
+        assertEquals(R.drawable.stat_sys_vpn_ic, mFooterIcon.getLastImageResource());
         assertEquals(mContext.getString(R.string.quick_settings_disclosure_named_vpn,
                                         VPN_PACKAGE),
                      mFooterText.getText());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
index ea8d4b2..818db87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
@@ -14,13 +14,19 @@
 
 package com.android.systemui.qs.tiles;
 
+import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.assertEquals;
 
+import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.media.MediaRouter;
+import android.media.MediaRouter.RouteInfo;
+import android.media.projection.MediaProjectionInfo;
 import android.service.quicksettings.Tile;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -33,6 +39,7 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.policy.CastController;
+import com.android.systemui.statusbar.policy.CastController.CastDevice;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.NetworkController;
 
@@ -43,8 +50,9 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
+
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -93,7 +101,6 @@
         verify(mNetworkController).observe(any(LifecycleOwner.class),
                 signalCallbackArgumentCaptor.capture());
         mCallback = signalCallbackArgumentCaptor.getValue();
-
     }
 
     @Test
@@ -120,33 +127,125 @@
         assertEquals(Tile.STATE_UNAVAILABLE, mCastTile.getState().state);
     }
 
-    @Test
-    public void testStateActive_wifiEnabledAndCasting() {
-        CastController.CastDevice device = mock(CastController.CastDevice.class);
-        device.state = CastController.CastDevice.STATE_CONNECTED;
-        Set<CastController.CastDevice> devices = new HashSet<>();
-        devices.add(device);
-        when(mController.getCastDevices()).thenReturn(devices);
-
+    private void enableWifiAndProcessMessages() {
         NetworkController.IconState qsIcon =
                 new NetworkController.IconState(true, 0, "");
         mCallback.setWifiIndicators(true, mock(NetworkController.IconState.class),
                 qsIcon, false,false, "",
                 false, "");
         mTestableLooper.processAllMessages();
+    }
 
+    @Test
+    public void testStateActive_wifiEnabledAndCasting() {
+        CastController.CastDevice device = new CastController.CastDevice();
+        device.state = CastController.CastDevice.STATE_CONNECTED;
+        List<CastDevice> devices = new ArrayList<>();
+        devices.add(device);
+        when(mController.getCastDevices()).thenReturn(devices);
+
+        enableWifiAndProcessMessages();
         assertEquals(Tile.STATE_ACTIVE, mCastTile.getState().state);
     }
 
     @Test
     public void testStateInactive_wifiEnabledNotCasting() {
-        NetworkController.IconState qsIcon =
-                new NetworkController.IconState(true, 0, "");
-        mCallback.setWifiIndicators(true, mock(NetworkController.IconState.class),
-                qsIcon, false,false, "",
-                false, "");
+        enableWifiAndProcessMessages();
+        assertEquals(Tile.STATE_INACTIVE, mCastTile.getState().state);
+    }
+
+    @Test
+    public void testHandleClick_castDevicePresent() {
+        CastController.CastDevice device = new CastController.CastDevice();
+        device.state = CastDevice.STATE_CONNECTED;
+        device.tag = mock(MediaRouter.RouteInfo.class);
+        List<CastDevice> devices = new ArrayList<>();
+        devices.add(device);
+        when(mController.getCastDevices()).thenReturn(devices);
+
+        enableWifiAndProcessMessages();
+        mCastTile.handleClick();
         mTestableLooper.processAllMessages();
 
-        assertEquals(Tile.STATE_INACTIVE, mCastTile.getState().state);
+        verify(mActivityStarter, times(1)).postQSRunnableDismissingKeyguard(any());
+    }
+
+    @Test
+    public void testHandleClick_projectionOnly() {
+        CastController.CastDevice device = new CastController.CastDevice();
+        device.state = CastDevice.STATE_CONNECTED;
+        device.tag = mock(MediaProjectionInfo.class);
+        List<CastDevice> devices = new ArrayList<>();
+        devices.add(device);
+        when(mController.getCastDevices()).thenReturn(devices);
+
+        enableWifiAndProcessMessages();
+        mCastTile.handleClick();
+        mTestableLooper.processAllMessages();
+
+        verify(mController, times(1)).stopCasting(same(device));
+    }
+
+    @Test
+    public void testUpdateState_projectionOnly() {
+        CastController.CastDevice device = new CastController.CastDevice();
+        device.state = CastDevice.STATE_CONNECTED;
+        device.tag = mock(MediaProjectionInfo.class);
+        device.name = "Test Projection Device";
+        List<CastDevice> devices = new ArrayList<>();
+        devices.add(device);
+        when(mController.getCastDevices()).thenReturn(devices);
+
+        enableWifiAndProcessMessages();
+        assertEquals(Tile.STATE_ACTIVE, mCastTile.getState().state);
+        assertTrue(mCastTile.getState().secondaryLabel.toString().startsWith(device.name));
+    }
+
+    @Test
+    public void testUpdateState_castingAndProjection() {
+        CastController.CastDevice casting = new CastController.CastDevice();
+        casting.state = CastDevice.STATE_CONNECTED;
+        casting.tag = mock(RouteInfo.class);
+        casting.name = "Test Casting Device";
+
+        CastController.CastDevice projection = new CastController.CastDevice();
+        projection.state = CastDevice.STATE_CONNECTED;
+        projection.tag = mock(MediaProjectionInfo.class);
+        projection.name = "Test Projection Device";
+
+        List<CastDevice> devices = new ArrayList<>();
+        devices.add(casting);
+        devices.add(projection);
+        when(mController.getCastDevices()).thenReturn(devices);
+
+        enableWifiAndProcessMessages();
+
+        // Note here that the tile should be active, and should choose casting over projection.
+        assertEquals(Tile.STATE_ACTIVE, mCastTile.getState().state);
+        assertTrue(mCastTile.getState().secondaryLabel.toString().startsWith(casting.name));
+    }
+
+    @Test
+    public void testUpdateState_connectedAndConnecting() {
+        CastController.CastDevice connecting = new CastController.CastDevice();
+        connecting.state = CastDevice.STATE_CONNECTING;
+        connecting.tag = mock(RouteInfo.class);
+        connecting.name = "Test Casting Device";
+
+        CastController.CastDevice connected = new CastController.CastDevice();
+        connected.state = CastDevice.STATE_CONNECTED;
+        connected.tag = mock(RouteInfo.class);
+        connected.name = "Test Casting Device";
+
+        List<CastDevice> devices = new ArrayList<>();
+        devices.add(connecting);
+        devices.add(connected);
+        when(mController.getCastDevices()).thenReturn(devices);
+
+        enableWifiAndProcessMessages();
+
+        // Tile should be connected and always prefer the connected device.
+        assertEquals(Tile.STATE_ACTIVE, mCastTile.getState().state);
+        assertTrue(mCastTile.getState().secondaryLabel.toString().startsWith(connected.name));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 1bcf880..8cc1571 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar;
 
+import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 
@@ -152,8 +153,9 @@
     /**
      * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble.
      */
-    public ExpandableNotificationRow createBubble() throws Exception {
-        return createBubble(null);
+    public ExpandableNotificationRow createBubble()
+            throws Exception {
+        return createBubble(makeBubbleMetadata(null), PKG);
     }
 
     /**
@@ -163,9 +165,20 @@
      */
     public ExpandableNotificationRow createBubble(@Nullable PendingIntent deleteIntent)
             throws Exception {
+        return createBubble(makeBubbleMetadata(deleteIntent), PKG);
+    }
+
+    /**
+     * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble.
+     *
+     * @param bubbleMetadata the {@link BubbleMetadata} to use
+     */
+    public ExpandableNotificationRow createBubble(BubbleMetadata bubbleMetadata, String pkg)
+            throws Exception {
         Notification n = createNotification(false /* isGroupSummary */,
-                null /* groupKey */, true /* isBubble */, deleteIntent);
-        return generateRow(n, PKG, UID, USER_HANDLE, 0 /* extraInflationFlags */, IMPORTANCE_HIGH);
+                null /* groupKey */, bubbleMetadata);
+        n.flags |= FLAG_BUBBLE;
+        return generateRow(n, pkg, UID, USER_HANDLE, 0 /* extraInflationFlags */, IMPORTANCE_HIGH);
     }
 
     /**
@@ -195,7 +208,7 @@
      *
      * @return a notification with no special properties
      */
-    private Notification createNotification() {
+    public Notification createNotification() {
         return createNotification(false /* isGroupSummary */, null /* groupKey */);
     }
 
@@ -207,8 +220,7 @@
      * @return a notification that is in the group specified or standalone if unspecified
      */
     private Notification createNotification(boolean isGroupSummary, @Nullable String groupKey) {
-        return createNotification(isGroupSummary, groupKey, false /* isBubble */,
-                null /* bubbleDeleteIntent */);
+        return createNotification(isGroupSummary, groupKey, null /* bubble metadata */);
     }
 
     /**
@@ -216,12 +228,11 @@
      *
      * @param isGroupSummary whether the notification is a group summary
      * @param groupKey the group key for the notification group used across notifications
-     * @param isBubble whether this notification should bubble
+     * @param bubbleMetadata the bubble metadata to use for this notification if it exists.
      * @return a notification that is in the group specified or standalone if unspecified
      */
     private Notification createNotification(boolean isGroupSummary,
-            @Nullable String groupKey, boolean isBubble,
-            @Nullable PendingIntent bubbleDeleteIntent) {
+            @Nullable String groupKey, @Nullable BubbleMetadata bubbleMetadata) {
         Notification publicVersion = new Notification.Builder(mContext).setSmallIcon(
                 R.drawable.ic_person)
                 .setCustomContentView(new RemoteViews(mContext.getPackageName(),
@@ -239,9 +250,8 @@
         if (!TextUtils.isEmpty(groupKey)) {
             notificationBuilder.setGroup(groupKey);
         }
-        if (isBubble) {
-            BubbleMetadata metadata = makeBubbleMetadata(bubbleDeleteIntent);
-            notificationBuilder.setBubbleMetadata(metadata);
+        if (bubbleMetadata != null) {
+            notificationBuilder.setBubbleMetadata(bubbleMetadata);
         }
         return notificationBuilder.build();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
new file mode 100644
index 0000000..cca9f28
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.os.Bundle;
+import android.service.notification.StatusBarNotification;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class NotificationEntryTest extends SysuiTestCase {
+    @Mock
+    private StatusBarNotification mStatusBarNotification;
+    @Mock
+    private Notification mNotif;
+
+    private NotificationEntry mEntry;
+    private Bundle mExtras;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mStatusBarNotification.getKey()).thenReturn("key");
+        when(mStatusBarNotification.getNotification()).thenReturn(mNotif);
+
+        mExtras = new Bundle();
+        mNotif.extras = mExtras;
+
+        mEntry = new NotificationEntry(mStatusBarNotification);
+    }
+
+    @Test
+    public void testGetUpdateMessage_default() {
+        final String msg = "Hello there!";
+        doReturn(Notification.Style.class).when(mNotif).getNotificationStyle();
+        mExtras.putCharSequence(Notification.EXTRA_TEXT, msg);
+        assertEquals(msg, mEntry.getUpdateMessage(mContext));
+    }
+
+    @Test
+    public void testGetUpdateMessage_bigText() {
+        final String msg = "A big hello there!";
+        doReturn(Notification.BigTextStyle.class).when(mNotif).getNotificationStyle();
+        mExtras.putCharSequence(Notification.EXTRA_TEXT, "A small hello there.");
+        mExtras.putCharSequence(Notification.EXTRA_BIG_TEXT, msg);
+
+        // Should be big text, not the small text.
+        assertEquals(msg, mEntry.getUpdateMessage(mContext));
+    }
+
+    @Test
+    public void testGetUpdateMessage_media() {
+        doReturn(Notification.MediaStyle.class).when(mNotif).getNotificationStyle();
+
+        // Media notifs don't get update messages.
+        assertNull(mEntry.getUpdateMessage(mContext));
+    }
+
+    @Test
+    public void testGetUpdateMessage_inboxStyle() {
+        doReturn(Notification.InboxStyle.class).when(mNotif).getNotificationStyle();
+        mExtras.putCharSequenceArray(
+                Notification.EXTRA_TEXT_LINES,
+                new CharSequence[]{
+                        "How do you feel about tests?",
+                        "They're okay, I guess.",
+                        "I hate when they're flaky.",
+                        "Really? I prefer them that way."});
+
+        // Should be the last one only.
+        assertEquals("Really? I prefer them that way.", mEntry.getUpdateMessage(mContext));
+    }
+
+    @Test
+    public void testGetUpdateMessage_messagingStyle() {
+        doReturn(Notification.MessagingStyle.class).when(mNotif).getNotificationStyle();
+        mExtras.putParcelableArray(
+                Notification.EXTRA_MESSAGES,
+                new Bundle[]{
+                        new Notification.MessagingStyle.Message(
+                                "Hello", 0, "Josh").toBundle(),
+                        new Notification.MessagingStyle.Message(
+                                "Oh, hello!", 0, "Mady").toBundle()});
+
+        // Should be the last one only.
+        assertEquals("Mady: Oh, hello!", mEntry.getUpdateMessage(mContext));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 0aa103f..8077e3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -37,7 +37,9 @@
 import static org.mockito.Mockito.when;
 
 import android.app.AppOpsManager;
+import android.app.Notification;
 import android.app.NotificationChannel;
+import android.os.UserHandle;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -355,4 +357,30 @@
         mGroupRow.setUserExpanded(true);
         Assert.assertTrue(mGroupRow.isExpanded());
     }
+
+    @Test
+    public void testGetIsNonblockable() throws Exception {
+        ExpandableNotificationRow row =
+                mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
+
+        assertFalse(row.getIsNonblockable());
+    }
+
+    @Test
+    public void testGetIsNonblockable_oemLocked() throws Exception {
+        ExpandableNotificationRow row =
+                mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
+        row.getEntry().channel.setImportanceLockedByOEM(true);
+
+        assertTrue(row.getIsNonblockable());
+    }
+
+    @Test
+    public void testGetIsNonblockable_criticalDeviceFunction() throws Exception {
+        ExpandableNotificationRow row =
+                mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
+        row.getEntry().channel.setImportanceLockedByCriticalDeviceFunction(true);
+
+        assertTrue(row.getIsNonblockable());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 1248cbb..67ad37b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -45,7 +45,7 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.Collections;
-import java.util.Set;
+import java.util.List;
 
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
@@ -118,10 +118,10 @@
         verify(mQsTileHost, never()).addTile("night");
     }
 
-    private static Set<CastDevice> buildFakeCastDevice(boolean isCasting) {
+    private static List<CastDevice> buildFakeCastDevice(boolean isCasting) {
         CastDevice cd = new CastDevice();
         cd.state = isCasting ? CastDevice.STATE_CONNECTED : CastDevice.STATE_DISCONNECTED;
-        return Collections.singleton(cd);
+        return Collections.singletonList(cd);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index e84dd68..c2e60d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
@@ -336,11 +337,25 @@
     }
 
     @Test
-    public void testIsShowingScrimmed() {
+    public void testIsShowingScrimmed_true() {
+        doAnswer(invocation -> {
+            assertThat(mBouncer.isScrimmed()).isTrue();
+            return null;
+        }).when(mExpansionCallback).onFullyShown();
         mBouncer.show(false /* resetSecuritySelection */, true /* animate */);
-        assertThat(mBouncer.isShowingScrimmed()).isTrue();
+        assertThat(mBouncer.isScrimmed()).isTrue();
+        mBouncer.hide(false /* destroyView */);
+        assertThat(mBouncer.isScrimmed()).isFalse();
+    }
+
+    @Test
+    public void testIsShowingScrimmed_false() {
+        doAnswer(invocation -> {
+            assertThat(mBouncer.isScrimmed()).isFalse();
+            return null;
+        }).when(mExpansionCallback).onFullyShown();
         mBouncer.show(false /* resetSecuritySelection */, false /* animate */);
-        assertThat(mBouncer.isShowingScrimmed()).isFalse();
+        assertThat(mBouncer.isScrimmed()).isFalse();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 232c6a2..6d6af47 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
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.verify;
@@ -23,6 +25,8 @@
 
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.view.MotionEvent;
+import android.view.ViewGroup;
 
 import androidx.test.filters.SmallTest;
 
@@ -32,6 +36,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.PulseExpansionHandler;
 import com.android.systemui.statusbar.StatusBarStateControllerImpl;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -54,18 +59,43 @@
 public class NotificationPanelViewTest extends SysuiTestCase {
 
     @Mock
+    private StatusBar mStatusBar;
+    @Mock
     private SysuiStatusBarStateController mStatusBarStateController;
     @Mock
     private NotificationStackScrollLayout mNotificationStackScrollLayout;
     @Mock
     private KeyguardStatusView mKeyguardStatusView;
     @Mock
+    private KeyguardBottomAreaView mKeyguardBottomArea;
+    @Mock
+    private KeyguardBottomAreaView mQsFrame;
+    @Mock
+    private ViewGroup mBigClockContainer;
+    @Mock
+    private ScrimController mScrimController;
+    @Mock
+    private NotificationIconAreaController mNotificationAreaController;
+    @Mock
+    private HeadsUpManagerPhone mHeadsUpManager;
+    @Mock
+    private NotificationShelf mNotificationShelf;
+    @Mock
+    private NotificationGroupManager mGroupManager;
+    @Mock
     private KeyguardStatusBarView mKeyguardStatusBar;
+    @Mock
+    private HeadsUpTouchHelper.Callback mHeadsUpCallback;
+    @Mock
+    private PanelBar mPanelBar;
     private NotificationPanelView mNotificationPanelView;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
+        when(mNotificationStackScrollLayout.getHeight()).thenReturn(1000);
+        when(mNotificationStackScrollLayout.getHeadsUpCallback()).thenReturn(mHeadsUpCallback);
+        when(mHeadsUpCallback.getContext()).thenReturn(mContext);
         mDependency.injectTestDependency(StatusBarStateController.class,
                 mStatusBarStateController);
         mDependency.injectMockDependency(ShadeController.class);
@@ -78,6 +108,8 @@
                         new StatusBarStateControllerImpl());
         PulseExpansionHandler expansionHandler = new PulseExpansionHandler(mContext, coordinator);
         mNotificationPanelView = new TestableNotificationPanelView(coordinator, expansionHandler);
+        mNotificationPanelView.setHeadsUpManager(mHeadsUpManager);
+        mNotificationPanelView.setBar(mPanelBar);
     }
 
     @Test
@@ -103,6 +135,37 @@
         verify(mNotificationStackScrollLayout).setShowDarkShelf(eq(false));
     }
 
+    @Test
+    public void testSetExpandedHeight() {
+        mNotificationPanelView.setExpandedHeight(200);
+        assertThat((int) mNotificationPanelView.getExpandedHeight()).isEqualTo(200);
+    }
+
+    @Test
+    public void testOnTouchEvent_expansionCanBeBlocked() {
+        mNotificationPanelView.onTouchEvent(MotionEvent.obtain(0L /* downTime */,
+                0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */,
+                0 /* metaState */));
+        mNotificationPanelView.onTouchEvent(MotionEvent.obtain(0L /* downTime */,
+                0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 200f /* y */,
+                0 /* metaState */));
+        assertThat((int) mNotificationPanelView.getExpandedHeight()).isEqualTo(200);
+        assertThat(mNotificationPanelView.isTrackingBlocked()).isFalse();
+
+        mNotificationPanelView.blockExpansionForCurrentTouch();
+        mNotificationPanelView.onTouchEvent(MotionEvent.obtain(0L /* downTime */,
+                0L /* eventTime */, MotionEvent.ACTION_MOVE, 0f /* x */, 300f /* y */,
+                0 /* metaState */));
+        // Expansion should not have changed because it was blocked
+        assertThat((int) mNotificationPanelView.getExpandedHeight()).isEqualTo(200);
+        assertThat(mNotificationPanelView.isTrackingBlocked()).isTrue();
+
+        mNotificationPanelView.onTouchEvent(MotionEvent.obtain(0L /* downTime */,
+                0L /* eventTime */, MotionEvent.ACTION_UP, 0f /* x */, 300f /* y */,
+                0 /* metaState */));
+        assertThat(mNotificationPanelView.isTrackingBlocked()).isFalse();
+    }
+
     private class TestableNotificationPanelView extends NotificationPanelView {
         TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator,
                 PulseExpansionHandler expansionHandler) {
@@ -113,6 +176,15 @@
             mNotificationStackScroller = mNotificationStackScrollLayout;
             mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
             mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
+            mKeyguardBottomArea = NotificationPanelViewTest.this.mKeyguardBottomArea;
+            mBigClockContainer = NotificationPanelViewTest.this.mBigClockContainer;
+            mQsFrame = NotificationPanelViewTest.this.mQsFrame;
+            initDependencies(NotificationPanelViewTest.this.mStatusBar,
+                    NotificationPanelViewTest.this.mGroupManager,
+                    NotificationPanelViewTest.this.mNotificationShelf,
+                    NotificationPanelViewTest.this.mHeadsUpManager,
+                    NotificationPanelViewTest.this.mNotificationAreaController,
+                    NotificationPanelViewTest.this.mScrimController);
         }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
deleted file mode 100644
index 7829830..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
-
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_DEAD_ZONE;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
-import static com.android.systemui.statusbar.phone.NavigationBarView.WINDOW_TARGET_BOTTOM;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyFloat;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper.RunWithLooper;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.shared.recents.IOverviewProxy;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.MockitoAnnotations;
-
-/** atest QuickStepControllerTest */
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-@SmallTest
-public class QuickStepControllerTest extends SysuiTestCase {
-    private static final int NAVBAR_WIDTH = 1000;
-    private static final int NAVBAR_HEIGHT = 300;
-
-    private QuickStepController mController;
-    private NavigationBarView mNavigationBarView;
-    private StatusBar mStatusBar;
-    private OverviewProxyService mProxyService;
-    private IOverviewProxy mProxy;
-    private Resources mResources;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        final ButtonDispatcher backButton = mock(ButtonDispatcher.class);
-        mResources = mock(Resources.class);
-
-        mProxyService = mock(OverviewProxyService.class);
-        mProxy = mock(IOverviewProxy.Stub.class);
-        doReturn(mProxy).when(mProxyService).getProxy();
-        doReturn(true).when(mProxyService).shouldShowSwipeUpUI();
-        mDependency.injectTestDependency(OverviewProxyService.class, mProxyService);
-
-        mStatusBar = mock(StatusBar.class);
-        doReturn(false).when(mStatusBar).isKeyguardShowing();
-        mContext.putComponent(StatusBar.class, mStatusBar);
-
-        mNavigationBarView = mock(NavigationBarView.class);
-        doReturn(false).when(mNavigationBarView).inScreenPinning();
-        doReturn(true).when(mNavigationBarView).isNotificationsFullyCollapsed();
-        doReturn(true).when(mNavigationBarView).isQuickScrubEnabled();
-        doReturn(HIT_TARGET_NONE).when(mNavigationBarView).getDownHitTarget();
-        doReturn(WINDOW_TARGET_BOTTOM).when(mNavigationBarView).getWindowTarget();
-        doReturn(backButton).when(mNavigationBarView).getBackButton();
-        doReturn(mResources).when(mNavigationBarView).getResources();
-        doReturn(mContext).when(mNavigationBarView).getContext();
-
-        mController = new QuickStepController(mContext);
-        mController.setComponents(mNavigationBarView);
-        mController.setBarState(false /* isRTL */, NAV_BAR_BOTTOM);
-    }
-
-    @Test
-    public void testNoActionsNoGestures() throws Exception {
-        MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
-        assertFalse(mController.onInterceptTouchEvent(ev));
-        verify(mNavigationBarView, never()).requestUnbufferedDispatch(ev);
-        assertNull(mController.getCurrentAction());
-    }
-
-    @Test
-    public void testNoGesturesWhenSwipeUpDisabled() throws Exception {
-        doReturn(false).when(mProxyService).shouldShowSwipeUpUI();
-        mController.setGestureActions(mockAction(true), null /* swipeDownAction */,
-                null /* swipeLeftAction */, null /* swipeRightAction */,  null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-
-        MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
-        assertFalse(mController.onInterceptTouchEvent(ev));
-        verify(mNavigationBarView, never()).requestUnbufferedDispatch(ev);
-        assertNull(mController.getCurrentAction());
-    }
-
-    @Test
-    public void testHasActionDetectGesturesTouchdown() throws Exception {
-        MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
-
-        // Add enabled gesture action
-        NavigationGestureAction action = mockAction(true);
-        mController.setGestureActions(action, null /* swipeDownAction */,
-                null /* swipeLeftAction */, null /* swipeRightAction */, null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-
-        assertFalse(mController.onInterceptTouchEvent(ev));
-        verify(mNavigationBarView, times(1)).requestUnbufferedDispatch(ev);
-        verify(action, times(1)).reset();
-        verify(mProxy, times(1)).onPreMotionEvent(mNavigationBarView.getDownHitTarget());
-        verify(mProxy, times(1)).onMotionEvent(ev);
-        assertNull(mController.getCurrentAction());
-    }
-
-    @Test
-    public void testProxyDisconnectedNoGestures() throws Exception {
-        MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
-
-        // Add enabled gesture action
-        mController.setGestureActions(mockAction(true), null /* swipeDownAction */,
-                null /* swipeLeftAction */, null /* swipeRightAction */, null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-
-        // Set the gesture on deadzone
-        doReturn(null).when(mProxyService).getProxy();
-
-        assertFalse(mController.onInterceptTouchEvent(ev));
-        verify(mNavigationBarView, never()).requestUnbufferedDispatch(ev);
-        assertNull(mController.getCurrentAction());
-    }
-
-    @Test
-    public void testNoActionsNoGesturesOverDeadzone() throws Exception {
-        MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
-
-        // Touched over deadzone
-        doReturn(HIT_TARGET_DEAD_ZONE).when(mNavigationBarView).getDownHitTarget();
-
-        assertTrue(mController.onInterceptTouchEvent(ev));
-        verify(mNavigationBarView, never()).requestUnbufferedDispatch(ev);
-        assertNull(mController.getCurrentAction());
-    }
-
-    @Test
-    public void testOnTouchIgnoredDownEventAfterOnIntercept() {
-        mController.setGestureActions(mockAction(true), null /* swipeDownAction */,
-                null /* swipeLeftAction */, null /* swipeRightAction */, null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-
-        MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
-        assertFalse(touch(ev));
-        verify(mNavigationBarView, times(1)).requestUnbufferedDispatch(ev);
-
-        // OnTouch event for down is ignored, so requestUnbufferedDispatch ran once from before
-        assertFalse(mNavigationBarView.onTouchEvent(ev));
-        verify(mNavigationBarView, times(1)).requestUnbufferedDispatch(ev);
-    }
-
-    @Test
-    public void testGesturesCallCorrectAction() throws Exception {
-        doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getWidth();
-        doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getHeight();
-
-        NavigationGestureAction swipeUp = mockAction(true);
-        NavigationGestureAction swipeDown = mockAction(true);
-        NavigationGestureAction swipeLeft = mockAction(true);
-        NavigationGestureAction swipeRight = mockAction(true);
-        mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
-                null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
-
-        // Swipe Up
-        assertGestureTriggersAction(swipeUp, 1, 100, 5, 1);
-        // Swipe Down
-        assertGestureTriggersAction(swipeDown, 1, 1, 5, 100);
-        // Swipe Left
-        assertGestureTriggersAction(swipeLeft, NAVBAR_WIDTH / 2, 1, 5, 1);
-        // Swipe Right
-        assertGestureTriggersAction(swipeRight, NAVBAR_WIDTH / 2, 1, NAVBAR_WIDTH, 5);
-    }
-
-    @Test
-    public void testGesturesCallCorrectActionLandscape() throws Exception {
-        doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getWidth();
-        doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getHeight();
-
-        NavigationGestureAction swipeUp = mockAction(true);
-        NavigationGestureAction swipeDown = mockAction(true);
-        NavigationGestureAction swipeLeft = mockAction(true);
-        NavigationGestureAction swipeRight = mockAction(true);
-        mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
-                null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
-
-        // In landscape
-        mController.setBarState(false /* isRTL */, NAV_BAR_RIGHT);
-
-        // Swipe Up
-        assertGestureTriggersAction(swipeRight, 1, 100, 5, 1);
-        // Swipe Down
-        assertGestureTriggersAction(swipeLeft, 1, NAVBAR_WIDTH / 2, 5, NAVBAR_WIDTH);
-        // Swipe Left
-        assertGestureTriggersAction(swipeUp, 100, 1, 5, 1);
-        // Swipe Right
-        assertGestureTriggersAction(swipeDown, 1, 1, 100, 5);
-    }
-
-    @Test
-    public void testGesturesCallCorrectActionSeascape() throws Exception {
-        doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getWidth();
-        doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getHeight();
-
-        mController.setBarState(false /* isRTL */, NAV_BAR_LEFT);
-        NavigationGestureAction swipeUp = mockAction(true);
-        NavigationGestureAction swipeDown = mockAction(true);
-        NavigationGestureAction swipeLeft = mockAction(true);
-        NavigationGestureAction swipeRight = mockAction(true);
-        mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
-                null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
-
-        // Swipe Up
-        assertGestureTriggersAction(swipeLeft, 1, NAVBAR_WIDTH / 2, 5, 1);
-        // Swipe Down
-        assertGestureTriggersAction(swipeRight, 1, NAVBAR_WIDTH / 2, 5, NAVBAR_WIDTH);
-        // Swipe Left
-        assertGestureTriggersAction(swipeDown, 100, 1, 5, 1);
-        // Swipe Right
-        assertGestureTriggersAction(swipeUp, 1, 1, 100, 5);
-    }
-
-    @Test
-    public void testGesturesCallCorrectActionRTL() throws Exception {
-        doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getWidth();
-        doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getHeight();
-        mController.setBarState(true /* isRTL */, NAV_BAR_BOTTOM);
-
-        // The swipe gestures below are for LTR, so RTL in portrait will be swapped
-        NavigationGestureAction swipeUp = mockAction(true);
-        NavigationGestureAction swipeDown = mockAction(true);
-        NavigationGestureAction swipeLeft = mockAction(true);
-        NavigationGestureAction swipeRight = mockAction(true);
-        mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
-                null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
-
-        // Swipe Up in RTL
-        assertGestureTriggersAction(swipeUp, 1, 100, 5, 1);
-        // Swipe Down in RTL
-        assertGestureTriggersAction(swipeDown, 1, 1, 5, 100);
-        // Swipe Left in RTL
-        assertGestureTriggersAction(swipeRight, NAVBAR_WIDTH / 2, 1, 5, 1);
-        // Swipe Right in RTL
-        assertGestureTriggersAction(swipeLeft, NAVBAR_WIDTH / 2, 1, NAVBAR_WIDTH, 0);
-    }
-
-    @Test
-    public void testGesturesCallCorrectActionLandscapeRTL() throws Exception {
-        doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getWidth();
-        doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getHeight();
-        mController.setBarState(true /* isRTL */, NAV_BAR_RIGHT);
-
-        // The swipe gestures below are for LTR, so RTL in landscape will be swapped
-        NavigationGestureAction swipeUp = mockAction(true);
-        NavigationGestureAction swipeDown = mockAction(true);
-        NavigationGestureAction swipeLeft = mockAction(true);
-        NavigationGestureAction swipeRight = mockAction(true);
-        mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
-                null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
-
-        // Swipe Up
-        assertGestureTriggersAction(swipeLeft, 1, NAVBAR_WIDTH / 2, 5, 1);
-        // Swipe Down
-        assertGestureTriggersAction(swipeRight, 1, NAVBAR_WIDTH / 2, 5, NAVBAR_WIDTH);
-        // Swipe Left
-        assertGestureTriggersAction(swipeUp, 100, 1, 5, 1);
-        // Swipe Right
-        assertGestureTriggersAction(swipeDown, 1, 1, 100, 5);
-    }
-
-    @Test
-    public void testGesturesCallCorrectActionSeascapeRTL() throws Exception {
-        doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getWidth();
-        doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getHeight();
-        mController.setBarState(true /* isRTL */, NAV_BAR_LEFT);
-
-        // The swipe gestures below are for LTR, so RTL in seascape will be swapped
-        NavigationGestureAction swipeUp = mockAction(true);
-        NavigationGestureAction swipeDown = mockAction(true);
-        NavigationGestureAction swipeLeft = mockAction(true);
-        NavigationGestureAction swipeRight = mockAction(true);
-        mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight,
-                null /* leftEdgeSwipe */, null /* rightEdgeSwipe */);
-
-        // Swipe Up
-        assertGestureTriggersAction(swipeRight, 1, NAVBAR_WIDTH / 2, 5, 1);
-        // Swipe Down
-        assertGestureTriggersAction(swipeLeft, 1, NAVBAR_WIDTH / 2, 5, NAVBAR_WIDTH);
-        // Swipe Left
-        assertGestureTriggersAction(swipeDown, 100, 1, 5, 1);
-        // Swipe Right
-        assertGestureTriggersAction(swipeUp, 1, 1, 100, 5);
-    }
-
-    @Test
-    public void testActionPreventByPinnedState() throws Exception {
-        // Screen is pinned
-        doReturn(true).when(mNavigationBarView).inScreenPinning();
-
-        // Add enabled gesture action
-        NavigationGestureAction action = mockAction(true);
-        mController.setGestureActions(action, null /* swipeDownAction */,
-                null /* swipeLeftAction */, null /* swipeRightAction */, null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-
-        // Touch down to begin swipe
-        MotionEvent downEvent = event(MotionEvent.ACTION_DOWN, 1, 100);
-        assertFalse(touch(downEvent));
-        verify(mProxy, never()).onPreMotionEvent(mNavigationBarView.getDownHitTarget());
-        verify(mProxy, never()).onMotionEvent(downEvent);
-
-        // Move to start gesture, but pinned so it should not trigger action
-        MotionEvent moveEvent = event(MotionEvent.ACTION_MOVE, 1, 1);
-        assertFalse(touch(moveEvent));
-        assertNull(mController.getCurrentAction());
-        verify(mNavigationBarView, times(1)).showPinningEscapeToast();
-        verify(action, never()).onGestureStart(moveEvent);
-    }
-
-    @Test
-    public void testActionPreventedNotificationsShown() throws Exception {
-        NavigationGestureAction action = mockAction(true);
-        doReturn(false).when(action).canRunWhenNotificationsShowing();
-        mController.setGestureActions(action, null /* swipeDownAction */,
-                null /* swipeLeftAction */, null /* swipeRightAction */, null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-
-        // Show the notifications
-        doReturn(false).when(mNavigationBarView).isNotificationsFullyCollapsed();
-
-        // Swipe up
-        assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
-        assertFalse(touch(MotionEvent.ACTION_MOVE, 1, 1));
-        assertNull(mController.getCurrentAction());
-        assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
-
-        // Hide the notifications
-        doReturn(true).when(mNavigationBarView).isNotificationsFullyCollapsed();
-
-        // Swipe up
-        assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
-        assertTrue(touch(MotionEvent.ACTION_MOVE, 1, 1));
-        assertEquals(action, mController.getCurrentAction());
-        assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
-    }
-
-    @Test
-    public void testActionCannotPerform() throws Exception {
-        NavigationGestureAction action = mockAction(true);
-        mController.setGestureActions(action, null /* swipeDownAction */,
-                null /* swipeLeftAction */, null /* swipeRightAction */, null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-
-        // Cannot perform action
-        doReturn(false).when(action).canPerformAction();
-
-        // Swipe up
-        assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
-        assertFalse(touch(MotionEvent.ACTION_MOVE, 1, 1));
-        assertNull(mController.getCurrentAction());
-        assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
-
-        // Cannot perform action
-        doReturn(true).when(action).canPerformAction();
-
-        // Swipe up
-        assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
-        assertTrue(touch(MotionEvent.ACTION_MOVE, 1, 1));
-        assertEquals(action, mController.getCurrentAction());
-        assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
-    }
-
-    @Test
-    public void testQuickScrub() throws Exception {
-        doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getWidth();
-        doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getHeight();
-        QuickScrubAction action = spy(new QuickScrubAction(mNavigationBarView, mProxyService));
-        mController.setGestureActions(null /* swipeUpAction */, null /* swipeDownAction */,
-                null /* swipeLeftAction */, action, null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-        int x = NAVBAR_WIDTH / 2;
-        int y = 20;
-
-        // Set the layout and other padding to make sure the scrub fraction is calculated correctly
-        action.onLayout(true, 0, 0, NAVBAR_WIDTH, NAVBAR_HEIGHT);
-        doReturn(0).when(mNavigationBarView).getPaddingLeft();
-        doReturn(0).when(mNavigationBarView).getPaddingRight();
-        doReturn(0).when(mNavigationBarView).getPaddingStart();
-        doReturn(0).when(mResources)
-                .getDimensionPixelSize(R.dimen.nav_quick_scrub_track_edge_padding);
-
-        // Quickscrub disabled, so the action should be disabled
-        doReturn(false).when(mNavigationBarView).isQuickScrubEnabled();
-        assertFalse(action.isEnabled());
-        doReturn(true).when(mNavigationBarView).isQuickScrubEnabled();
-
-        // Touch down
-        MotionEvent downEvent = event(MotionEvent.ACTION_DOWN, x, y);
-        assertFalse(touch(downEvent));
-        assertNull(mController.getCurrentAction());
-        verify(mProxy, times(1)).onPreMotionEvent(mNavigationBarView.getDownHitTarget());
-        verify(mProxy, times(1)).onMotionEvent(downEvent);
-
-        // Move to start trigger action from gesture
-        MotionEvent moveEvent1 = event(MotionEvent.ACTION_MOVE, x + 100, y);
-        assertTrue(touch(moveEvent1));
-        assertEquals(action, mController.getCurrentAction());
-        verify(action, times(1)).onGestureStart(moveEvent1);
-        verify(mProxy, times(1)).onQuickScrubStart();
-        verify(mProxyService, times(1)).notifyQuickScrubStarted();
-        verify(mNavigationBarView, times(1)).updateSlippery();
-        verify(mProxy, never()).onMotionEvent(moveEvent1);
-
-        // Move again for scrub
-        float fraction = 3f / 4;
-        x = (int) (NAVBAR_WIDTH * fraction);
-        MotionEvent moveEvent2 = event(MotionEvent.ACTION_MOVE, x, y);
-        assertTrue(touch(moveEvent2));
-        assertEquals(action, mController.getCurrentAction());
-        verify(action, times(1)).onGestureMove(x, y);
-        verify(mProxy, times(1)).onQuickScrubProgress(fraction);
-        verify(mProxy, never()).onMotionEvent(moveEvent2);
-
-        // Action up
-        MotionEvent upEvent = event(MotionEvent.ACTION_UP, 1, y);
-        assertFalse(touch(upEvent));
-        assertNull(mController.getCurrentAction());
-        verify(action, times(1)).onGestureEnd();
-        verify(mProxy, times(1)).onQuickScrubEnd();
-        verify(mProxy, never()).onMotionEvent(upEvent);
-    }
-
-    @Test
-    public void testQuickStep() throws Exception {
-        QuickStepAction action = new QuickStepAction(mNavigationBarView, mProxyService);
-        mController.setGestureActions(action, null /* swipeDownAction */,
-                null /* swipeLeftAction */, null /* swipeRightAction */, null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-
-        // Notifications are up, should prevent quickstep
-        doReturn(false).when(mNavigationBarView).isNotificationsFullyCollapsed();
-
-        // Swipe up
-        assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
-        assertNull(mController.getCurrentAction());
-        assertFalse(touch(MotionEvent.ACTION_MOVE, 1, 1));
-        assertNull(mController.getCurrentAction());
-        assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
-        doReturn(true).when(mNavigationBarView).isNotificationsFullyCollapsed();
-
-        // Quickstep disabled, so the action should be disabled
-        doReturn(false).when(mNavigationBarView).isQuickStepSwipeUpEnabled();
-        assertFalse(action.isEnabled());
-        doReturn(true).when(mNavigationBarView).isQuickStepSwipeUpEnabled();
-
-        // Swipe up should call proxy events
-        MotionEvent downEvent = event(MotionEvent.ACTION_DOWN, 1, 100);
-        assertFalse(touch(downEvent));
-        assertNull(mController.getCurrentAction());
-        verify(mProxy, times(1)).onPreMotionEvent(mNavigationBarView.getDownHitTarget());
-        verify(mProxy, times(1)).onMotionEvent(downEvent);
-
-        MotionEvent moveEvent = event(MotionEvent.ACTION_MOVE, 1, 1);
-        assertTrue(touch(moveEvent));
-        assertEquals(action, mController.getCurrentAction());
-        verify(mProxy, times(1)).onQuickStep(moveEvent);
-        verify(mProxyService, times(1)).notifyQuickStepStarted();
-    }
-
-    @Test
-    public void testLongPressPreventDetection() throws Exception {
-        NavigationGestureAction action = mockAction(true);
-        mController.setGestureActions(action, null /* swipeDownAction */,
-                null /* swipeLeftAction */, null /* swipeRightAction */, null /* leftEdgeSwipe */,
-                null /* rightEdgeSwipe */);
-
-        // Start the drag up
-        assertFalse(touch(MotionEvent.ACTION_DOWN, 100, 1));
-        assertNull(mController.getCurrentAction());
-
-        // Long press something on the navigation bar such as Home button
-        mNavigationBarView.onNavigationButtonLongPress(mock(View.class));
-
-        // Swipe right will not start any gestures
-        MotionEvent motionMoveEvent = event(MotionEvent.ACTION_MOVE, 1, 1);
-        assertFalse(touch(motionMoveEvent));
-        assertNull(mController.getCurrentAction());
-        verify(action, never()).startGesture(motionMoveEvent);
-
-        // Touch up
-        assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
-        verify(action, never()).endGesture();
-    }
-
-    @Test
-    public void testHitTargetDragged() throws Exception {
-        ButtonDispatcher button = mock(ButtonDispatcher.class);
-        FakeLocationView buttonView = spy(new FakeLocationView(mContext, NAVBAR_WIDTH / 2,
-                NAVBAR_HEIGHT / 2));
-        doReturn(buttonView).when(button).getCurrentView();
-
-        NavigationGestureAction action = mockAction(true);
-        mController.setGestureActions(action, action, action, action, action, action);
-
-        // Setup getting the hit target
-        doReturn(HIT_TARGET_HOME).when(action).requiresTouchDownHitTarget();
-        doReturn(true).when(action).allowHitTargetToMoveOverDrag();
-        doReturn(HIT_TARGET_HOME).when(mNavigationBarView).getDownHitTarget();
-        doReturn(button).when(mNavigationBarView).getHomeButton();
-        doReturn(NAVBAR_WIDTH).when(mNavigationBarView).getWidth();
-        doReturn(NAVBAR_HEIGHT).when(mNavigationBarView).getHeight();
-
-        // Portrait
-        assertGestureDragsHitTargetAllDirections(buttonView, false /* isRTL */, NAV_BAR_BOTTOM);
-
-        // Portrait RTL
-        assertGestureDragsHitTargetAllDirections(buttonView, true /* isRTL */, NAV_BAR_BOTTOM);
-
-        // Landscape
-        assertGestureDragsHitTargetAllDirections(buttonView, false /* isRTL */, NAV_BAR_RIGHT);
-
-        // Landscape RTL
-        assertGestureDragsHitTargetAllDirections(buttonView, true /* isRTL */, NAV_BAR_RIGHT);
-
-        // Seascape
-        assertGestureDragsHitTargetAllDirections(buttonView, false /* isRTL */, NAV_BAR_LEFT);
-
-        // Seascape RTL
-        assertGestureDragsHitTargetAllDirections(buttonView, true /* isRTL */, NAV_BAR_LEFT);
-    }
-
-    private void assertGestureDragsHitTargetAllDirections(View buttonView, boolean isRTL,
-            int navPos) {
-        mController.setBarState(isRTL, navPos);
-
-        // Swipe up
-        assertGestureDragsHitTarget(buttonView, 10 /* x1 */, 200 /* y1 */, 0 /* x2 */, 0 /* y2 */,
-                0 /* dx */, -1 /* dy */);
-        // Swipe left
-        assertGestureDragsHitTarget(buttonView, 200 /* x1 */, 10 /* y1 */, 0 /* x2 */, 0 /* y2 */,
-                -1 /* dx */, 0 /* dy */);
-        // Swipe right
-        assertGestureDragsHitTarget(buttonView, 0 /* x1 */, 0 /* y1 */, 200 /* x2 */, 10 /* y2 */,
-                1 /* dx */, 0 /* dy */);
-        // Swipe down
-        assertGestureDragsHitTarget(buttonView, 0 /* x1 */, 0 /* y1 */, 10 /* x2 */, 200 /* y2 */,
-                0 /* dx */, 1 /* dy */);
-    }
-
-    /**
-     * Asserts the gesture actually moves the hit target
-     * @param buttonView button to check if moved, use Mockito.spy on a real object
-     * @param x1 start x
-     * @param x2 start y
-     * @param y1 end x
-     * @param y2 end y
-     * @param dx diff in x, if not 0, its sign determines direction, value does not matter
-     * @param dy diff in y, if not 0, its sign determines direction, value does not matter
-     */
-    private void assertGestureDragsHitTarget(View buttonView, int x1, int y1, int x2, int y2,
-            int dx, int dy) {
-        ArgumentCaptor<Float> captor = ArgumentCaptor.forClass(Float.class);
-        assertFalse(touch(MotionEvent.ACTION_DOWN, x1, y1));
-        assertTrue(touch(MotionEvent.ACTION_MOVE, x2, y2));
-
-        // Verify positions of the button drag
-        if (dx == 0) {
-            verify(buttonView, never()).setTranslationX(anyFloat());
-        } else {
-            verify(buttonView).setTranslationX(captor.capture());
-            if (dx < 0) {
-                assertTrue("Button should have moved left", (float) captor.getValue() < 0);
-            } else {
-                assertTrue("Button should have moved right", (float) captor.getValue() > 0);
-            }
-        }
-        if (dy == 0) {
-            verify(buttonView, never()).setTranslationY(anyFloat());
-        } else {
-            verify(buttonView).setTranslationY(captor.capture());
-            if (dy < 0) {
-                assertTrue("Button should have moved up", (float) captor.getValue() < 0);
-            } else {
-                assertTrue("Button should have moved down", (float) captor.getValue() > 0);
-            }
-        }
-
-        // Touch up
-        assertFalse(touch(MotionEvent.ACTION_UP, x2, y2));
-        verify(buttonView, times(1)).animate();
-
-        // Reset button state
-        reset(buttonView);
-    }
-
-    private MotionEvent event(int action, float x, float y) {
-        final MotionEvent event = mock(MotionEvent.class);
-        doReturn(x).when(event).getX();
-        doReturn(y).when(event).getY();
-        doReturn(action & MotionEvent.ACTION_MASK).when(event).getActionMasked();
-        doReturn(action).when(event).getAction();
-        return event;
-    }
-
-    private boolean touch(int action, float x, float y) {
-        return touch(event(action, x, y));
-    }
-
-    private boolean touch(MotionEvent event) {
-        return mController.onInterceptTouchEvent(event);
-    }
-
-    private NavigationGestureAction mockAction(boolean enabled) {
-        final NavigationGestureAction action = mock(NavigationGestureAction.class);
-        doReturn(enabled).when(action).isEnabled();
-        doReturn(HIT_TARGET_NONE).when(action).requiresTouchDownHitTarget();
-        doReturn(true).when(action).canPerformAction();
-        return action;
-    }
-
-    private void assertGestureTriggersAction(NavigationGestureAction action, int x1, int y1,
-            int x2, int y2) {
-        // Start the drag
-        assertFalse(touch(MotionEvent.ACTION_DOWN, x1, y1));
-        assertNull(mController.getCurrentAction());
-
-        // Swipe
-        MotionEvent motionMoveEvent = event(MotionEvent.ACTION_MOVE, x2, y2);
-        assertTrue(touch(motionMoveEvent));
-        assertEquals(action, mController.getCurrentAction());
-        verify(action, times(1)).startGesture(motionMoveEvent);
-
-        // Move again
-        assertTrue(touch(MotionEvent.ACTION_MOVE, x2, y2));
-        verify(action, times(1)).onGestureMove(x2, y2);
-
-        // Touch up
-        assertFalse(touch(MotionEvent.ACTION_UP, x2, y2));
-        assertNull(mController.getCurrentAction());
-        verify(action, times(1)).endGesture();
-    }
-
-    static class FakeLocationView extends View {
-        private final int mX;
-        private final int mY;
-
-        public FakeLocationView(Context context, int x, int y) {
-            super(context);
-            mX = x;
-            mY = y;
-        }
-
-        @Override
-        public void getLocationInWindow(int[] outLocation) {
-            outLocation[0] = mX;
-            outLocation[1] = mY;
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 539851f..191c983 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -46,7 +46,6 @@
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.util.function.TriConsumer;
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.doze.DozeLog;
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.util.wakelock.WakeLock;
 import com.android.systemui.utils.os.FakeHandler;
@@ -140,7 +139,6 @@
         assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
 
         // Pulsing notification should conserve AOD wallpaper.
-        mScrimController.setPulseReason(DozeLog.PULSE_REASON_NOTIFICATION);
         mScrimController.transitionTo(ScrimState.PULSING);
         mScrimController.finishAnimationsImmediately();
         assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
@@ -225,14 +223,17 @@
         mScrimController.finishAnimationsImmediately();
         assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
 
-        mScrimController.setPulseReason(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN);
         mScrimController.transitionTo(ScrimState.PULSING);
         mScrimController.finishAnimationsImmediately();
         // Front scrim should be transparent
         // Back scrim should be semi-transparent so the user can see the wallpaper
         // Pulse callback should have been invoked
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
+        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
         assertScrimTint(mScrimBehind, true /* tinted */);
+
+        mScrimController.setWakeLockScreenSensorActive(true);
+        mScrimController.finishAnimationsImmediately();
+        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
     }
 
     @Test
@@ -486,7 +487,6 @@
     @Test
     public void testHoldsPulsingWallpaperAnimationLock() {
         // Pre-conditions
-        mScrimController.setPulseReason(DozeLog.PULSE_REASON_NOTIFICATION);
         mScrimController.transitionTo(ScrimState.PULSING);
         mScrimController.finishAnimationsImmediately();
         reset(mWakeLock);
@@ -508,30 +508,6 @@
     }
 
     @Test
-    public void testWillHidePulsingWallpaper_whenNotification() {
-        mScrimController.setWallpaperSupportsAmbientMode(false);
-        mScrimController.transitionTo(ScrimState.AOD);
-        mScrimController.finishAnimationsImmediately();
-        mScrimController.setPulseReason(DozeLog.PULSE_REASON_NOTIFICATION);
-        mScrimController.transitionTo(ScrimState.PULSING);
-        mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
-        assertScrimTint(mScrimBehind, true);
-    }
-
-    @Test
-    public void testWillHidePulsingWallpaper_whenDocking() {
-        mScrimController.setWallpaperSupportsAmbientMode(false);
-        mScrimController.transitionTo(ScrimState.AOD);
-        mScrimController.finishAnimationsImmediately();
-        mScrimController.setPulseReason(DozeLog.PULSE_REASON_DOCKING);
-        mScrimController.transitionTo(ScrimState.PULSING);
-        mScrimController.finishAnimationsImmediately();
-        assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
-        assertScrimTint(mScrimBehind, true);
-    }
-
-    @Test
     public void testConservesExpansionOpacityAfterTransition() {
         mScrimController.transitionTo(ScrimState.UNLOCKED);
         mScrimController.setPanelExpansion(0.5f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 1a27765..7d347d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -120,7 +120,8 @@
 
     @Test
     public void onPanelExpansionChanged_neverHidesScrimmedBouncer() {
-        when(mBouncer.isShowingScrimmed()).thenReturn(true);
+        when(mBouncer.isShowing()).thenReturn(true);
+        when(mBouncer.isScrimmed()).thenReturn(true);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */,
                 true /* tracking */);
         verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_VISIBLE));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 20af1ac..51fb47b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -24,7 +24,10 @@
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.KeyguardManager;
@@ -49,6 +52,7 @@
 import com.android.systemui.ActivityIntentHelper;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
+import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -101,22 +105,23 @@
     private KeyguardMonitor mKeyguardMonitor;
     @Mock
     private Handler mHandler;
+    @Mock
+    private BubbleController mBubbleController;
 
     @Mock
     private ActivityIntentHelper mActivityIntentHelper;
     @Mock
     private PendingIntent mContentIntent;
     @Mock
+    private Intent mContentIntentInner;
+    @Mock
     private NotificationData mNotificationData;
-    @Mock
-    private NotificationEntry mNotificationEntry;
-    @Mock
-    private NotificationEntry mBubbleEntry;
 
     private NotificationActivityStarter mNotificationActivityStarter;
 
     private NotificationTestHelper mNotificationTestHelper;
-    ExpandableNotificationRow mNotificationRow;
+    private ExpandableNotificationRow mNotificationRow;
+    private ExpandableNotificationRow mBubbleNotificationRow;
 
     private final Answer<Void> mCallOnDismiss = answerVoid(
             (ActivityStarter.OnDismissAction dismissAction, Runnable cancel,
@@ -129,14 +134,31 @@
         when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
         when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
 
-        mActiveNotifications = new ArrayList<>();
-        mActiveNotifications.add(mNotificationEntry);
-        mActiveNotifications.add(mBubbleEntry);
-        when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications);
-        when(mNotificationEntry.getRow()).thenReturn(mNotificationRow);
+        when(mContentIntent.isActivity()).thenReturn(true);
+        when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1));
+        when(mContentIntent.getIntent()).thenReturn(mContentIntentInner);
 
         mNotificationTestHelper = new NotificationTestHelper(mContext);
+
+        // Create standard notification with contentIntent
         mNotificationRow = mNotificationTestHelper.createRow();
+        StatusBarNotification sbn = mNotificationRow.getStatusBarNotification();
+        sbn.getNotification().contentIntent = mContentIntent;
+        sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
+
+        // Create bubble notification row with contentIntent
+        mBubbleNotificationRow = mNotificationTestHelper.createBubble();
+        StatusBarNotification bubbleSbn = mBubbleNotificationRow.getStatusBarNotification();
+        bubbleSbn.getNotification().contentIntent = mContentIntent;
+        bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
+        // Do what BubbleController's NotificationEntryListener#onPendingEntryAdded does:
+        mBubbleNotificationRow.getEntry().setShowInShadeWhenBubble(true);
+
+        mActiveNotifications = new ArrayList<>();
+        mActiveNotifications.add(mNotificationRow.getEntry());
+        mActiveNotifications.add(mBubbleNotificationRow.getEntry());
+        when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications);
+        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
 
         mNotificationActivityStarter = new StatusBarNotificationActivityStarter(getContext(),
                 mock(CommandQueue.class), mAssistManager, mock(NotificationPanelView.class),
@@ -147,16 +169,8 @@
                 mock(StatusBarRemoteInputCallback.class), mock(NotificationGroupManager.class),
                 mock(NotificationLockscreenUserManager.class), mShadeController, mKeyguardMonitor,
                 mock(NotificationInterruptionStateProvider.class), mock(MetricsLogger.class),
-                mock(LockPatternUtils.class), mHandler, mActivityIntentHelper);
-
-
-        when(mContentIntent.isActivity()).thenReturn(true);
-        when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1));
-
-        // SBNActivityStarter expects contentIntent or fullScreenIntent to be set
-        mNotificationRow.getEntry().notification.getNotification().contentIntent = mContentIntent;
-
-        when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
+                mock(LockPatternUtils.class), mHandler, mHandler, mActivityIntentHelper,
+                mBubbleController);
 
         // set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg
         doAnswer(mCallOnDismiss).when(mActivityStarter).dismissKeyguardThenExecute(
@@ -173,33 +187,26 @@
         // set up Handler to synchronously invoke the Runnable arg
         doAnswer(answerVoid(Runnable::run))
                 .when(mHandler).post(any(Runnable.class));
+
+        doAnswer(answerVoid(Runnable::run))
+                .when(mHandler).postAtFrontOfQueue(any(Runnable.class));
     }
 
     @Test
-    public void testOnNotificationClicked_whileKeyguardVisible()
+    public void testOnNotificationClicked_keyGuardShowing()
             throws PendingIntent.CanceledException, RemoteException {
         // Given
+        StatusBarNotification sbn = mNotificationRow.getStatusBarNotification();
+        sbn.getNotification().contentIntent = mContentIntent;
+        sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
+
         when(mKeyguardMonitor.isShowing()).thenReturn(true);
         when(mShadeController.isOccluded()).thenReturn(true);
-        when(mContentIntent.isActivity()).thenReturn(true);
-        when(mActivityIntentHelper.wouldShowOverLockscreen(any(Intent.class), anyInt()))
-                .thenReturn(false);
-        when(mActivityIntentHelper.wouldLaunchResolverActivity(any(Intent.class), anyInt()))
-                .thenReturn(false);
-
-        StatusBarNotification statusBarNotification = mNotificationRow.getEntry().notification;
-        statusBarNotification.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
 
         // When
-        mNotificationActivityStarter.onNotificationClicked(statusBarNotification,
-                mNotificationRow);
+        mNotificationActivityStarter.onNotificationClicked(sbn, mNotificationRow);
 
         // Then
-        verify(mActivityStarter).dismissKeyguardThenExecute(
-                any(ActivityStarter.OnDismissAction.class),
-                any() /* cancel */,
-                anyBoolean() /* afterKeyguardGone */);
-
         verify(mShadeController, atLeastOnce()).collapsePanel();
 
         verify(mContentIntent).sendAndReturnResult(
@@ -214,9 +221,100 @@
         verify(mAssistManager).hideAssist();
 
         verify(mStatusBarService).onNotificationClick(
-                eq(mNotificationRow.getEntry().key), any(NotificationVisibility.class));
+                eq(sbn.getKey()), any(NotificationVisibility.class));
 
         // Notification is removed due to FLAG_AUTO_CANCEL
-        verify(mEntryManager).performRemoveNotification(eq(statusBarNotification));
+        verify(mEntryManager).performRemoveNotification(eq(sbn));
+    }
+
+    @Test
+    public void testOnNotificationClicked_bubble_noContentIntent_noKeyGuard()
+            throws RemoteException {
+        StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification();
+
+        // Given
+        sbn.getNotification().contentIntent = null;
+
+        // When
+        mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
+
+        // Then
+        verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey()));
+
+        // This is called regardless, and simply short circuits when there is nothing to do.
+        verify(mShadeController, atLeastOnce()).collapsePanel();
+
+        verify(mAssistManager).hideAssist();
+
+        verify(mStatusBarService).onNotificationClick(
+                eq(sbn.getKey()), any(NotificationVisibility.class));
+
+        // The content intent should NOT be sent on click.
+        verifyZeroInteractions(mContentIntent);
+
+        // Notification should not be cancelled.
+        verify(mEntryManager, never()).performRemoveNotification(eq(sbn));
+    }
+
+    @Test
+    public void testOnNotificationClicked_bubble_noContentIntent_keyGuardShowing()
+            throws RemoteException {
+        StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification();
+
+        // Given
+        sbn.getNotification().contentIntent = null;
+        when(mKeyguardMonitor.isShowing()).thenReturn(true);
+        when(mShadeController.isOccluded()).thenReturn(true);
+
+        // When
+        mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
+
+        // Then
+        verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey()));
+
+        verify(mShadeController, atLeastOnce()).collapsePanel();
+
+        verify(mAssistManager).hideAssist();
+
+        verify(mStatusBarService).onNotificationClick(
+                eq(sbn.getKey()), any(NotificationVisibility.class));
+
+        // The content intent should NOT be sent on click.
+        verifyZeroInteractions(mContentIntent);
+
+        // Notification should not be cancelled.
+        verify(mEntryManager, never()).performRemoveNotification(eq(sbn));
+    }
+
+    @Test
+    public void testOnNotificationClicked_bubble_withContentIntent_keyGuardShowing()
+            throws RemoteException {
+        StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification();
+
+        // Given
+        sbn.getNotification().contentIntent = mContentIntent;
+        when(mKeyguardMonitor.isShowing()).thenReturn(true);
+        when(mShadeController.isOccluded()).thenReturn(true);
+
+        // When
+        mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
+
+        // Then
+        verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey()));
+
+        verify(mShadeController, atLeastOnce()).collapsePanel();
+
+        verify(mAssistManager).hideAssist();
+
+        verify(mStatusBarService).onNotificationClick(
+                eq(sbn.getKey()), any(NotificationVisibility.class));
+
+        // The content intent should NOT be sent on click.
+        verify(mContentIntent).getIntent();
+        verify(mContentIntent).isActivity();
+        verifyNoMoreInteractions(mContentIntent);
+
+        // Notification should not be cancelled.
+        verify(mEntryManager, never()).performRemoveNotification(eq(sbn));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 5cafc02..4fe18b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -448,7 +448,12 @@
         }
     }
 
-   protected void assertNetworkNameEquals(String expected) {
+    protected void assertNetworkNameEquals(String expected) {
        assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
-   }
+    }
+
+    protected void assertDataNetworkNameEquals(String expected) {
+        assertEquals("Data network name", expected, mNetworkController.getMobileDataNetworkName());
+    }
+
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 68323c9..cd0a0441 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -285,6 +285,15 @@
         testDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT, true, true);
     }
 
+    @Test
+    public void testUpdateDataNetworkName() {
+        setupDefaultSignal();
+        String newDataName = "TestDataName";
+        when(mServiceState.getDataOperatorAlphaShort()).thenReturn(newDataName);
+        updateServiceState();
+        assertDataNetworkNameEquals(newDataName);
+    }
+
     private void testDataActivity(int direction, boolean in, boolean out) {
         updateDataActivity(direction);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index bcbba8b..ac6544e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -20,6 +20,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import android.content.Intent;
 import android.net.ConnectivityManager;
@@ -55,7 +56,7 @@
     @Test
     public void testNoIconWithoutMobile() {
         // Turn off mobile network support.
-        Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
@@ -117,7 +118,7 @@
     @Test
     public void testNoSimlessIconWithoutMobile() {
         // Turn off mobile network support.
-        Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
@@ -253,14 +254,14 @@
 
             // Generate a list of subscriptions we will tell the NetworkController to use.
             SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
-            Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
+            when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
             subscriptions.add(mockSubInfo);
         }
         assertTrue(mNetworkController.hasCorrectMobileControllers(subscriptions));
 
         // Add a subscription that the NetworkController doesn't know about.
         SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
-        Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(notTestSubscription);
+        when(mockSubInfo.getSubscriptionId()).thenReturn(notTestSubscription);
         subscriptions.add(mockSubInfo);
         assertFalse(mNetworkController.hasCorrectMobileControllers(subscriptions));
     }
@@ -290,8 +291,8 @@
             if (i != indexToSkipSubscription) {
                 // Generate a list of subscriptions we will tell the NetworkController to use.
                 SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
-                Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
-                Mockito.when(mockSubInfo.getSimSlotIndex()).thenReturn(testSubscriptions[i]);
+                when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
+                when(mockSubInfo.getSimSlotIndex()).thenReturn(testSubscriptions[i]);
                 subscriptions.add(mockSubInfo);
             }
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
index cd9069a..3edfb56 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
@@ -95,7 +95,7 @@
         triggerConstantsOnChange();
         assertEquals(false, mConstants.requiresTargetingP());
 
-        overrideSetting(SystemUiDeviceConfigFlags.SSIN_REQUIRES_TARGETING_P, "");
+        overrideSetting(SystemUiDeviceConfigFlags.SSIN_REQUIRES_TARGETING_P, null);
         triggerConstantsOnChange();
         assertEquals(true, mConstants.requiresTargetingP());
     }
@@ -223,21 +223,21 @@
 
     private void resetAllDeviceConfigFlags() {
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SSIN_ENABLED, "", false /* makeDefault */);
+                SystemUiDeviceConfigFlags.SSIN_ENABLED, null, false /* makeDefault */);
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SSIN_REQUIRES_TARGETING_P, "", false /* makeDefault */);
+                SystemUiDeviceConfigFlags.SSIN_REQUIRES_TARGETING_P, null, false /* makeDefault */);
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SSIN_MAX_SQUEEZE_REMEASURE_ATTEMPTS, "",
+                SystemUiDeviceConfigFlags.SSIN_MAX_SQUEEZE_REMEASURE_ATTEMPTS, null,
                 false /* makeDefault */);
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SSIN_EDIT_CHOICES_BEFORE_SENDING, "",
+                SystemUiDeviceConfigFlags.SSIN_EDIT_CHOICES_BEFORE_SENDING, null,
                 false /* makeDefault */);
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SSIN_SHOW_IN_HEADS_UP, "", false /* makeDefault */);
+                SystemUiDeviceConfigFlags.SSIN_SHOW_IN_HEADS_UP, null, false /* makeDefault */);
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SSIN_MIN_NUM_SYSTEM_GENERATED_REPLIES, "",
+                SystemUiDeviceConfigFlags.SSIN_MIN_NUM_SYSTEM_GENERATED_REPLIES, null,
                 false /* makeDefault */);
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.SSIN_MAX_NUM_ACTIONS, "", false /* makeDefault */);
+                SystemUiDeviceConfigFlags.SSIN_MAX_NUM_ACTIONS, null, false /* makeDefault */);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeCastController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeCastController.java
index 51149ab..f6b24da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeCastController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeCastController.java
@@ -19,7 +19,8 @@
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.CastController.Callback;
 
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
 
 public class FakeCastController extends BaseLeakChecker<Callback> implements CastController {
     public FakeCastController(LeakCheck test) {
@@ -37,8 +38,8 @@
     }
 
     @Override
-    public Set<CastDevice> getCastDevices() {
-        return null;
+    public List<CastDevice> getCastDevices() {
+        return new ArrayList<>();
     }
 
     @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
index 5385f6d..d5ba381 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
@@ -93,4 +93,9 @@
     public String getMobileDataNetworkName() {
         return "";
     }
+
+    @Override
+    public int getNumberSubscriptions() {
+        return 0;
+    }
 }
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index 1d0b9b6..9f6ba03 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -27,7 +27,7 @@
                  android:allowBackup="false">
 
         <activity android:name=".ConfirmDialog"
-                  android:theme="@android:style/Theme.Material.Light.Dialog.Alert">
+                  android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.DEFAULT"/>
@@ -35,7 +35,7 @@
         </activity>
 
         <activity android:name=".ManageDialog"
-                  android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
+                  android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight"
                   android:noHistory="true"
                   android:excludeFromRecents="true"
                   android:permission="android.permission.NETWORK_SETTINGS"
@@ -44,7 +44,7 @@
 
         <activity android:name=".AlwaysOnDisconnectedDialog"
                   android:label="@string/always_on_disconnected_title"
-                  android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
+                  android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight"
                   android:noHistory="true"
                   android:excludeFromRecents="true"
                   android:permission="android.permission.NETWORK_SETTINGS"
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
index 72ce9c4..989470f 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
@@ -29,6 +29,7 @@
 import android.text.Html;
 import android.text.Html.ImageGetter;
 import android.util.Log;
+import android.util.TypedValue;
 import android.view.View;
 import android.widget.Button;
 import android.widget.TextView;
@@ -111,8 +112,16 @@
     @Override
     public Drawable getDrawable(String source) {
         // Should only reach this when fetching the VPN icon for the warning string.
-        Drawable icon = getDrawable(R.drawable.ic_vpn_dialog);
+        final Drawable icon = getDrawable(R.drawable.ic_vpn_dialog);
         icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
+
+        final TypedValue tv = new TypedValue();
+        if (getTheme().resolveAttribute(android.R.attr.textColorPrimary, tv, true)) {
+            icon.setTint(getColor(tv.resourceId));
+        } else {
+            Log.w(TAG, "Unable to resolve theme color");
+        }
+
         return icon;
     }
 
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
new file mode 100644
index 0000000..b45b910
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="@*android:color/accent_device_default" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.12,7.38c0-2.96-2.41-5.38-5.37-5.38H11v7.94L6.03,4.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-5.97,5.97c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L11,14.06V22h0.75 c2.96,0,5.37-2.41,5.37-5.38c0-1.97-1.06-3.69-2.64-4.62C16.06,11.06,17.12,9.34,17.12,7.38z M15.62,16.62 c0,1.88-1.34,3.45-3.12,3.8v-7.6C14.28,13.17,15.62,14.75,15.62,16.62z M12.5,11.18v-7.6c1.78,0.35,3.12,1.92,3.12,3.8 S14.28,10.83,12.5,11.18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml
index 4d8c366f..b4307a4 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml
@@ -1,30 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,18V11A9,9,0,0,0,3,11v7a2.93,2.93,0,0,0,2.88,3H8V13H4V11a8,8,0,0,1,16,0v2H16v8h2.12A2.93,2.93,0,0,0,21,18ZM7,14v6H5.88A1.92,1.92,0,0,1,4,18V14Zm13,4a1.92,1.92,0,0,1-1.88,2H17V14h3Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,17.78V11c0-4.96-4.04-9-9-9s-9,4.04-9,9v6.78C3,19.56,4.41,21,6.13,21H9v-8H4.5v-2c0-4.13,3.36-7.5,7.5-7.5 s7.5,3.36,7.5,7.5v2H15v8h2.87C19.59,21,21,19.56,21,17.78z M7.5,19.5H6.13c-0.9,0-1.63-0.77-1.63-1.72V14.5h3V19.5z M19.5,17.78 c0,0.95-0.73,1.72-1.63,1.72H16.5v-5h3V17.78z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_expand_more.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_expand_more.xml
index ab6aec5..69b7e0b 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_expand_more.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_expand_more.xml
@@ -1,30 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.35,9.65a0.48 0.48 ,0,0,0-0.7,0L12,15.28,6.35,9.65a0.49 0.49 ,0,0,0-0.7 0.7 L12,16.7l6.35-6.35A0.48 0.48 ,0,0,0,18.35,9.65Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M19.78,8.22c-0.29-0.29-0.77-0.29-1.06,0L12,14.94L5.28,8.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L12,17.06 l7.78-7.78C20.07,8.99,20.07,8.51,19.78,8.22z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_faster_emergency.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_faster_emergency.xml
new file mode 100644
index 0000000..fe238d9
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_faster_emergency.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorError" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M16.5,10.75h-3.25V7.5c0-0.28-0.22-0.5-0.5-0.5h-1.5c-0.28,0-0.5,0.22-0.5,0.5v3.25H7.5c-0.28,0-0.5,0.22-0.5,0.5v1.5 c0,0.28,0.22,0.5,0.5,0.5h3.25v3.25c0,0.28,0.22,0.5,0.5,0.5h1.5c0.28,0,0.5-0.22,0.5-0.5v-3.25h3.25c0.28,0,0.5-0.22,0.5-0.5v-1.5 C17,10.97,16.78,10.75,16.5,10.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18,4.5c0.83,0,1.5,0.67,1.5,1.5v13.5h-15V6c0-0.83,0.67-1.5,1.5-1.5H18 M18,3H6C4.34,3,3,4.34,3,6v15h18V6 C21,4.34,19.66,3,18,3L18,3z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_info_outline_24.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_info_outline_24.xml
index 0e108ca..7f060a4 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_info_outline_24.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_info_outline_24.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,11a0.5 0.5 ,0,0,0-0.5 0.5 v5a0.5 0.5 ,0,0,0,1,0v-5A0.5 0.5 ,0,0,0,12,11Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 7 C 12.4142135624 7 12.75 7.33578643763 12.75 7.75 C 12.75 8.16421356237 12.4142135624 8.5 12 8.5 C 11.5857864376 8.5 11.25 8.16421356237 11.25 7.75 C 11.25 7.33578643763 11.5857864376 7 12 7 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_invert_colors.xml
deleted file mode 100644
index 59e7838..0000000
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_invert_colors.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.62,2.23A1,1,0,0,0,12,2a1.07,1.07,0,0,0-0.63 0.22 C9.48,3.75,4,8.5,4,14a7.89,7.89,0,0,0,8,8,8,8,0,0,0,8-8C20,8.5,14.5,3.73,12.62,2.23ZM12,21a6.92,6.92,0,0,1-7-7C5,9.16,9.89,4.71,12,3Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml
new file mode 100644
index 0000000..a5cef0d
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.25,14.79v1.46c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.46c0.45-0.26,0.75-0.74,0.75-1.29 c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5C10.5,14.05,10.8,14.53,11.25,14.79z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,1C9.79,1,8,2.88,8,5v3H5v10c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V8h-3V5C16,2.88,14.21,1,12,1z M9.5,5 c0-1.33,1.17-2.5,2.5-2.5s2.5,1.17,2.5,2.5v3h-5V5z M17.5,9.5V18c0,0.83-0.67,1.5-1.5,1.5H8c-0.83,0-1.5-0.67-1.5-1.5V9.5H8h8H17.5 z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_bugreport.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_bugreport.xml
new file mode 100644
index 0000000..3cef2ae
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_bugreport.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.75,13.25H6v2.65l-2.56,1.16c-0.38,0.17-0.54,0.62-0.37,0.99c0.12,0.28,0.4,0.44,0.68,0.44c0.1,0,0.21-0.02,0.31-0.07 L6,17.55V21h12v-3.45l1.94,0.88c0.1,0.05,0.21,0.07,0.31,0.07c0.29,0,0.56-0.16,0.68-0.44c0.17-0.38,0-0.82-0.37-0.99L18,15.9 v-2.65h3.25c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H18V11c0-0.46-0.06-0.9-0.15-1.33l2.71-1.23 c0.38-0.17,0.54-0.62,0.37-0.99c-0.17-0.38-0.62-0.54-0.99-0.37l-2.61,1.18c-0.52-1-1.31-1.84-2.28-2.41l0.67-1.84 c0.14-0.39-0.06-0.82-0.45-0.96C14.87,2.9,14.44,3.1,14.3,3.49l-0.63,1.76C13.14,5.09,12.58,5,12,5s-1.14,0.09-1.67,0.24L9.7,3.49 C9.56,3.1,9.12,2.89,8.74,3.03C8.35,3.18,8.14,3.6,8.29,3.99l0.67,1.84C7.98,6.41,7.19,7.25,6.67,8.25L4.06,7.07 c-0.38-0.17-0.82,0-0.99,0.37c-0.17,0.38,0,0.82,0.37,0.99l2.71,1.23C6.06,10.1,6,10.54,6,11v0.75H2.75C2.34,11.75,2,12.09,2,12.5 S2.34,13.25,2.75,13.25z M7.5,11c0-2.48,2.02-4.5,4.5-4.5s4.5,2.02,4.5,4.5v8.5h-9V11z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14,14.75c0-0.41-0.34-0.75-0.75-0.75h-2.5C10.34,14,10,14.34,10,14.75s0.34,0.75,0.75,0.75h2.5 C13.66,15.5,14,15.16,14,14.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M10.75,12h2.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75h-2.5c-0.41,0-0.75,0.34-0.75,0.75S10.34,12,10.75,12z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml
new file mode 100644
index 0000000..0f7a552
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.25,14.79v1.46c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.46c0.45-0.26,0.75-0.74,0.75-1.29 c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5C10.5,14.05,10.8,14.53,11.25,14.79z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19,2.5c1.35,0,2.5,1.18,2.5,2.57c0,0.41,0.34,0.75,0.75,0.75S23,5.48,23,5.07C23,2.86,21.17,1,19,1s-4,1.86-4,4.07V8H5v10 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V8h-2.5V5.07C16.5,3.68,17.65,2.5,19,2.5z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V9.5h11V18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_power_off.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_power_off.xml
new file mode 100644
index 0000000..d0e21a1
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_power_off.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,13c-0.41,0-0.75-0.34-0.75-0.75v-9.5C11.25,2.33,11.59,2,12,2s0.75,0.34,0.75,0.75v9.5C12.75,12.66,12.41,13,12,13z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,21c-4.96,0-9-4.02-9-8.96c0-2.5,1.06-4.9,2.91-6.6c0.31-0.28,0.78-0.26,1.06,0.05C7.25,5.8,7.23,6.27,6.92,6.55 C5.38,7.96,4.5,9.96,4.5,12.04c0,4.11,3.36,7.46,7.5,7.46s7.5-3.34,7.5-7.46c0-2.08-0.88-4.08-2.42-5.49 c-0.3-0.28-0.33-0.75-0.05-1.06c0.28-0.3,0.75-0.33,1.06-0.05c1.85,1.69,2.91,4.1,2.91,6.6C21,16.98,16.96,21,12,21z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
index 04a2c24..3104903 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
@@ -1,57 +1,29 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,21a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2H3A2,2,0,0,0,1,6V19a2,2,0,0,0,2,2ZM2,19V6A1,1,0,0,1,3,5H21a1,1,0,0,1,1,1V19a1,1,0,0,1-1,1H3A1,1,0,0,1,2,19Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9.5 8 L 10.5 8 Q 11 8 11 8.5 L 11 9.5 Q 11 10 10.5 10 L 9.5 10 Q 9 10 9 9.5 L 9 8.5 Q 9 8 9.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5.5 8 L 6.5 8 Q 7 8 7 8.5 L 7 9.5 Q 7 10 6.5 10 L 5.5 10 Q 5 10 5 9.5 L 5 8.5 Q 5 8 5.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13.5 8 L 14.5 8 Q 15 8 15 8.5 L 15 9.5 Q 15 10 14.5 10 L 13.5 10 Q 13 10 13 9.5 L 13 8.5 Q 13 8 13.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9.5 12 L 10.5 12 Q 11 12 11 12.5 L 11 13.5 Q 11 14 10.5 14 L 9.5 14 Q 9 14 9 13.5 L 9 12.5 Q 9 12 9.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5.5 12 L 6.5 12 Q 7 12 7 12.5 L 7 13.5 Q 7 14 6.5 14 L 5.5 14 Q 5 14 5 13.5 L 5 12.5 Q 5 12 5.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13.5 12 L 14.5 12 Q 15 12 15 12.5 L 15 13.5 Q 15 14 14.5 14 L 13.5 14 Q 13 14 13 13.5 L 13 12.5 Q 13 12 13.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17.5 8 L 18.5 8 Q 19 8 19 8.5 L 19 9.5 Q 19 10 18.5 10 L 17.5 10 Q 17 10 17 9.5 L 17 8.5 Q 17 8 17.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17.5 12 L 18.5 12 Q 19 12 19 12.5 L 19 13.5 Q 19 14 18.5 14 L 17.5 14 Q 17 14 17 13.5 L 17 12.5 Q 17 12 17.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M8.5,17h7a0.5 0.5 ,0,0,0,0-1h-7a0.5 0.5 ,0,0,0,0,1Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21.5,19c0,0.27-0.23,0.5-0.5,0.5 H3c-0.27,0-0.5-0.23-0.5-0.5V6c0-0.27,0.23-0.5,0.5-0.5h18c0.27,0,0.5,0.23,0.5,0.5V19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.75,8h0.5C10.66,8,11,8.34,11,8.75v0.5C11,9.66,10.66,10,10.25,10h-0.5C9.34,10,9,9.66,9,9.25v-0.5 C9,8.34,9.34,8,9.75,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5.75,8h0.5C6.66,8,7,8.34,7,8.75v0.5C7,9.66,6.66,10,6.25,10h-0.5C5.34,10,5,9.66,5,9.25v-0.5C5,8.34,5.34,8,5.75,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.75,8h0.5C14.66,8,15,8.34,15,8.75v0.5C15,9.66,14.66,10,14.25,10h-0.5C13.34,10,13,9.66,13,9.25v-0.5 C13,8.34,13.34,8,13.75,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C9.34,14,9,13.66,9,13.25v-0.5 C9,12.34,9.34,12,9.75,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5.75,12h0.5C6.66,12,7,12.34,7,12.75v0.5C7,13.66,6.66,14,6.25,14h-0.5C5.34,14,5,13.66,5,13.25v-0.5 C5,12.34,5.34,12,5.75,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C13.34,14,13,13.66,13,13.25v-0.5 C13,12.34,13.34,12,13.75,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.75,8h0.5C18.66,8,19,8.34,19,8.75v0.5C19,9.66,18.66,10,18.25,10h-0.5C17.34,10,17,9.66,17,9.25v-0.5 C17,8.34,17.34,8,17.75,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C17.34,14,17,13.66,17,13.25v-0.5 C17,12.34,17.34,12,17.75,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15.5,17h-7C8.22,17,8,16.78,8,16.5S8.22,16,8.5,16h7c0.28,0,0.5,0.22,0.5,0.5S15.78,17,15.5,17z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml
index f9b0f6c..87edcc4 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml
@@ -1,30 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,21H7.18L20.41,7.77a2,2,0,0,0,0-2.83L19.06,3.59a2,2,0,0,0-2.83,0L3,16.82ZM16.94,4.3a1,1,0,0,1,1.41,0l1.36,1.35a1,1,0,0,1,0.29 0.7 ,1,1,0,0,1-0.3 0.71 l-2,2L15,6.26ZM4,17.23,14.26,7,17,9.74,6.77,20H4Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.41,4.94l-1.35-1.35c-0.39-0.39-0.9-0.58-1.41-0.58s-1.03,0.2-1.41,0.58L3,16.82V21h4.18L20.41,7.77 C21.2,6.99,21.2,5.72,20.41,4.94z M6.56,19.5H4.5v-2.06l9.94-9.94l2.06,2.06L6.56,19.5z M19.35,6.71L17.56,8.5L15.5,6.44l1.79-1.79 c0.13-0.13,0.28-0.15,0.35-0.15S17.87,4.52,18,4.65l1.36,1.36c0.12,0.12,0.15,0.25,0.15,0.35S19.48,6.58,19.35,6.71z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M10.75,19.5c-0.41,0-0.75,0.34-0.75,0.75S10.34,21,10.75,21h9.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H10.75z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml
index ac47a86..e3534d6 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml
@@ -1,30 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,18.06a3.22,3.22,0,0,0-5.49-2.28L13.26,18A17.13,17.13,0,0,1,9.2,15.1,18.37,18.37,0,0,1,6,10.69L8.22,8.48A3.19,3.19,0,0,0,9,5.33,3.24,3.24,0,0,0,6,3H3.49s0,0,0,0L3.39,3l-0.1,0-0.07 0.05 -0.08 0.06 a0.35 0.35 ,0,0,0-0.05 0.08 A0.35 0.35 ,0,0,0,3,3.3a0.36 0.36 ,0,0,0,0,0.1 0.24 0.24,0,0,0,0,0.08v0H3a19.11,19.11,0,0,0,5.5,12.3,18.38,18.38,0,0,0,12,5.2h0a0.58 0.58 ,0,0,0,0.19,0,0.18 0.18 ,0,0,0,0.07-0.05l0.09-0.06,0-0.07a0.35 0.35 ,0,0,0,0.05-0.08 0.29 0.29,0,0,0,0-0.1s0-0.05,0-0.08h0ZM4.06,4H6A2.22,2.22,0,0,1,7.52,7.78l-2,2A18.05,18.05,0,0,1,4.06,4ZM14.21,18.5l2-2A2.22,2.22,0,0,1,20,18.06V20A17.64,17.64,0,0,1,14.21,18.5Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M9.71,4.56C9.28,3.06,7.89,2,6.32,2L3,1.99l0.05,0.8c0.29,4.81,2.32,9.34,5.71,12.77c3.35,3.26,7.77,5.18,12.45,5.41 L21.99,21v-3.31c0-1.56-1.04-2.96-2.54-3.39c-1.24-0.36-2.58-0.02-3.5,0.89l-2.19,2.19c-1.43-0.77-2.76-1.74-3.95-2.89 c-1.27-1.28-2.33-2.73-3.16-4.3l2.16-2.16C9.72,7.13,10.06,5.8,9.71,4.56z M17.01,16.25c0.53-0.53,1.3-0.73,2.02-0.51 c0.86,0.25,1.46,1.06,1.46,1.96v1.72c-1.84-0.17-3.62-0.62-5.3-1.34L17.01,16.25z M7.75,6.98L5.97,8.76 C5.26,7.09,4.8,5.32,4.61,3.49l1.71,0c0.9,0,1.7,0.61,1.95,1.48C8.47,5.69,8.27,6.45,7.75,6.98z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_airplane.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_airplane.xml
new file mode 100644
index 0000000..0908925
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_airplane.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M22,15.89v-2.57c0-1.1-0.65-2.09-1.67-2.53L14.5,8.28V3.75c0-1.38-1.12-2.5-2.5-2.5s-2.5,1.12-2.5,2.5v4.53l-5.83,2.51 C2.65,11.22,2,12.22,2,13.32v2.57l7.5-1.28v3.03l-1.47,1.17C7.38,19.34,7,20.12,7,20.96v1.33l4.96-0.3L17,22.3v-1.33 c0-0.84-0.38-1.62-1.03-2.15l-1.47-1.17v-3.03L22,15.89z M15.03,19.98c0.23,0.18,0.38,0.44,0.44,0.72l-3.52-0.2l-3.43,0.2 c0.06-0.28,0.21-0.53,0.44-0.72L11,18.36v-5.53l-7.5,1.28v-0.79c0-0.5,0.3-0.95,0.76-1.15L11,9.27V3.75c0-0.55,0.45-1,1-1 s1,0.45,1,1v5.52l6.74,2.9c0.46,0.2,0.76,0.65,0.76,1.15v0.79L13,12.83v5.53L15.03,19.98z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml
new file mode 100644
index 0000000..239893d
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.75,6.5v4.75H7.5c0.41,0,0.75-0.34,0.75-0.75S7.91,9.75,7.5,9.75H5.39l4.5-4.22c0.89-0.84,2.27-0.82,3.13,0.05l4.94,4.95 c0.29,0.29,0.77,0.29,1.06,0c0.29-0.29,0.29-0.77,0-1.06l-4.94-4.95c-1.44-1.44-3.73-1.48-5.22-0.08L4.25,8.77V6.5 c0-0.41-0.34-0.75-0.75-0.75S2.75,6.09,2.75,6.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.25,17.5v-4.75H16.5c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h2.11l-4.5,4.22c-0.89,0.84-2.27,0.82-3.13-0.05 l-4.94-4.95c-0.29-0.29-0.77-0.29-1.06,0c-0.29,0.29-0.29,0.77,0,1.06l4.94,4.95c0.74,0.74,1.69,1.11,2.65,1.11 c0.92,0,1.84-0.34,2.57-1.02l4.62-4.33v2.27c0,0.41,0.34,0.75,0.75,0.75S21.25,17.91,21.25,17.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
new file mode 100644
index 0000000..ba0dfc6
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.12,7.38c0-2.96-2.41-5.38-5.37-5.38H11v7.94L6.03,4.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-5.97,5.97c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L11,14.06V22h0.75 c2.96,0,5.37-2.41,5.37-5.38c0-1.97-1.06-3.69-2.64-4.62C16.06,11.06,17.12,9.34,17.12,7.38z M15.62,16.62 c0,1.88-1.34,3.45-3.12,3.8v-7.6C14.28,13.17,15.62,14.75,15.62,16.62z M12.5,11.18v-7.6c1.78,0.35,3.12,1.92,3.12,3.8 S14.28,10.83,12.5,11.18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_dnd.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_dnd.xml
new file mode 100644
index 0000000..0c309c8
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_dnd.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,22c5.52,0,10-4.48,10-10c0-5.52-4.48-10-10-10S2,6.48,2,12C2,17.52,6.48,22,12,22z M12,3.5c4.69,0,8.5,3.81,8.5,8.5 c0,4.69-3.81,8.5-8.5,8.5S3.5,16.69,3.5,12C3.5,7.31,7.31,3.5,12,3.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.75,12.75h10.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H6.75C6.34,11.25,6,11.59,6,12S6.34,12.75,6.75,12.75z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_flashlight.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_flashlight.xml
new file mode 100644
index 0000000..9c21da6
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_flashlight.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11,22h2c1.1,0,2-0.9,2-2V10c1.95-1.17,3-3.5,3-6V3H6v1c0,2.5,1.05,4.83,3,6v10C9,21.1,9.9,22,11,22z M16.48,4.5 C16.45,5.03,16.35,5.53,16.2,6H7.8C7.65,5.53,7.55,5.03,7.52,4.5H16.48z M8.51,7.5h6.99c-0.35,0.5-0.77,0.92-1.26,1.21L13.5,9.15 V20c0,0.28-0.22,0.5-0.5,0.5h-2c-0.28,0-0.5-0.22-0.5-0.5V9.15L9.77,8.71C9.28,8.42,8.85,8,8.51,7.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 13 C 12.5522847498 13 13 13.4477152502 13 14 C 13 14.5522847498 12.5522847498 15 12 15 C 11.4477152502 15 11 14.5522847498 11 14 C 11 13.4477152502 11.4477152502 13 12 13 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_night_display_on.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_night_display_on.xml
index 8ee7e2f..fa25381 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_night_display_on.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_night_display_on.xml
@@ -1,30 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22.36,15.7a0.51 0.51 ,0,0,0-0.51-0.22,11.59,11.59,0,0,1-2.07 0.2 A11.5,11.5,0,0,1,8.31,4.17a10.91,10.91,0,0,1,0.2-2.08 0.51 0.51,0,0,0-0.22-0.51 0.5 0.5,0,0,0-0.55,0A10.57,10.57,0,1,0,22.36,16.25 0.5 0.5,0,0,0,22.36,15.7ZM13.55,20A9.59,9.59,0,0,1,7.36,3.12a9.34,9.34,0,0,0-0.05,1A12.46,12.46,0,0,0,20.82,16.63,9.49,9.49,0,0,1,13.55,20Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M22.88,16.06c-0.17-0.25-0.46-0.38-0.76-0.32c-0.75,0.14-1.46,0.2-2.15,0.2c-6.57,0-11.91-5.34-11.91-11.91 c0-0.69,0.07-1.4,0.2-2.15c0.05-0.3-0.07-0.59-0.32-0.76c-0.25-0.17-0.58-0.17-0.83,0C3.91,3.24,2,6.79,2,10.62 C2,16.89,7.11,22,13.38,22c3.83,0,7.38-1.91,9.49-5.11C23.04,16.64,23.04,16.31,22.88,16.06z M13.38,20.5 c-5.45,0-9.88-4.43-9.88-9.88c0-2.73,1.12-5.3,3.07-7.15C6.56,3.66,6.56,3.85,6.56,4.04c0,7.58,6.36,13.75,13.98,13.39 C18.69,19.38,16.12,20.5,13.38,20.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_restart.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_restart.xml
new file mode 100644
index 0000000..d4fdadd
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_restart.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12.03,2.96c-0.29-0.29-0.77-0.29-1.06,0L7.94,6l3.04,3.04c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0.29-0.29,0.29-0.77,0-1.06l-1.37-1.37C11.1,6.52,11.55,6.47,12,6.47c3.58,0,6.5,2.92,6.5,6.5c0,3.05-2.07,5.66-5.04,6.33 c-0.4,0.09-0.66,0.5-0.56,0.9c0.08,0.35,0.39,0.58,0.73,0.58c0.06,0,0.11-0.01,0.17-0.02c3.65-0.84,6.21-4.04,6.21-7.8 c0-4.41-3.59-8-8-8c-0.33,0-0.65,0.03-0.98,0.07l1.01-1.01C12.33,3.73,12.33,3.26,12.03,2.96z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M7,7.66C6.69,7.39,6.22,7.42,5.95,7.74C4.69,9.19,4,11.05,4,12.97c0,3.75,2.55,6.96,6.21,7.8 c0.06,0.01,0.11,0.02,0.17,0.02c0.34,0,0.65-0.24,0.73-0.58c0.09-0.4-0.16-0.81-0.56-0.9c-2.97-0.68-5.04-3.29-5.04-6.33 c0-1.56,0.56-3.07,1.58-4.25C7.35,8.41,7.32,7.93,7,7.66z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_screenshot.xml
new file mode 100644
index 0000000..7b07000
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_screenshot.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M15,22c1.66,0,3-1.34,3-3V5c0-1.66-1.34-3-3-3H9C7.34,2,6,3.34,6,5v14c0,1.66,1.34,3,3,3H15z M7.5,6.5h9v11h-9V6.5z M9,3.5 h6c0.83,0,1.5,0.67,1.5,1.5h-9C7.5,4.17,8.17,3.5,9,3.5z M7.5,19h9c0,0.83-0.67,1.5-1.5,1.5H9C8.17,20.5,7.5,19.83,7.5,19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13,8.25c0-0.41-0.34-0.75-0.75-0.75H8.5v3.75C8.5,11.66,8.84,12,9.25,12S10,11.66,10,11.25V9h2.25 C12.66,9,13,8.66,13,8.25z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14.75,12C14.34,12,14,12.34,14,12.75V15h-2.25C11.34,15,11,15.34,11,15.75s0.34,0.75,0.75,0.75h3.75v-3.75 C15.5,12.34,15.16,12,14.75,12z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_settings_bluetooth.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
new file mode 100644
index 0000000..ba0dfc6
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.12,7.38c0-2.96-2.41-5.38-5.37-5.38H11v7.94L6.03,4.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-5.97,5.97c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L11,14.06V22h0.75 c2.96,0,5.37-2.41,5.37-5.38c0-1.97-1.06-3.69-2.64-4.62C16.06,11.06,17.12,9.34,17.12,7.38z M15.62,16.62 c0,1.88-1.34,3.45-3.12,3.8v-7.6C14.28,13.17,15.62,14.75,15.62,16.62z M12.5,11.18v-7.6c1.78,0.35,3.12,1.92,3.12,3.8 S14.28,10.83,12.5,11.18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_location.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_location.xml
index 25535c7..f16fbc1 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_location.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_location.xml
@@ -1,33 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,21.5s7-5.34,7-11.25A7.13,7.13,0,0,0,12,3a7.13,7.13,0,0,0-7,7.25C5,16.16,12,21.5,12,21.5ZM12,4a6.13,6.13,0,0,1,6,6.25c0,4.37-4.37,8.54-6,10-1.63-1.4-6-5.57-6-9.95A6.13,6.13,0,0,1,12,4Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-5,0a2,2,0,1,1,2,2A2,2,0,0,1,10,10Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,21.5c0,0,7-5.34,7-11.25c0-4-3.13-7.25-7-7.25c-3.87,0-7,3.25-7,7.25C5,16.16,12,21.5,12,21.5z M12,4.5 c3.03,0,5.5,2.58,5.5,5.75c0,3.91-3.74,7.72-5.51,9.29C9.9,17.68,6.5,13.89,6.5,10.25C6.5,7.08,8.97,4.5,12,4.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15,10c0-1.66-1.34-3-3-3c-1.66,0-3,1.34-3,3c0,1.66,1.34,3,3,3C13.66,13,15,11.66,15,10z M10.5,10 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5s-0.67,1.5-1.5,1.5S10.5,10.83,10.5,10z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_0.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_0.xml
index b73fcb2..6afdbcb 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_0.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_0.xml
@@ -1,51 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M2.15,8.85a0.48 0.48 ,0,0,0,0.7,0,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0A0.48 0.48 ,0,0,0,2.15,8.85Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.08,5.08,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53c-1.41,0-2.73,0.54-3.73,1.53 c-0.29,0.29-0.77,0.29-1.06-0.01c-0.29-0.29-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96c1.8,0,3.5,0.7,4.78,1.96 c0.29,0.29,0.3,0.77,0.01,1.06C16.64,14.93,16.45,15,16.25,15z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_1.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_1.xml
index 69b1bd8..20baa63 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_1.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_1.xml
@@ -1,48 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.85,8.15a13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0A0.48 0.48 ,0,0,0,21.85,8.15Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.08,5.08,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43 c-0.29,0.29-0.77,0.29-1.06,0s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53c-1.41,0-2.73,0.54-3.73,1.53 c-0.29,0.29-0.77,0.29-1.06-0.01c-0.29-0.29-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96c1.8,0,3.5,0.7,4.78,1.96 c0.29,0.29,0.3,0.77,0.01,1.06C16.64,14.93,16.45,15,16.25,15z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_2.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_2.xml
index 353fccb..b50bdde 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_2.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_2.xml
@@ -1,45 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.85,8.15a13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0A0.48 0.48 ,0,0,0,21.85,8.15Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.07,5.07,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53s-2.73,0.54-3.73,1.53c-0.29,0.29-0.77,0.29-1.06-0.01 s-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96s3.5,0.7,4.78,1.96c0.29,0.29,0.3,0.77,0.01,1.06 C16.64,14.93,16.45,15,16.25,15z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_3.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_3.xml
index a8bade5..9398c69 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_3.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_3.xml
@@ -1,42 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.07,5.07,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53s-2.73,0.54-3.73,1.53c-0.29,0.29-0.77,0.29-1.06-0.01 s-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96s3.5,0.7,4.78,1.96c0.29,0.29,0.3,0.77,0.01,1.06 C16.64,14.93,16.45,15,16.25,15z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_4.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_4.xml
index a4afffd..c66a406 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_4.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_wifi_signal_4.xml
@@ -1,39 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.08,5.08,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53c-1.41,0-2.73,0.54-3.73,1.53 c-0.29,0.29-0.77,0.29-1.06-0.01c-0.29-0.29-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96c1.8,0,3.5,0.7,4.78,1.96 c0.29,0.29,0.3,0.77,0.01,1.06C16.64,14.93,16.45,15,16.25,15z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_empty_recents.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_empty_recents.xml
deleted file mode 100644
index 7e363f6..0000000
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_empty_recents.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17,18V6c0-1.1-0.9-2-2-2H9C7.9,4,7,4.9,7,6v12c0,1.1,0.9,2,2,2h6C16.1,20,17,19.1,17,18z M8.5,18V6 c0-0.28,0.22-0.5,0.5-0.5h6c0.28,0,0.5,0.22,0.5,0.5v12c0,0.28-0.22,0.5-0.5,0.5H9C8.72,18.5,8.5,18.28,8.5,18z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,7h-2c-0.55,0-1,0.45-1,1v8c0,0.55,0.45,1,1,1h2c0.55,0,1-0.45,1-1V8C22,7.45,21.55,7,21,7z M20.5,15.5h-1v-7h1V15.5z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M5,17c0.55,0,1-0.45,1-1V8c0-0.55-0.45-1-1-1H3C2.45,7,2,7.45,2,8v8c0,0.55,0.45,1,1,1H5z M3.5,8.5h1v7h-1V8.5z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_airplanemode_active.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_airplanemode_active.xml
new file mode 100644
index 0000000..6212a51
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_airplanemode_active.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M22,15.89v-2.57c0-1.1-0.65-2.09-1.67-2.53L14.5,8.28V3.75c0-1.38-1.12-2.5-2.5-2.5s-2.5,1.12-2.5,2.5v4.53l-5.83,2.51 C2.65,11.22,2,12.22,2,13.32v2.57l7.5-1.28v3.03l-1.47,1.17C7.38,19.34,7,20.12,7,20.96v1.33l4.96-0.3L17,22.3v-1.33 c0-0.84-0.38-1.62-1.03-2.15l-1.47-1.17v-3.03L22,15.89z M15.03,19.98c0.23,0.18,0.38,0.44,0.44,0.72l-3.52-0.2l-3.43,0.2 c0.06-0.28,0.21-0.53,0.44-0.72L11,18.36v-5.53l-7.5,1.28v-0.79c0-0.5,0.3-0.95,0.76-1.15L11,9.27V3.75c0-0.55,0.45-1,1-1 s1,0.45,1,1v5.52l6.74,2.9c0.46,0.2,0.76,0.65,0.76,1.15v0.79L13,12.83v5.53L15.03,19.98z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml
index dbac48d..d11d2c2 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml
@@ -1,54 +1,28 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M6,4A2,2,0,0,0,6,8H7.5A0.5 0.5 ,0,0,0,8,7.5V6A2,2,0,0,0,6,4Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,8h1.5a0.5 0.5 ,0,0,0,0.5-0.5V6a2,2,0,1,0-2,2Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M20,6a2,2,0,1,0-2,2h1.5a0.5 0.5 ,0,0,0,0.5-0.5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M6,14H7.5a0.5 0.5 ,0,0,0,0.5-0.5V12a2,2,0,1,0-2,2Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,14h1.5a0.5 0.5 ,0,0,0,0.5-0.5V12a2,2,0,1,0-2,2Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M20,12a2,2,0,1,0-2,2h1.5a0.5 0.5 ,0,0,0,0.5-0.5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M6,20H7.5a0.5 0.5 ,0,0,0,0.5-0.5V18a2,2,0,1,0-2,2Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,20h1.5a0.5 0.5 ,0,0,0,0.5-0.5V18a2,2,0,1,0-2,2Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M20,18a2,2,0,1,0-2,2h1.5a0.5 0.5 ,0,0,0,0.5-0.5Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 6 4 C 7.10456949966 4 8 4.89543050034 8 6 C 8 7.10456949966 7.10456949966 8 6 8 C 4.89543050034 8 4 7.10456949966 4 6 C 4 4.89543050034 4.89543050034 4 6 4 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 4 C 13.1045694997 4 14 4.89543050034 14 6 C 14 7.10456949966 13.1045694997 8 12 8 C 10.8954305003 8 10 7.10456949966 10 6 C 10 4.89543050034 10.8954305003 4 12 4 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 18 4 C 19.1045694997 4 20 4.89543050034 20 6 C 20 7.10456949966 19.1045694997 8 18 8 C 16.8954305003 8 16 7.10456949966 16 6 C 16 4.89543050034 16.8954305003 4 18 4 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 6 10 C 7.10456949966 10 8 10.8954305003 8 12 C 8 13.1045694997 7.10456949966 14 6 14 C 4.89543050034 14 4 13.1045694997 4 12 C 4 10.8954305003 4.89543050034 10 6 10 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 10 C 13.1045694997 10 14 10.8954305003 14 12 C 14 13.1045694997 13.1045694997 14 12 14 C 10.8954305003 14 10 13.1045694997 10 12 C 10 10.8954305003 10.8954305003 10 12 10 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 18 10 C 19.1045694997 10 20 10.8954305003 20 12 C 20 13.1045694997 19.1045694997 14 18 14 C 16.8954305003 14 16 13.1045694997 16 12 C 16 10.8954305003 16.8954305003 10 18 10 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 6 16 C 7.10456949966 16 8 16.8954305003 8 18 C 8 19.1045694997 7.10456949966 20 6 20 C 4.89543050034 20 4 19.1045694997 4 18 C 4 16.8954305003 4.89543050034 16 6 16 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 16 C 13.1045694997 16 14 16.8954305003 14 18 C 14 19.1045694997 13.1045694997 20 12 20 C 10.8954305003 20 10 19.1045694997 10 18 C 10 16.8954305003 10.8954305003 16 12 16 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 18 16 C 19.1045694997 16 20 16.8954305003 20 18 C 20 19.1045694997 19.1045694997 20 18 20 C 16.8954305003 20 16 19.1045694997 16 18 C 16 16.8954305003 16.8954305003 16 18 16 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml
new file mode 100644
index 0000000..ccbaecd
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,7a0.76 0.76 ,0,0,0-0.75 0.75 v3.5H7.75a0.75 0.75 ,0,0,0,0,1.5h3.5v3.5a0.75 0.75 ,0,0,0,1.5,0v-3.5h3.5a0.75 0.75 ,0,0,0,0-1.5h-3.5V7.75A0.76 0.76 ,0,0,0,12,7Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
index a407bd6..c64995c 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M2,16.5A2.5,2.5,0,0,0,4.5,19h2a0.5 0.5 ,0,0,0,0-1h-2A1.5,1.5,0,0,1,3,16.5v-9A1.5,1.5,0,0,1,4.5,6h17a0.5 0.5 ,0,0,0,0-1H4.5A2.5,2.5,0,0,0,2,7.5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M14,16a3,3,0,1,0-3,3A3,3,0,0,0,14,16ZM9,16a2,2,0,1,1,2,2A2,2,0,0,1,9,16Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M22,17V10a2,2,0,0,0-2-2H17a2,2,0,0,0-2,2v7a2,2,0,0,0,2,2h3A2,2,0,0,0,22,17Zm-6,0V10a1,1,0,0,1,1-1h3a1,1,0,0,1,1,1v7a1,1,0,0,1-1,1H17A1,1,0,0,1,16,17Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M7.25,18.25c0-0.41-0.34-0.75-0.75-0.75H3V8.25C3,7.01,4.01,6,5.25,6h16C21.66,6,22,5.66,22,5.25S21.66,4.5,21.25,4.5h-16 C3.18,4.5,1.5,6.18,1.5,8.25V19h5C6.91,19,7.25,18.66,7.25,18.25z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14,16c0-1.66-1.34-3-3-3s-3,1.34-3,3s1.34,3,3,3S14,17.66,14,16z M9.5,16c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5 s-0.67,1.5-1.5,1.5S9.5,16.83,9.5,16z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20,19c1.1,0,2-0.9,2-2v-7c0-1.1-0.9-2-2-2h-3c-1.1,0-2,0.9-2,2v7c0,1.1,0.9,2,2,2H20z M16.5,17v-7 c0-0.28,0.22-0.5,0.5-0.5h3c0.28,0,0.5,0.22,0.5,0.5v7c0,0.28-0.22,0.5-0.5,0.5h-3C16.72,17.5,16.5,17.28,16.5,17z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml
index c906847..3945ce5 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,22h0A10,10,0,0,0,22,12v0A10,10,0,1,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M8.62,9.65a0.5 0.5 ,0,0,0,0.61-0.37,2.94,2.94,0,0,1,5-1.41A2.64,2.64,0,0,1,15,10a2.27,2.27,0,0,1-1,1.69l-0.44 0.26 a3.21,3.21,0,0,0-1.91,2.47A0.49 0.49 ,0,0,0,12,15h0.08a0.5 0.5 ,0,0,0,0.49-0.42A2.25,2.25,0,0,1,14,12.81l0.5-0.29A3.27,3.27,0,0,0,16,10.09,3.62,3.62,0,0,0,14.9,7.16a4,4,0,0,0-5.6,0A4.06,4.06,0,0,0,8.25,9.05 0.5 0.5,0,0,0,8.62,9.65Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 16.25 C 12.4142135624 16.25 12.75 16.5857864376 12.75 17 C 12.75 17.4142135624 12.4142135624 17.75 12 17.75 C 11.5857864376 17.75 11.25 17.4142135624 11.25 17 C 11.25 16.5857864376 11.5857864376 16.25 12 16.25 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,22c0,0,0.01,0,0.01,0c5.51,0,9.98-4.46,9.99-9.98c0-0.01,0-0.01,0-0.02c0-5.52-4.48-10-10-10S2,6.48,2,12 S6.48,22,12,22z M12,3.5c4.69,0,8.5,3.81,8.5,8.52c-0.01,4.68-3.81,8.48-8.5,8.48c-4.69,0-8.5-3.81-8.5-8.5 C3.5,7.31,7.31,3.5,12,3.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8.57,9.89c0.4,0.1,0.81-0.15,0.9-0.56c0.12-0.5,0.36-0.94,0.71-1.29c1.06-1.06,2.78-1.06,3.84,0 c0.53,0.53,0.79,1.23,0.72,1.92c-0.06,0.62-0.39,1.15-0.92,1.5c-0.17,0.11-0.35,0.19-0.52,0.27c-0.7,0.33-1.67,0.78-1.93,2.37 c-0.07,0.41,0.21,0.8,0.61,0.86C12.02,14.99,12.06,15,12.1,15c0.36,0,0.68-0.26,0.74-0.62c0.14-0.82,0.48-0.98,1.09-1.26 c0.25-0.11,0.49-0.23,0.72-0.38c0.91-0.6,1.48-1.53,1.58-2.61c0.12-1.14-0.31-2.28-1.15-3.13c-1.64-1.64-4.32-1.64-5.96,0 c-0.54,0.54-0.93,1.24-1.11,2C7.92,9.39,8.16,9.8,8.57,9.89z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 16.5 C 12.5522847498 16.5 13 16.9477152502 13 17.5 C 13 18.0522847498 12.5522847498 18.5 12 18.5 C 11.4477152502 18.5 11 18.0522847498 11 17.5 C 11 16.9477152502 11.4477152502 16.5 12 16.5 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml
index f3419d4..948e2ab 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M15,22a3,3,0,0,0,3-3V5a3,3,0,0,0-3-3H9A3,3,0,0,0,6,5V19a3,3,0,0,0,3,3ZM7,6H17V18H7ZM9,3h6a2,2,0,0,1,2,2H7A2,2,0,0,1,9,3ZM7,19H17a2,2,0,0,1-2,2H9A2,2,0,0,1,7,19Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,10.5a0.5 0.5 ,0,0,0-0.5 0.5 v4.5a0.5 0.5 ,0,0,0,1,0V11A0.5 0.5 ,0,0,0,12,10.5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 8 C 12.4142135624 8 12.75 8.33578643763 12.75 8.75 C 12.75 9.16421356237 12.4142135624 9.5 12 9.5 C 11.5857864376 9.5 11.25 9.16421356237 11.25 8.75 C 11.25 8.33578643763 11.5857864376 8 12 8 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M15,22c1.66,0,3-1.34,3-3V5c0-1.66-1.34-3-3-3H9C7.34,2,6,3.34,6,5v14c0,1.66,1.34,3,3,3H15z M7.5,6.5h9v11h-9V6.5z M9,3.5 h6c0.83,0,1.5,0.67,1.5,1.5h-9C7.5,4.17,8.17,3.5,9,3.5z M7.5,19h9c0,0.83-0.67,1.5-1.5,1.5H9C8.17,20.5,7.5,19.83,7.5,19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,11.5c-0.41,0-0.75,0.34-0.75,0.75v3c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-3 C12.75,11.84,12.41,11.5,12,11.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 8 C 12.5522847498 8 13 8.44771525017 13 9 C 13 9.55228474983 12.5522847498 10 12 10 C 11.4477152502 10 11 9.55228474983 11 9 C 11 8.44771525017 11.4477152502 8 12 8 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml
index 8a8ddec..80a40b2 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -1,42 +1,24 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M21,5.35A0.51 0.51 ,0,0,0,20.37,5,37.25,37.25,0,0,1,3.63,5,0.51 0.51 ,0,0,0,3,5.35 0.51 0.51,0,0,0,3.37,6,32.05,32.05,0,0,0,9,6.87V20a0.5 0.5 ,0,0,0,1,0V13.5h4V20a0.5 0.5 ,0,0,0,1,0V6.87A32.05,32.05,0,0,0,20.63,6,0.51 0.51 ,0,0,0,21,5.35Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 1 C 13.1045694997 1 14 1.89543050034 14 3 C 14 4.10456949966 13.1045694997 5 12 5 C 10.8954305003 5 10 4.10456949966 10 3 C 10 1.89543050034 10.8954305003 1 12 1 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M3.03,5.54c-0.11,0.4,0.13,0.81,0.53,0.92C5.24,6.91,7.07,7.2,9,7.35v8.15v3.75C9,19.66,9.34,20,9.75,20 s0.75-0.34,0.75-0.75V15.5c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5v3.75c0,0.41,0.34,0.75,0.75,0.75S15,19.66,15,19.25V15.5V7.35 c1.93-0.15,3.76-0.44,5.44-0.89c0.4-0.11,0.64-0.52,0.53-0.92c-0.11-0.4-0.51-0.64-0.92-0.53C17.64,5.66,14.93,5.98,12,5.98 S6.36,5.66,3.94,5.01C3.54,4.9,3.13,5.14,3.03,5.54z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 1 C 13.1045694997 1 14 1.89543050034 14 3 C 14 4.10456949966 13.1045694997 5 12 5 C 10.8954305003 5 10 4.10456949966 10 3 C 10 1.89543050034 10.8954305003 1 12 1 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml
index 01fc4b9..5360e9b 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -1,33 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22Zm0-1a9,9,0,0,1-7-3.31,10.37,10.37,0,0,1,13.94,0A9,9,0,0,1,12,21ZM3,12a9,9,0,0,1,18,0,8.88,8.88,0,0,1-1.45,4.88,11.35,11.35,0,0,0-15.1,0A8.83,8.83,0,0,1,3,12Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M15.5,9.5A3.5,3.5,0,1,0,12,13,3.5,3.5,0,0,0,15.5,9.5Zm-6,0A2.5,2.5,0,1,1,12,12,2.5,2.5,0,0,1,9.5,9.5Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,6c-1.93,0-3.5,1.57-3.5,3.5S10.07,13,12,13s3.5-1.57,3.5-3.5S13.93,6,12,6z M12,11.5c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2 c1.1,0,2,0.9,2,2C14,10.6,13.1,11.5,12,11.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20.5c-2.57,0-4.86-1.15-6.42-2.95 C7.25,16.21,9.45,15.5,12,15.5c2.55,0,4.75,0.71,6.42,2.05C16.86,19.35,14.57,20.5,12,20.5z M12,14c-2.82,0-5.38,0.82-7.3,2.33 C3.94,15.06,3.5,13.58,3.5,12c0-4.69,3.81-8.5,8.5-8.5c4.69,0,8.5,3.81,8.5,8.5c0,1.58-0.44,3.06-1.2,4.33 C17.38,14.82,14.82,14,12,14z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml
index b43923f..bd700c4 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -1,30 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M14,4a1,1,0,0,0-1-1H11a1,1,0,0,0-1,1H9A2,2,0,0,0,7,6V19a2,2,0,0,0,2,2h6a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M14,4c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9C7.34,4,6,5.34,6,7v12c0,1.66,1.34,3,3,3h6c1.66,0,3-1.34,3-3V7 c0-1.66-1.34-3-3-3H14z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_delete.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_delete.xml
new file mode 100644
index 0000000..c66f918
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_delete.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M9,20h6c1.66,0,3-1.34,3-3V6h0.5c0.41,0,0.75-0.34,0.75-0.75S18.91,4.5,18.5,4.5H18h-3l-1-1h-4l-1,1H6H5.5 c-0.41,0-0.75,0.34-0.75,0.75S5.09,6,5.5,6H6v11C6,18.66,7.34,20,9,20z M16.5,6v11c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V6H16.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.97,16c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v6.5 C13.22,15.66,13.55,16,13.97,16z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M10,16c0.41,0,0.75-0.34,0.75-0.75v-6.5C10.75,8.34,10.41,8,10,8S9.25,8.34,9.25,8.75v6.5C9.25,15.66,9.59,16,10,16z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml
index 580271b..1180633 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -1,33 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M3.41,14.72A2,2,0,0,1,4,16.14V18a2,2,0,0,0,2,2H7.86a2,2,0,0,1,1.42 0.59 l1.31,1.31a2,2,0,0,0,2.82,0l1.31-1.31A2,2,0,0,1,16.14,20H18a2,2,0,0,0,2-2V16.14a2,2,0,0,1,0.59-1.42l1.31-1.31a2,2,0,0,0,0-2.82L20.59,9.28A2,2,0,0,1,20,7.86V6a2,2,0,0,0-2-2H16.14a2,2,0,0,1-1.42-0.59L13.41,2.1a2,2,0,0,0-2.82,0L9.28,3.41A2,2,0,0,1,7.86,4H6A2,2,0,0,0,4,6V7.86a2,2,0,0,1-0.59,1.42L2.1,10.59a2,2,0,0,0,0,2.82Zm-0.6-3.43L4.12,10A3,3,0,0,0,5,7.86V6A1,1,0,0,1,6,5H7.86A3,3,0,0,0,10,4.12l1.31-1.31a1,1,0,0,1,1.42,0L14,4.12A3,3,0,0,0,16.14,5H18a1,1,0,0,1,1,1V7.86A3,3,0,0,0,19.88,10l1.31,1.31a1,1,0,0,1,0,1.42L19.88,14A3,3,0,0,0,19,16.14V18a1,1,0,0,1-1,1H16.14a3,3,0,0,0-2.12 0.88 l-1.31,1.31a1,1,0,0,1-1.42,0L10,19.88A3,3,0,0,0,7.86,19H6a1,1,0,0,1-1-1V16.14A3,3,0,0,0,4.12,14L2.81,12.71a1,1,0,0,1,0-1.42Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M17,12a5,5,0,0,0-5-5V17A5,5,0,0,0,17,12Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17,12c0-2.76-2.24-5-5-5v10C14.76,17,17,14.76,17,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M4,15.31V18c0,1.1,0.9,2,2,2h2.69l1.9,1.9c0.39,0.39,0.9,0.59,1.41,0.59s1.02-0.2,1.41-0.59l1.9-1.9H18c1.1,0,2-0.9,2-2 v-2.69l1.9-1.9c0.78-0.78,0.78-2.05,0-2.83L20,8.69V6c0-1.1-0.9-2-2-2h-2.69l-1.9-1.9c-0.39-0.39-0.9-0.59-1.41-0.59 s-1.02,0.2-1.41,0.59L8.69,4H6C4.9,4,4,4.9,4,6v2.69l-1.9,1.9c-0.78,0.78-0.78,2.05,0,2.83L4,15.31z M3.16,11.65l1.9-1.9L5.5,9.31 V8.69V6c0-0.28,0.22-0.5,0.5-0.5h2.69h0.62l0.44-0.44l1.9-1.9c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.35,0.15l1.9,1.9 l0.44,0.44h0.62H18c0.28,0,0.5,0.22,0.5,0.5v2.69v0.62l0.44,0.44l1.9,1.9c0.13,0.13,0.15,0.28,0.15,0.35s-0.02,0.23-0.15,0.35 l-1.9,1.9l-0.44,0.44v0.62V18c0,0.28-0.22,0.5-0.5,0.5h-2.69h-0.62l-0.44,0.44l-1.9,1.9c-0.13,0.13-0.28,0.15-0.35,0.15 c-0.08,0-0.23-0.02-0.35-0.15l-1.9-1.9L9.31,18.5H8.69H6c-0.28,0-0.5-0.22-0.5-0.5v-2.69v-0.62l-0.44-0.44l-1.9-1.9 C3.04,12.23,3.02,12.08,3.02,12S3.04,11.77,3.16,11.65z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml
index 37d5576..f16fbc1 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -1,33 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,21.5s7-5.34,7-11.25A7.13,7.13,0,0,0,12,3a7.13,7.13,0,0,0-7,7.25C5,16.16,12,21.5,12,21.5ZM12,4a6.13,6.13,0,0,1,6,6.25c0,4.37-4.37,8.54-6,10-1.63-1.4-6-5.57-6-9.95A6.13,6.13,0,0,1,12,4Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-5,0a2,2,0,1,1,2,2A2,2,0,0,1,10,10Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,21.5c0,0,7-5.34,7-11.25c0-4-3.13-7.25-7-7.25c-3.87,0-7,3.25-7,7.25C5,16.16,12,21.5,12,21.5z M12,4.5 c3.03,0,5.5,2.58,5.5,5.75c0,3.91-3.74,7.72-5.51,9.29C9.9,17.68,6.5,13.89,6.5,10.25C6.5,7.08,8.97,4.5,12,4.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15,10c0-1.66-1.34-3-3-3c-1.66,0-3,1.34-3,3c0,1.66,1.34,3,3,3C13.66,13,15,11.66,15,10z M10.5,10 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5s-0.67,1.5-1.5,1.5S10.5,10.83,10.5,10z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml
index 32f9e53..f48fc11 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,17a9.48,9.48,0,0,1-8.92-5.5A9.48,9.48,0,0,1,12,6a9.5,9.5,0,0,1,8.65,5h1.13A10.5,10.5,0,0,0,12,5,10.47,10.47,0,0,0,2,11.5,10.47,10.47,0,0,0,12,18a11.48,11.48,0,0,0,4-0.7V16.22A10.48,10.48,0,0,1,12,17Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,8a3.5,3.5,0,1,0,3.5,3.5A3.5,3.5,0,0,0,12,8Zm0,6a2.5,2.5,0,1,1,2.5-2.5A2.5,2.5,0,0,1,12,14Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M22,15V14a2,2,0,0,0-4,0v1a1,1,0,0,0-1,1v3a1,1,0,0,0,1,1h4a1,1,0,0,0,1-1V16A1,1,0,0,0,22,15Zm-3,0V14a1,1,0,0,1,2,0v1Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,16.5c-3.74,0-6.89-1.9-8.37-5c1.47-3.1,4.62-5,8.37-5c3.53,0,6.52,1.71,8.08,4.5h1.7C20.09,7.3,16.35,5,12,5 C7.45,5,3.57,7.51,2,11.5C3.57,15.49,7.45,18,12,18c1.41,0,2.76-0.24,4-0.7v-1.62C14.79,16.21,13.44,16.5,12,16.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,8c-1.93,0-3.5,1.57-3.5,3.5S10.07,15,12,15s3.5-1.57,3.5-3.5S13.93,8,12,8z M12,13.5c-1.1,0-2-0.9-2-2s0.9-2,2-2 c1.1,0,2,0.9,2,2S13.1,13.5,12,13.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22,14c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,0.37,0,0.7,0,1h-1v4c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-4h-1 C22,14.65,22,14.28,22,14z M19,14c0-0.55,0.45-1,1-1s1,0.45,1,1v1h-2V14z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml
index 71d427a..736dad3 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -1,33 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,12a1.5,1.5,0,0,0-0.5,2.91V16.5a0.5 0.5 ,0,0,0,1,0V14.91A1.5,1.5,0,0,0,12,12Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M23,5a4,4,0,0,0-8,0V8H6A1,1,0,0,0,5,9v9a3,3,0,0,0,3,3h8a3,3,0,0,0,3-3V9a1,1,0,0,0-1-1H16V5a3,3,0,0,1,6,0,0.5 0.5 ,0,0,0,1,0ZM18,9v9a2,2,0,0,1-2,2H8a2,2,0,0,1-2-2V9H18Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.25,14.79v1.46c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.46c0.45-0.26,0.75-0.74,0.75-1.29 c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5C10.5,14.05,10.8,14.53,11.25,14.79z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19,2.5c1.35,0,2.5,1.18,2.5,2.57c0,0.41,0.34,0.75,0.75,0.75S23,5.48,23,5.07C23,2.86,21.17,1,19,1s-4,1.86-4,4.07V8H5v10 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V8h-2.5V5.07C16.5,3.68,17.65,2.5,19,2.5z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V9.5h11V18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
index f4b29ae..7f060a4 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,11a0.5 0.5 ,0,0,0-0.5 0.5 v5a0.5 0.5 ,0,0,0,1,0v-5A0.5 0.5 ,0,0,0,12,11Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 7 C 12.4142135624 7 12.75 7.33578643763 12.75 7.75 C 12.75 8.16421356237 12.4142135624 8.5 12 8.5 C 11.5857864376 8.5 11.25 8.16421356237 11.25 7.75 C 11.25 7.33578643763 11.5857864376 7 12 7 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
index 85abfff..00a4a07 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
@@ -1,39 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M18.76,11.8a0.54 0.54 ,0,0,0,0.36-0.14 0.51 0.51,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0A0.54 0.54 ,0,0,0,18.76,11.8Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M2.15,8.15a0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7A13.77,13.77,0,0,0,2.15,8.15Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M15.93,14.64a0.49 0.49 ,0,0,0,0.35-0.15 0.5 0.5,0,0,0,0-0.71,6.08,6.08,0,0,0-8.58,0,0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.07,5.07,0,0,1,7.16,0A0.51 0.51 ,0,0,0,15.93,14.64Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53s-2.73,0.54-3.73,1.53c-0.29,0.29-0.77,0.29-1.06-0.01 s-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96s3.5,0.7,4.78,1.96c0.29,0.29,0.3,0.77,0.01,1.06 C16.64,14.93,16.45,15,16.25,15z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml
index ea7a97f..1ee5ee0 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -1,45 +1,25 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M3,5V7A1,1,0,0,0,4,8H20a1,1,0,0,0,1-1V5a2,2,0,0,0-2-2H5A2,2,0,0,0,3,5ZM20,5V7H4V5A1,1,0,0,1,5,4H19A1,1,0,0,1,20,5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M3,19a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V17a2,2,0,0,0-2-2H5a2,2,0,0,0-2,2Zm1-2a1,1,0,0,1,1-1H19a1,1,0,0,1,1,1v2H4Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M3,13a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V11a2,2,0,0,0-2-2H5a2,2,0,0,0-2,2Zm1-2a1,1,0,0,1,1-1H19a1,1,0,0,1,1,1v2H4Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 6.01 4.75 C 6.42421356237 4.75 6.76 5.08578643763 6.76 5.5 C 6.76 5.91421356237 6.42421356237 6.25 6.01 6.25 C 5.59578643763 6.25 5.26 5.91421356237 5.26 5.5 C 5.26 5.08578643763 5.59578643763 4.75 6.01 4.75 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 6.01 10.75 C 6.42421356237 10.75 6.76 11.0857864376 6.76 11.5 C 6.76 11.9142135624 6.42421356237 12.25 6.01 12.25 C 5.59578643763 12.25 5.26 11.9142135624 5.26 11.5 C 5.26 11.0857864376 5.59578643763 10.75 6.01 10.75 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 6.01 16.75 C 6.42421356237 16.75 6.76 17.0857864376 6.76 17.5 C 6.76 17.9142135624 6.42421356237 18.25 6.01 18.25 C 5.59578643763 18.25 5.26 17.9142135624 5.26 17.5 C 5.26 17.0857864376 5.59578643763 16.75 6.01 16.75 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,17c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2v3h18V17z M19.5,18.5h-15V17c0-0.28,0.22-0.5,0.5-0.5h14 c0.28,0,0.5,0.22,0.5,0.5V18.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,5c0-1.1-0.9-2-2-2H5C3.9,3,3,3.9,3,5v3h18V5z M19.5,6.5h-15V5c0-0.28,0.22-0.5,0.5-0.5h14c0.28,0,0.5,0.22,0.5,0.5V6.5 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,11c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2v3h18V11z M19.5,12.5h-15V11c0-0.28,0.22-0.5,0.5-0.5h14 c0.28,0,0.5,0.22,0.5,0.5V12.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 6.01 4.75 C 6.42421356237 4.75 6.76 5.08578643763 6.76 5.5 C 6.76 5.91421356237 6.42421356237 6.25 6.01 6.25 C 5.59578643763 6.25 5.26 5.91421356237 5.26 5.5 C 5.26 5.08578643763 5.59578643763 4.75 6.01 4.75 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 6.01 10.75 C 6.42421356237 10.75 6.76 11.0857864376 6.76 11.5 C 6.76 11.9142135624 6.42421356237 12.25 6.01 12.25 C 5.59578643763 12.25 5.26 11.9142135624 5.26 11.5 C 5.26 11.0857864376 5.59578643763 10.75 6.01 10.75 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 6.01 16.75 C 6.42421356237 16.75 6.76 17.0857864376 6.76 17.5 C 6.76 17.9142135624 6.42421356237 18.25 6.01 18.25 C 5.59578643763 18.25 5.26 17.9142135624 5.26 17.5 C 5.26 17.0857864376 5.59578643763 16.75 6.01 16.75 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
index 7ed248d..7d9dc20 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M13.79,13.79a0.5 0.5 ,0,0,0,0.21,1,0.54 0.54 ,0,0,0,0.21-0.05,2.92,2.92,0,0,0,0-5.39 0.49 0.49,0,0,0-0.66 0.24 0.5 0.5 ,0,0,0,0.24 0.67 ,1.93,1.93,0,0,1,0,3.58Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M13.89,17.67a0.5 0.5 ,0,0,0,0.11,1l0.11,0a6.78,6.78,0,0,0,0-13.28 0.5 0.5,0,1,0-0.22,1,5.79,5.79,0,0,1,0,11.34Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M5,15H7l4.15,4.15a0.47 0.47 ,0,0,0,0.35 0.14 0.5 0.5 ,0,0,0,0.5-0.5V5.21a0.5 0.5 ,0,0,0-0.5-0.5 0.47 0.47,0,0,0-0.35 0.14 L7,9H5a2,2,0,0,0-2,2v2A2,2,0,0,0,5,15ZM4,11a1,1,0,0,1,1-1H7.41l0.3-0.29L11,6.41V17.59l-3.29-3.3L7.41,14H5a1,1,0,0,1-1-1Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M14.44,13.56c-0.38,0.17-0.54,0.62-0.37,0.99c0.13,0.28,0.4,0.44,0.68,0.44c0.1,0,0.21-0.02,0.31-0.07 C16.26,14.37,17,13.25,17,12c0-1.25-0.74-2.37-1.93-2.93c-0.37-0.17-0.82-0.01-1,0.37c-0.17,0.38-0.01,0.82,0.36,1 c0.66,0.3,1.07,0.9,1.07,1.57S15.09,13.26,14.44,13.56z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14.59,17.42c-0.4,0.09-0.66,0.49-0.57,0.9c0.08,0.35,0.39,0.59,0.73,0.59c0.05,0,0.11-0.01,0.16-0.02 c3.29-0.74,5.59-3.57,5.59-6.89s-2.3-6.15-5.59-6.89c-0.41-0.08-0.81,0.17-0.9,0.57s0.16,0.8,0.57,0.9C17.19,7.16,19,9.39,19,12 S17.19,16.84,14.59,17.42z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M7,15l4.15,4.15c0.1,0.1,0.23,0.15,0.35,0.15c0.26,0,0.5-0.2,0.5-0.5V5.21c0-0.3-0.25-0.5-0.5-0.5 c-0.12,0-0.25,0.05-0.35,0.15L7,9H5c-1.1,0-2,0.9-2,2v2c0,1.1,0.9,2,2,2H7z M4.5,13v-2c0-0.28,0.22-0.5,0.5-0.5h2.62l2.88-2.88 v8.76L7.62,13.5H5C4.72,13.5,4.5,13.28,4.5,13z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml
index 10c1592..dcf507a 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_wifi_tethering.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M15.18,16.39a0.51 0.51 ,0,0,0,0.71,0,5.5,5.5,0,0,0,0-7.78,5.52,5.52,0,0,0-7.78,0,5.5,5.5,0,0,0,0,7.78 0.5 0.5,0,0,0,0.35 0.15 0.51 0.51 ,0,0,0,0.36-0.15 0.51 0.51,0,0,0,0-0.71,4.5,4.5,0,1,1,6.36,0A0.51 0.51 ,0,0,0,15.18,16.39Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M18,19.22a0.49 0.49 ,0,0,0,0.35 0.14 0.5 0.5 ,0,0,0,0.36-0.14,9.5,9.5,0,1,0-13.44,0,0.51 0.51 ,0,0,0,0.71,0,0.5 0.5 ,0,0,0,0-0.71,8.5,8.5,0,0,1,12-12,8.5,8.5,0,0,1,0,12A0.5 0.5 ,0,0,0,18,19.22Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,14c-0.83,0-1.5-0.67-1.5-1.5S11.17,11,12,11s1.5,0.67,1.5,1.5S12.83,14,12,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8.46,16.79c-0.19,0-0.38-0.07-0.53-0.22c-1.09-1.09-1.68-2.53-1.68-4.07s0.6-2.98,1.68-4.07 c2.24-2.24,5.89-2.24,8.13,0c1.09,1.09,1.68,2.53,1.68,4.07s-0.6,2.98-1.68,4.07c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06c0.8-0.8,1.24-1.87,1.24-3c0-1.14-0.44-2.2-1.24-3.01c-1.66-1.66-4.35-1.66-6.01,0 c-0.8,0.8-1.24,1.87-1.24,3c0,1.14,0.44,2.2,1.24,3.01c0.29,0.29,0.29,0.77,0,1.06C8.85,16.71,8.66,16.79,8.46,16.79z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.36,19.61c-0.19,0-0.38-0.07-0.53-0.22c-0.29-0.29-0.29-0.77,0-1.06c1.56-1.56,2.42-3.63,2.42-5.83 s-0.86-4.28-2.42-5.83c-3.22-3.22-8.45-3.22-11.67,0C4.61,8.22,3.75,10.3,3.75,12.5s0.86,4.28,2.42,5.83 c0.29,0.29,0.29,0.77,0,1.06s-0.77,0.29-1.06,0c-1.84-1.84-2.86-4.29-2.86-6.89s1.01-5.05,2.86-6.89c3.8-3.8,9.99-3.8,13.79,0 c1.84,1.84,2.86,4.29,2.86,6.89s-1.01,5.05-2.86,6.89C18.75,19.54,18.56,19.61,18.36,19.61z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm.xml
new file mode 100644
index 0000000..ae4af50
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm.xml
@@ -0,0 +1,23 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,4c-4.97,0-9,4.03-9,9c0,4.97,4.03,9,9,9s9-4.03,9-9C21,8.03,16.97,4,12,4z M12,20.5c-4.14,0-7.5-3.36-7.5-7.5 S7.86,5.5,12,5.5s7.5,3.36,7.5,7.5S16.14,20.5,12,20.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.1,4.22c0.13-0.15,0.31-0.25,0.51-0.26c0.2-0.02,0.39,0.04,0.55,0.17l1.53,1.29c0.15,0.13,0.25,0.31,0.26,0.51 c0.02,0.2-0.04,0.39-0.17,0.54c-0.27,0.32-0.23,0.79,0.09,1.06c0.14,0.12,0.31,0.18,0.48,0.18c0.21,0,0.43-0.09,0.57-0.27 c0.8-0.95,0.68-2.37-0.27-3.17l-1.53-1.29c-0.46-0.39-1.04-0.57-1.64-0.52c-0.6,0.05-1.14,0.33-1.53,0.79 c-0.27,0.32-0.23,0.79,0.09,1.06C16.37,4.58,16.84,4.54,17.1,4.22z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.65,7.71c0.17,0,0.34-0.06,0.48-0.18c0.32-0.27,0.36-0.74,0.09-1.06C4.09,6.32,4.03,6.13,4.05,5.93 c0.02-0.2,0.11-0.38,0.26-0.51l1.53-1.29C5.99,4,6.19,3.94,6.39,3.96c0.2,0.02,0.38,0.11,0.51,0.26c0.27,0.32,0.74,0.36,1.06,0.09 c0.32-0.27,0.36-0.74,0.09-1.06C7.66,2.8,7.11,2.52,6.52,2.46C5.92,2.41,5.34,2.6,4.88,2.98L3.34,4.28 C2.39,5.07,2.27,6.5,3.07,7.44C3.22,7.62,3.43,7.71,3.65,7.71z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.75,12.69V7.75C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75v5.56l2.7,2.7c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L12.75,12.69z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm_dim.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm_dim.xml
new file mode 100644
index 0000000..ae4af50
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_alarm_dim.xml
@@ -0,0 +1,23 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,4c-4.97,0-9,4.03-9,9c0,4.97,4.03,9,9,9s9-4.03,9-9C21,8.03,16.97,4,12,4z M12,20.5c-4.14,0-7.5-3.36-7.5-7.5 S7.86,5.5,12,5.5s7.5,3.36,7.5,7.5S16.14,20.5,12,20.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.1,4.22c0.13-0.15,0.31-0.25,0.51-0.26c0.2-0.02,0.39,0.04,0.55,0.17l1.53,1.29c0.15,0.13,0.25,0.31,0.26,0.51 c0.02,0.2-0.04,0.39-0.17,0.54c-0.27,0.32-0.23,0.79,0.09,1.06c0.14,0.12,0.31,0.18,0.48,0.18c0.21,0,0.43-0.09,0.57-0.27 c0.8-0.95,0.68-2.37-0.27-3.17l-1.53-1.29c-0.46-0.39-1.04-0.57-1.64-0.52c-0.6,0.05-1.14,0.33-1.53,0.79 c-0.27,0.32-0.23,0.79,0.09,1.06C16.37,4.58,16.84,4.54,17.1,4.22z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.65,7.71c0.17,0,0.34-0.06,0.48-0.18c0.32-0.27,0.36-0.74,0.09-1.06C4.09,6.32,4.03,6.13,4.05,5.93 c0.02-0.2,0.11-0.38,0.26-0.51l1.53-1.29C5.99,4,6.19,3.94,6.39,3.96c0.2,0.02,0.38,0.11,0.51,0.26c0.27,0.32,0.74,0.36,1.06,0.09 c0.32-0.27,0.36-0.74,0.09-1.06C7.66,2.8,7.11,2.52,6.52,2.46C5.92,2.41,5.34,2.6,4.88,2.98L3.34,4.28 C2.39,5.07,2.27,6.5,3.07,7.44C3.22,7.62,3.43,7.71,3.65,7.71z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.75,12.69V7.75C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75v5.56l2.7,2.7c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L12.75,12.69z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml
new file mode 100644
index 0000000..c8f07aa
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 19 11 C 19.5522847498 11 20 11.4477152502 20 12 C 20 12.5522847498 19.5522847498 13 19 13 C 18.4477152502 13 18 12.5522847498 18 12 C 18 11.4477152502 18.4477152502 11 19 11 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 5 11 C 5.55228474983 11 6 11.4477152502 6 12 C 6 12.5522847498 5.55228474983 13 5 13 C 4.44771525017 13 4 12.5522847498 4 12 C 4 11.4477152502 4.44771525017 11 5 11 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M4.97,4.97c-0.29,0.29-0.29,0.77,0,1.06L10.94,12l-5.97,5.97c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22L11,14.06V22h0.75c2.96,0,5.37-2.41,5.37-5.38c0-1.97-1.06-3.69-2.64-4.62c1.58-0.94,2.64-2.66,2.64-4.62 c0-2.96-2.41-5.38-5.37-5.38H11v7.94L6.03,4.97C5.74,4.68,5.26,4.68,4.97,4.97z M12.5,3.57c1.78,0.35,3.12,1.92,3.12,3.8 s-1.34,3.45-3.12,3.8V3.57z M12.5,12.82c1.78,0.35,3.12,1.92,3.12,3.8s-1.34,3.45-3.12,3.8V12.82z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
index 04ee7cd..a8eccbd 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
@@ -1,33 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M3.41,14.72A2,2,0,0,1,4,16.14V18a2,2,0,0,0,2,2H7.86a2,2,0,0,1,1.42 0.59 l1.31,1.31a2,2,0,0,0,2.82,0l1.31-1.31A2,2,0,0,1,16.14,20H18a2,2,0,0,0,2-2V16.14a2,2,0,0,1,0.59-1.42l1.31-1.31a2,2,0,0,0,0-2.82L20.59,9.28A2,2,0,0,1,20,7.86V6a2,2,0,0,0-2-2H16.14a2,2,0,0,1-1.42-0.59L13.41,2.1a2,2,0,0,0-2.82,0L9.28,3.41A2,2,0,0,1,7.86,4H6A2,2,0,0,0,4,6V7.86a2,2,0,0,1-0.59,1.42L2.1,10.59a2,2,0,0,0,0,2.82Zm-0.6-3.43L4.12,10A3,3,0,0,0,5,7.86V6A1,1,0,0,1,6,5H7.86A3,3,0,0,0,10,4.12l1.31-1.31a1,1,0,0,1,1.42,0L14,4.12A3,3,0,0,0,16.14,5H18a1,1,0,0,1,1,1V7.86A3,3,0,0,0,19.88,10l1.31,1.31a1,1,0,0,1,0,1.42L19.88,14A3,3,0,0,0,19,16.14V18a1,1,0,0,1-1,1H16.14a3,3,0,0,0-2.12 0.88 l-1.31,1.31a1,1,0,0,1-1.42,0L10,19.88A3,3,0,0,0,7.86,19H6a1,1,0,0,1-1-1V16.14A3,3,0,0,0,4.12,14L2.81,12.71a1,1,0,0,1,0-1.42Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M 12 7 C 14.7614237492 7 17 9.23857625085 17 12 C 17 14.7614237492 14.7614237492 17 12 17 C 9.23857625085 17 7 14.7614237492 7 12 C 7 9.23857625085 9.23857625085 7 12 7 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="?android:attr/colorPrimary" android:pathData="M18.94,9.75L18.5,9.31V8.69V6c0-0.28-0.22-0.5-0.5-0.5h-2.69h-0.62l-0.44-0.44l-1.9-1.9 C12.23,3.04,12.08,3.02,12,3.02c-0.08,0-0.23,0.02-0.35,0.15l-1.9,1.9L9.31,5.5H8.69H6C5.72,5.5,5.5,5.72,5.5,6v2.69v0.62 L5.06,9.75l-1.9,1.9C3.04,11.77,3.02,11.92,3.02,12s0.02,0.23,0.15,0.35l1.9,1.9l0.44,0.44v0.62V18c0,0.28,0.22,0.5,0.5,0.5h2.69 h0.62l0.44,0.44l1.9,1.9c0.13,0.13,0.28,0.15,0.35,0.15c0.08,0,0.23-0.02,0.35-0.15l1.9-1.9l0.44-0.44h0.62H18 c0.28,0,0.5-0.22,0.5-0.5v-2.69v-0.62l0.44-0.44l1.9-1.9c0.13-0.13,0.15-0.28,0.15-0.35s-0.02-0.23-0.15-0.35L18.94,9.75z M12,17 c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S14.76,17,12,17z"/>
+  <path android:fillColor="?android:attr/colorControlActivated" android:pathData="M21.9,10.59L20,8.69V6c0-1.1-0.9-2-2-2h-2.69l-1.9-1.9c-0.39-0.39-0.9-0.59-1.41-0.59s-1.02,0.2-1.41,0.59L8.69,4H6 C4.9,4,4,4.9,4,6v2.69l-1.9,1.9c-0.78,0.78-0.78,2.05,0,2.83l1.9,1.9V18c0,1.1,0.9,2,2,2h2.69l1.9,1.9 c0.39,0.39,0.9,0.59,1.41,0.59s1.02-0.2,1.41-0.59l1.9-1.9H18c1.1,0,2-0.9,2-2v-2.69l1.9-1.9C22.68,12.63,22.68,11.37,21.9,10.59z M20.84,12.35l-1.9,1.9l-0.44,0.44v0.62V18c0,0.28-0.22,0.5-0.5,0.5h-2.69h-0.62l-0.44,0.44l-1.9,1.9 c-0.13,0.13-0.28,0.15-0.35,0.15c-0.08,0-0.23-0.02-0.35-0.15l-1.9-1.9L9.31,18.5H8.69H6c-0.28,0-0.5-0.22-0.5-0.5v-2.69v-0.62 l-0.44-0.44l-1.9-1.9C3.04,12.23,3.02,12.08,3.02,12s0.02-0.23,0.15-0.35l1.9-1.9L5.5,9.31V8.69V6c0-0.28,0.22-0.5,0.5-0.5h2.69 h0.62l0.44-0.44l1.9-1.9c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.35,0.15l1.9,1.9l0.44,0.44h0.62H18 c0.28,0,0.5,0.22,0.5,0.5v2.69v0.62l0.44,0.44l1.9,1.9c0.13,0.13,0.15,0.28,0.15,0.35S20.96,12.23,20.84,12.35z"/>
+  <path android:fillColor="?android:attr/colorControlActivated" android:pathData="M 12 7 C 14.7614237492 7 17 9.23857625085 17 12 C 17 14.7614237492 14.7614237492 17 12 17 C 9.23857625085 17 7 14.7614237492 7 12 C 7 9.23857625085 9.23857625085 7 12 7 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml
new file mode 100644
index 0000000..66b4a35
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M22,8c0-1.66-1.34-3-3-3h-2l-2-2H9L7,5H5C3.34,5,2,6.34,2,8v13h20V8z M20.5,19.5h-17V8c0-0.83,0.67-1.5,1.5-1.5h14 c0.83,0,1.5,0.67,1.5,1.5V19.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,8.5c-2.49,0-4.5,2.01-4.5,4.5s2.01,4.5,4.5,4.5s4.5-2.01,4.5-4.5S14.49,8.5,12,8.5z M12,16c-1.65,0-3-1.35-3-3 c0-1.65,1.35-3,3-3c1.65,0,3,1.35,3,3C15,14.65,13.65,16,12,16z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast.xml
new file mode 100644
index 0000000..1d7d5e9
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast.xml
@@ -0,0 +1,23 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.25,9C2.66,9,3,8.66,3,8.25v-1C3,6.01,4.01,5,5.25,5h13.5C19.99,5,21,6.01,21,7.25V19h-7.25C13.34,19,13,19.34,13,19.75 s0.34,0.75,0.75,0.75h8.75V7.25c0-2.07-1.68-3.75-3.75-3.75H5.25C3.18,3.5,1.5,5.18,1.5,7.25v1C1.5,8.66,1.84,9,2.25,9z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.38,20.49c0.3,0.04,0.6-0.06,0.83-0.29c0.39-0.39,0.39-1.02,0-1.41c-0.39-0.39-1.02-0.39-1.41,0l0.01-0.01 c0,0-0.01,0.01-0.01,0.01c-0.39,0.39-0.39,1.02,0,1.41C1.96,20.37,2.16,20.47,2.38,20.49z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.25,12.5c4,0,7.25,3.25,7.25,7.25c0,0.41,0.34,0.75,0.75,0.75S11,20.16,11,19.75C11,14.93,7.07,11,2.25,11 c-0.41,0-0.75,0.34-0.75,0.75S1.84,12.5,2.25,12.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.25,16.5c1.79,0,3.25,1.46,3.25,3.25c0,0.41,0.34,0.75,0.75,0.75S7,20.16,7,19.75C7,17.13,4.87,15,2.25,15 c-0.41,0-0.75,0.34-0.75,0.75S1.84,16.5,2.25,16.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast_connected.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast_connected.xml
new file mode 100644
index 0000000..1656b0b
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_cast_connected.xml
@@ -0,0 +1,24 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.25,9C2.66,9,3,8.66,3,8.25v-1C3,6.01,4.01,5,5.25,5h13.5C19.99,5,21,6.01,21,7.25V19h-7.25C13.34,19,13,19.34,13,19.75 s0.34,0.75,0.75,0.75h8.75V7.25c0-2.07-1.68-3.75-3.75-3.75H5.25C3.18,3.5,1.5,5.18,1.5,7.25v1C1.5,8.66,1.84,9,2.25,9z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.38,20.49c0.3,0.04,0.6-0.06,0.83-0.29c0.39-0.39,0.39-1.02,0-1.41c-0.39-0.39-1.02-0.39-1.41,0l0.01-0.01 c0,0-0.01,0.01-0.01,0.01c-0.39,0.39-0.39,1.02,0,1.41C1.96,20.37,2.16,20.47,2.38,20.49z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.25,12.5c4,0,7.25,3.25,7.25,7.25c0,0.41,0.34,0.75,0.75,0.75S11,20.16,11,19.75C11,14.93,7.07,11,2.25,11 c-0.41,0-0.75,0.34-0.75,0.75S1.84,12.5,2.25,12.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.25,16.5c1.79,0,3.25,1.46,3.25,3.25c0,0.41,0.34,0.75,0.75,0.75S7,20.16,7,19.75C7,17.13,4.87,15,2.25,15 c-0.41,0-0.75,0.34-0.75,0.75S1.84,16.5,2.25,16.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.75,15C13.34,15,13,15.34,13,15.75s0.34,0.75,0.75,0.75h4c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.96-0.79-1.75-1.75-1.75 H6.25C5.84,7.5,5.5,7.84,5.5,8.25S5.84,9,6.25,9h10.5C16.89,9,17,9.11,17,9.25V15H13.75z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_close_white.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_close_white.xml
new file mode 100644
index 0000000..4c2e143
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_close_white.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.03,3.97c-0.29-0.29-0.77-0.29-1.06,0L12,10.94L5.03,3.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-6.97,6.97c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L12,13.06l6.97,6.97 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l6.97-6.97 C20.32,4.74,20.32,4.26,20.03,3.97z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml
new file mode 100644
index 0000000..5670871
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp " android:viewportHeight="24" android:viewportWidth="24" android:width="18dp " xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,7a0.76 0.76 ,0,0,0-0.75 0.75 v3.5H7.75a0.75 0.75 ,0,0,0,0,1.5h3.5v3.5a0.75 0.75 ,0,0,0,1.5,0v-3.5h3.5a0.75 0.75 ,0,0,0,0-1.5h-3.5V7.75A0.76 0.76 ,0,0,0,12,7Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml
index d25350a..2921dd8 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml
@@ -1,36 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,7.5a0.5 0.5 ,0,0,0-0.5 0.5 v3.5H8a0.5 0.5 ,0,0,0,0,1h3.5V16a0.5 0.5 ,0,0,0,1,0V12.5H16a0.5 0.5 ,0,0,0,0-1H12.5V8A0.5 0.5 ,0,0,0,12,7.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22,12a10,10,0,0,0-9-9.95v3A7,7,0,0,1,19,12a7.12,7.12,0,0,1-0.48,2.54h0l2.6,1.53A9.88,9.88,0,0,0,22,12Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.09,13.39a10,10,0,0,0,18,4.52l-2.6-1.53h0A7,7,0,1,1,11,5.08v-3A10,10,0,0,0,2.09,13.39Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_dnd.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_dnd.xml
deleted file mode 100644
index 3e32b3b..0000000
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_dnd.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M7,12.5H17a0.5 0.5 ,0,0,0,0-1H7a0.5 0.5 ,0,0,0,0,1Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_drag_handle.xml
index 793b32f..81cc975 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_drag_handle.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_drag_handle.xml
@@ -1,33 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19.5,9H4.5a0.5 0.5 ,0,0,0,0,1h15a0.5 0.5 ,0,0,0,0-1Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19.5,14H4.5a0.5 0.5 ,0,0,0,0,1h15a0.5 0.5 ,0,0,0,0-1Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4.75,10.5h14.5c0.41,0,0.75-0.34,0.75-0.75S19.66,9,19.25,9H4.75C4.34,9,4,9.34,4,9.75S4.34,10.5,4.75,10.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M4.75,15h14.5c0.41,0,0.75-0.34,0.75-0.75s-0.34-0.75-0.75-0.75H4.75C4.34,13.5,4,13.84,4,14.25S4.34,15,4.75,15z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset.xml
index 4d8c366f..71c76b5 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset.xml
@@ -1,30 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,18V11A9,9,0,0,0,3,11v7a2.93,2.93,0,0,0,2.88,3H8V13H4V11a8,8,0,0,1,16,0v2H16v8h2.12A2.93,2.93,0,0,0,21,18ZM7,14v6H5.88A1.92,1.92,0,0,1,4,18V14Zm13,4a1.92,1.92,0,0,1-1.88,2H17V14h3Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,17.78V11c0-4.96-4.04-9-9-9s-9,4.04-9,9v6.78C3,19.56,4.41,21,6.13,21H9v-8H4.5v-2c0-4.13,3.36-7.5,7.5-7.5 s7.5,3.36,7.5,7.5v2H15v8h2.87C19.59,21,21,19.56,21,17.78z M7.5,19.5H6.13c-0.9,0-1.63-0.77-1.63-1.72V14.5h3V19.5z M19.5,17.78 c0,0.95-0.73,1.72-1.63,1.72H16.5v-5h3V17.78z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset_mic.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset_mic.xml
new file mode 100644
index 0000000..231163b
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_headset_mic.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:pathData="M0,0h24v24H0V0z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,1c-4.96,0-9,4.04-9,9v6.78C3,18.56,4.41,20,6.13,20H9v-8H4.5v-2c0-4.13,3.36-7.5,7.5-7.5s7.5,3.36,7.5,7.5v2H15v8h2.87 c0.59,0,1.13-0.18,1.6-0.47c-0.14,1.11-1.08,1.97-2.22,1.97h-4.5c-0.41,0-0.75,0.34-0.75,0.75S12.34,23,12.75,23h4.5 c2.07,0,3.75-1.68,3.75-3.75V10C21,5.04,16.96,1,12,1z M7.5,18.5H6.13c-0.9,0-1.63-0.77-1.63-1.72V13.5h3V18.5z M17.87,18.5H16.5 v-5h3V16v0.78C19.5,17.73,18.77,18.5,17.87,18.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_hotspot.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_hotspot.xml
index 670449a..895123c 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_hotspot.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_hotspot.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15.18,16.39a0.51 0.51 ,0,0,0,0.71,0,5.5,5.5,0,0,0,0-7.78,5.52,5.52,0,0,0-7.78,0,5.5,5.5,0,0,0,0,7.78 0.5 0.5,0,0,0,0.35 0.15 0.51 0.51 ,0,0,0,0.36-0.15 0.51 0.51,0,0,0,0-0.71,4.5,4.5,0,1,1,6.36,0A0.51 0.51 ,0,0,0,15.18,16.39Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18,19.22a0.49 0.49 ,0,0,0,0.35 0.14 0.5 0.5 ,0,0,0,0.36-0.14,9.5,9.5,0,1,0-13.44,0,0.51 0.51 ,0,0,0,0.71,0,0.5 0.5 ,0,0,0,0-0.71,8.5,8.5,0,0,1,12-12,8.5,8.5,0,0,1,0,12A0.5 0.5 ,0,0,0,18,19.22Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,14c-0.83,0-1.5-0.67-1.5-1.5S11.17,11,12,11s1.5,0.67,1.5,1.5S12.83,14,12,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8.46,16.79c-0.19,0-0.38-0.07-0.53-0.22c-1.09-1.09-1.68-2.53-1.68-4.07s0.6-2.98,1.68-4.07 c2.24-2.24,5.89-2.24,8.13,0c1.09,1.09,1.68,2.53,1.68,4.07s-0.6,2.98-1.68,4.07c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06c0.8-0.8,1.24-1.87,1.24-3c0-1.14-0.44-2.2-1.24-3.01c-1.66-1.66-4.35-1.66-6.01,0 c-0.8,0.8-1.24,1.87-1.24,3c0,1.14,0.44,2.2,1.24,3.01c0.29,0.29,0.29,0.77,0,1.06C8.85,16.71,8.66,16.79,8.46,16.79z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.36,19.61c-0.19,0-0.38-0.07-0.53-0.22c-0.29-0.29-0.29-0.77,0-1.06c1.56-1.56,2.42-3.63,2.42-5.83 s-0.86-4.28-2.42-5.83c-3.22-3.22-8.45-3.22-11.67,0C4.61,8.22,3.75,10.3,3.75,12.5s0.86,4.28,2.42,5.83 c0.29,0.29,0.29,0.77,0,1.06s-0.77,0.29-1.06,0c-1.84-1.84-2.86-4.29-2.86-6.89s1.01-5.05,2.86-6.89c3.8-3.8,9.99-3.8,13.79,0 c1.84,1.84,2.86,4.29,2.86,6.89s-1.01,5.05-2.86,6.89C18.75,19.54,18.56,19.61,18.36,19.61z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info.xml
index 0e108ca..7f060a4 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,11a0.5 0.5 ,0,0,0-0.5 0.5 v5a0.5 0.5 ,0,0,0,1,0v-5A0.5 0.5 ,0,0,0,12,11Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 7 C 12.4142135624 7 12.75 7.33578643763 12.75 7.75 C 12.75 8.16421356237 12.4142135624 8.5 12 8.5 C 11.5857864376 8.5 11.25 8.16421356237 11.25 7.75 C 11.25 7.33578643763 11.5857864376 7 12 7 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info_outline.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info_outline.xml
new file mode 100644
index 0000000..7f060a4
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_info_outline.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_invert_colors.xml
new file mode 100644
index 0000000..5c516f7
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_invert_colors.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2.27L12,2.27C7.02,7.25,4.02,9.61,4.02,14.02C4.02,18.43,7.59,22,12,22s7.98-3.57,7.98-7.98 c0-2.48-0.95-4.31-2.67-6.33C15.98,6.12,14.18,4.45,12,2.27z M5.52,14.02c0-3.26,2.08-5.3,5.85-9.01C11.57,4.8,11.79,4.6,12,4.38 V20.5C8.43,20.5,5.52,17.59,5.52,14.02z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_location.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_location.xml
new file mode 100644
index 0000000..1daa5a5
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_location.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,21.5c0,0,7-5.34,7-11.25c0-4-3.13-7.25-7-7.25c-3.87,0-7,3.25-7,7.25C5,16.16,12,21.5,12,21.5z M12,4.5 c3.03,0,5.5,2.58,5.5,5.75c0,3.91-3.74,7.72-5.51,9.29C9.9,17.68,6.5,13.89,6.5,10.25C6.5,7.08,8.97,4.5,12,4.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15,10c0-1.66-1.34-3-3-3c-1.66,0-3,1.34-3,3c0,1.66,1.34,3,3,3C13.66,13,15,11.66,15,10z M10.5,10 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5s-0.67,1.5-1.5,1.5S10.5,10.83,10.5,10z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml
index 04a2c24..3104903 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml
@@ -1,57 +1,29 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,21a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2H3A2,2,0,0,0,1,6V19a2,2,0,0,0,2,2ZM2,19V6A1,1,0,0,1,3,5H21a1,1,0,0,1,1,1V19a1,1,0,0,1-1,1H3A1,1,0,0,1,2,19Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9.5 8 L 10.5 8 Q 11 8 11 8.5 L 11 9.5 Q 11 10 10.5 10 L 9.5 10 Q 9 10 9 9.5 L 9 8.5 Q 9 8 9.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5.5 8 L 6.5 8 Q 7 8 7 8.5 L 7 9.5 Q 7 10 6.5 10 L 5.5 10 Q 5 10 5 9.5 L 5 8.5 Q 5 8 5.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13.5 8 L 14.5 8 Q 15 8 15 8.5 L 15 9.5 Q 15 10 14.5 10 L 13.5 10 Q 13 10 13 9.5 L 13 8.5 Q 13 8 13.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9.5 12 L 10.5 12 Q 11 12 11 12.5 L 11 13.5 Q 11 14 10.5 14 L 9.5 14 Q 9 14 9 13.5 L 9 12.5 Q 9 12 9.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5.5 12 L 6.5 12 Q 7 12 7 12.5 L 7 13.5 Q 7 14 6.5 14 L 5.5 14 Q 5 14 5 13.5 L 5 12.5 Q 5 12 5.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13.5 12 L 14.5 12 Q 15 12 15 12.5 L 15 13.5 Q 15 14 14.5 14 L 13.5 14 Q 13 14 13 13.5 L 13 12.5 Q 13 12 13.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17.5 8 L 18.5 8 Q 19 8 19 8.5 L 19 9.5 Q 19 10 18.5 10 L 17.5 10 Q 17 10 17 9.5 L 17 8.5 Q 17 8 17.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17.5 12 L 18.5 12 Q 19 12 19 12.5 L 19 13.5 Q 19 14 18.5 14 L 17.5 14 Q 17 14 17 13.5 L 17 12.5 Q 17 12 17.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M8.5,17h7a0.5 0.5 ,0,0,0,0-1h-7a0.5 0.5 ,0,0,0,0,1Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21.5,19c0,0.27-0.23,0.5-0.5,0.5 H3c-0.27,0-0.5-0.23-0.5-0.5V6c0-0.27,0.23-0.5,0.5-0.5h18c0.27,0,0.5,0.23,0.5,0.5V19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.75,8h0.5C10.66,8,11,8.34,11,8.75v0.5C11,9.66,10.66,10,10.25,10h-0.5C9.34,10,9,9.66,9,9.25v-0.5 C9,8.34,9.34,8,9.75,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5.75,8h0.5C6.66,8,7,8.34,7,8.75v0.5C7,9.66,6.66,10,6.25,10h-0.5C5.34,10,5,9.66,5,9.25v-0.5C5,8.34,5.34,8,5.75,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.75,8h0.5C14.66,8,15,8.34,15,8.75v0.5C15,9.66,14.66,10,14.25,10h-0.5C13.34,10,13,9.66,13,9.25v-0.5 C13,8.34,13.34,8,13.75,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C9.34,14,9,13.66,9,13.25v-0.5 C9,12.34,9.34,12,9.75,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5.75,12h0.5C6.66,12,7,12.34,7,12.75v0.5C7,13.66,6.66,14,6.25,14h-0.5C5.34,14,5,13.66,5,13.25v-0.5 C5,12.34,5.34,12,5.75,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C13.34,14,13,13.66,13,13.25v-0.5 C13,12.34,13.34,12,13.75,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.75,8h0.5C18.66,8,19,8.34,19,8.75v0.5C19,9.66,18.66,10,18.25,10h-0.5C17.34,10,17,9.66,17,9.25v-0.5 C17,8.34,17.34,8,17.75,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.75,12h0.5c0.41,0,0.75,0.34,0.75,0.75v0.5c0,0.41-0.34,0.75-0.75,0.75h-0.5C17.34,14,17,13.66,17,13.25v-0.5 C17,12.34,17.34,12,17.75,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15.5,17h-7C8.22,17,8,16.78,8,16.5S8.22,16,8.5,16h7c0.28,0,0.5,0.22,0.5,0.5S15.78,17,15.5,17z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_alert.xml
index 2b9e371..e3b4ef7 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_alert.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_alert.xml
@@ -1,39 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,2.5A1.5,1.5,0,0,0,10.5,4v0.2A6,6,0,0,0,6,10v5.5a0.5 0.5 ,0,0,1-0.5 0.5 A1.5,1.5,0,0,0,4,17.5v1a0.5 0.5 ,0,0,0,0.5 0.5 h15a0.5 0.5 ,0,0,0,0.5-0.5v-1A1.5,1.5,0,0,0,18.5,16a0.5 0.5 ,0,0,1-0.5-0.5V10a6,6,0,0,0-4.5-5.8V4A1.5,1.5,0,0,0,12,2.5ZM17,10v5.5A1.5,1.5,0,0,0,18.5,17a0.5 0.5 ,0,0,1,0.5 0.5 V18H5v-0.5a0.5 0.5 ,0,0,1,0.5-0.5A1.5,1.5,0,0,0,7,15.5V10a5,5,0,0,1,10,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,20H10a2,2,0,0,0,4,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M6,3.2a9.24,9.24,0,0,0-3.26,7.05 0.5 0.5,0,0,0,1,0A8.25,8.25,0,0,1,6.66,4,0.5 0.5 ,0,0,0,6,3.2Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.25,10.25A9.24,9.24,0,0,0,18,3.2a0.5 0.5 ,0,0,0-0.65 0.76 ,8.25,8.25,0,0,1,2.91,6.29 0.5 0.5,0,0,0,1,0Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.5,10.25c0-2.79-1.22-5.43-3.35-7.24c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06 C18.97,5.68,20,7.9,20,10.25c0,0.41,0.34,0.75,0.75,0.75S21.5,10.66,21.5,10.25z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,2.5c-0.83,0-1.5,0.67-1.5,1.5v0.7C7.91,5.36,6,7.71,6,10.5V15c0,0.55-0.45,1-1,1s-1,0.45-1,1v2h16v-2 c0-0.55-0.45-1-1-1s-1-0.45-1-1v-4.5c0-2.79-1.91-5.14-4.5-5.8V4C13.5,3.17,12.83,2.5,12,2.5z M16.5,10.5V15 c0,1.21,0.86,2.22,2,2.45v0.05h-13v-0.05c1.14-0.23,2-1.24,2-2.45v-4.5C7.5,8.02,9.52,6,12,6S16.5,8.02,16.5,10.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_silence.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_silence.xml
index 838f752..e60b7da 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_silence.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_notifications_silence.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,5a5,5,0,0,1,5,5v5.17l3,3V17.5A1.5,1.5,0,0,0,18.5,16a0.5 0.5 ,0,0,1-0.5-0.5V10a6,6,0,0,0-4.5-5.8V4a1.5,1.5,0,0,0-3,0v0.2A6,6,0,0,0,7.68,5.85l0.71 0.71 A5,5,0,0,1,12,5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,20H10a2,2,0,0,0,4,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20.85,21.15l-18-18a0.48 0.48 ,0,0,0-0.7,0h0a0.48 0.48 ,0,0,0,0,0.7L6.33,8A6.06,6.06,0,0,0,6,10v5.5a0.5 0.5 ,0,0,1-0.5 0.5 A1.5,1.5,0,0,0,4,17.5v1a0.5 0.5 ,0,0,0,0.5 0.5 H17.29l2.86,2.85a0.48 0.48 ,0,0,0,0.7,0h0A0.48 0.48 ,0,0,0,20.85,21.15ZM5,18v-0.5a0.5 0.5 ,0,0,1,0.5-0.5A1.5,1.5,0,0,0,7,15.5V10a4.83,4.83,0,0,1,0.15-1.15L16.29,18Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,6c2.48,0,4.5,2.02,4.5,4.5v3.8l3.5,3.5V17c0-0.55-0.45-1-1-1s-1-0.45-1-1v-4.5c0-2.79-1.91-5.14-4.5-5.8V4 c0-0.83-0.67-1.5-1.5-1.5S10.5,3.17,10.5,4v0.7C9.61,4.93,8.8,5.35,8.13,5.92L9.2,7C9.97,6.38,10.94,6,12,6z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.03,20.97l-18-18c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06l4.4,4.4 C6.14,9.08,6,9.77,6,10.5V15c0,0.55-0.45,1-1,1s-1,0.45-1,1v2h12.94l3.03,3.03c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0,0,0,0,0,0C21.32,21.74,21.32,21.26,21.03,20.97z M5.5,17.5v-0.05c1.14-0.23,2-1.24,2-2.45v-4.5c0-0.29,0.03-0.58,0.09-0.85 l7.85,7.85H5.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_low.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_low.xml
new file mode 100644
index 0000000..388e1d3
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_low.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,13.5c0.41,0,0.75-0.34,0.75-0.75v-4C12.75,8.34,12.41,8,12,8s-0.75,0.34-0.75,0.75v4C11.25,13.16,11.59,13.5,12,13.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 15 C 12.5522847498 15 13 15.4477152502 13 16 C 13 16.5522847498 12.5522847498 17 12 17 C 11.4477152502 17 11 16.5522847498 11 16 C 11 15.4477152502 11.4477152502 15 12 15 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14,4c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9C7.34,4,6,5.34,6,7v12c0,1.66,1.34,3,3,3h6c1.66,0,3-1.34,3-3V7 c0-1.66-1.34-3-3-3H14z M16.5,7v12c0,0.83-0.67,1.5-1.5,1.5H9c-0.83,0-1.5-0.67-1.5-1.5V7c0-0.83,0.67-1.5,1.5-1.5h6 C15.83,5.5,16.5,6.17,16.5,7z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_saver.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_saver.xml
new file mode 100644
index 0000000..2d04510
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_power_saver.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M9.75,13.75h1.5v1.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.5h1.5c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.5v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.5h-1.5C9.34,12.25,9,12.59,9,13 S9.34,13.75,9.75,13.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.66,1.34,3,3,3h6c1.66,0,3-1.34,3-3V7c0-1.66-1.34-3-3-3h-1c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9 C7.34,4,6,5.34,6,7V19z M7.5,7c0-0.83,0.67-1.5,1.5-1.5h6c0.83,0,1.5,0.67,1.5,1.5v12c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V7z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml
deleted file mode 100644
index f98e2b8..0000000
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.5,6a0.5 0.5 ,0,0,0-0.5 0.5 V11H7.5a0.5 0.5 ,0,0,0,0-1H4.76l5-4.65a2.49,2.49,0,0,1,3.48 0.05 l4.95,4.95a0.49 0.49 ,0,1,0,0.7-0.7L13.91,4.7A3.47,3.47,0,0,0,9,4.62L4,9.35V6.5A0.5 0.5 ,0,0,0,3.5,6Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20.5,18a0.5 0.5 ,0,0,0,0.5-0.5V13H16.5a0.5 0.5 ,0,0,0,0,1h2.74l-5,4.65a2.49,2.49,0,0,1-3.48,0l-5-5a0.49 0.49 ,0,0,0-0.7 0.7 l4.94,5a3.47,3.47,0,0,0,4.87 0.08 l5-4.73V17.5A0.5 0.5 ,0,0,0,20.5,18Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
index 10b1cbf..86bfecc 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.16,17.37a0.51 0.51 ,0,0,0,0.71,0,7.76,7.76,0,0,0,0-10.68 0.5 0.5,0,1,0-0.74 0.68 ,6.74,6.74,0,0,1,0,9.32A0.51 0.51 ,0,0,0,18.16,17.37Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.27,14.47a0.51 0.51 ,0,0,0,0.7,0,3.48,3.48,0,0,0,0-4.92l-0.72 0.7 a2.47,2.47,0,0,1,0,3.51A0.5 0.5 ,0,0,0,16.27,14.47Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.15,18.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L9,13.71V22h0.5a5.25,5.25,0,0,0,2.25-10A5.25,5.25,0,0,0,9.5,2H9v8.29L3.85,5.15a0.49 0.49 ,0,0,0-0.7 0.7 L9,11.71v0.58Zm10.63-1.4A4.26,4.26,0,0,1,10,21V12.53A4.26,4.26,0,0,1,13.78,16.75ZM10,3a4.25,4.25,0,0,1,0,8.44Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M18.2,16.49c-0.28,0.3-0.26,0.78,0.04,1.06c0.14,0.13,0.33,0.2,0.51,0.2c0.2,0,0.4-0.08,0.55-0.24 c1.42-1.53,2.2-3.49,2.2-5.51c0-2.02-0.78-3.97-2.2-5.51c-0.28-0.3-0.76-0.32-1.06-0.04c-0.3,0.28-0.32,0.76-0.04,1.06 C19.36,8.77,20,10.36,20,12C20,13.64,19.36,15.23,18.2,16.49z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.35,9.36c-0.29,0.29-0.29,0.77,0,1.06C16.77,10.85,17,11.41,17,12s-0.23,1.16-0.66,1.58c-0.29,0.29-0.3,0.77,0,1.06 c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.71-0.7,1.1-1.64,1.1-2.64c0-1-0.39-1.94-1.09-2.64 C17.12,9.07,16.64,9.07,16.35,9.36z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.97,19.03c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L9,14.06V22h0.75c2.96,0,5.37-2.41,5.37-5.38 c0-1.97-1.06-3.69-2.64-4.62c1.58-0.94,2.64-2.66,2.64-4.62C15.12,4.41,12.71,2,9.75,2H9v7.94L4.03,4.97 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L8.94,12l-5.97,5.97C2.68,18.26,2.68,18.74,2.97,19.03z M10.5,3.57 c1.78,0.35,3.12,1.92,3.12,3.8s-1.34,3.45-3.12,3.8V3.57z M10.5,12.82c1.78,0.35,3.12,1.92,3.12,3.8s-1.34,3.45-3.12,3.8V12.82z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml
index e8664f6..48b0dda 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml
@@ -21,10 +21,6 @@
     android:viewportHeight="24">
 
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.78,7.25A5.27,5.27,0,0,0,11.5,2H11v8.29L5.85,5.15a0.49 0.49 ,0,0,0-0.7 0.7 L11,11.71v0.58L5.15,18.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L11,13.71V22h0.5a5.25,5.25,0,0,0,2.25-10A5.25,5.25,0,0,0,16.78,7.25Zm-1,9.5A4.26,4.26,0,0,1,12,21V12.53A4.26,4.26,0,0,1,15.78,16.75ZM12,11.47V3a4.25,4.25,0,0,1,0,8.44Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M17.12,7.38c0-2.96-2.41-5.38-5.37-5.38H11v7.94L6.03,4.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-5.97,5.97c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L11,14.06V22h0.75 c2.96,0,5.37-2.41,5.37-5.38c0-1.97-1.06-3.69-2.64-4.62C16.06,11.06,17.12,9.34,17.12,7.38z M15.62,16.62 c0,1.88-1.34,3.45-3.12,3.8v-7.6C14.28,13.17,15.62,14.75,15.62,16.62z M12.5,11.18v-7.6c1.78,0.35,3.12,1.92,3.12,3.8 S14.28,10.83,12.5,11.18z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml
deleted file mode 100644
index fc990d8..0000000
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.41,14.72A2,2,0,0,1,4,16.14V18a2,2,0,0,0,2,2H7.86a2,2,0,0,1,1.42 0.59 l1.31,1.31a2,2,0,0,0,2.82,0l1.31-1.31A2,2,0,0,1,16.14,20H18a2,2,0,0,0,2-2V16.14a2,2,0,0,1,0.59-1.42l1.31-1.31a2,2,0,0,0,0-2.82L20.59,9.28A2,2,0,0,1,20,7.86V6a2,2,0,0,0-2-2H16.14a2,2,0,0,1-1.42-0.59L13.41,2.1a2,2,0,0,0-2.82,0L9.28,3.41A2,2,0,0,1,7.86,4H6A2,2,0,0,0,4,6V7.86a2,2,0,0,1-0.59,1.42L2.1,10.59a2,2,0,0,0,0,2.82Zm-0.6-3.43L4.12,10A3,3,0,0,0,5,7.86V6A1,1,0,0,1,6,5H7.86A3,3,0,0,0,10,4.12l1.31-1.31a1,1,0,0,1,1.42,0L14,4.12A3,3,0,0,0,16.14,5H18a1,1,0,0,1,1,1V7.86A3,3,0,0,0,19.88,10l1.31,1.31a1,1,0,0,1,0,1.42L19.88,14A3,3,0,0,0,19,16.14V18a1,1,0,0,1-1,1H16.14a3,3,0,0,0-2.12 0.88 l-1.31,1.31a1,1,0,0,1-1.42,0L10,19.88A3,3,0,0,0,7.86,19H6a1,1,0,0,1-1-1V16.14A3,3,0,0,0,4.12,14L2.81,12.71a1,1,0,0,1,0-1.42Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10,14.61h4L14.85,17H17L13.11,7H10.87L7,17H9.15Zm1.92-5.44h0.11l1.29,3.71H10.63Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cancel.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cancel.xml
index 40de609..ee7ad6e 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cancel.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cancel.xml
@@ -1,33 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,3a9,9,0,1,1-9,9A9,9,0,0,1,12,3Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M7.15,16.85a0.48 0.48 ,0,0,0,0.7,0L12,12.71l4.15,4.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L12.71,12l4.14-4.15a0.49 0.49 ,0,1,0-0.7-0.7L12,11.29,7.85,7.15a0.49 0.49 ,0,0,0-0.7 0.7 L11.29,12,7.15,16.15A0.48 0.48 ,0,0,0,7.15,16.85Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,22c5.52,0,10-4.48,10-10S17.52,2,12,2S2,6.48,2,12S6.48,22,12,22z M12,3.5c4.69,0,8.5,3.81,8.5,8.5s-3.81,8.5-8.5,8.5 c-4.69,0-8.5-3.81-8.5-8.5C3.5,7.31,7.31,3.5,12,3.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.97,17.03c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L12,13.06l3.97,3.97c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l3.97-3.97c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L8.03,6.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-3.97,3.97C6.68,16.26,6.68,16.74,6.97,17.03z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cast_on.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cast_on.xml
deleted file mode 100644
index d12cf9e..0000000
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_cast_on.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22,17.5V6.5A2.5,2.5,0,0,0,19.5,4H4.5A2.5,2.5,0,0,0,2,6.5v2a0.5 0.5 ,0,0,0,1,0v-2A1.5,1.5,0,0,1,4.5,5h15A1.5,1.5,0,0,1,21,6.5v11A1.5,1.5,0,0,1,19.5,19h-6a0.5 0.5 ,0,0,0,0,1h6A2.5,2.5,0,0,0,22,17.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.21,19.61A1,1,0,0,0,3,20a1,1,0,0,0,0-2H3a1,1,0,0,0-0.79,1.61Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.5,12A7.5,7.5,0,0,1,10,19.5a0.5 0.5 ,0,0,0,1,0A8.51,8.51,0,0,0,2.5,11a0.5 0.5 ,0,0,0,0,1Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.5,16A3.5,3.5,0,0,1,6,19.5a0.5 0.5 ,0,0,0,1,0A4.51,4.51,0,0,0,2.5,15a0.5 0.5 ,0,0,0,0,1Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.5,15h-3a0.5 0.5 ,0,0,0,0,1h3A1.5,1.5,0,0,0,18,14.5v-5A1.5,1.5,0,0,0,16.5,8H6.5a0.5 0.5 ,0,0,0,0,1h10a0.5 0.5 ,0,0,1,0.5 0.5 v5A0.5 0.5 ,0,0,1,16.5,15Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_no_sim.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_no_sim.xml
index e17d646..799aaa0 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_no_sim.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_no_sim.xml
@@ -1,33 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10.41,4H17a1,1,0,0,1,1,1V16.17l1,1V5a2,2,0,0,0-2-2H10L7.42,5.58l0.7 0.71 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20.85,21.15l-18-18a0.48 0.48 ,0,0,0-0.7,0h0a0.48 0.48 ,0,0,0,0,0.7l3.5,3.5L5,8V19a2,2,0,0,0,2,2H17a2,2,0,0,0,1.55-0.75l1.6,1.6a0.48 0.48 ,0,0,0,0.7,0h0A0.48 0.48 ,0,0,0,20.85,21.15ZM17,20H7a1,1,0,0,1-1-1V8.41l0.35-0.35L17.83,19.53A1,1,0,0,1,17,20Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M10.62,4.5H16c0.83,0,1.5,0.67,1.5,1.5v9.3l1.5,1.5V6c0-1.66-1.34-3-3-3h-6L7.6,5.4l1.06,1.06L10.62,4.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5,8v10c0,1.66,1.34,3,3,3h8c0.81,0,1.55-0.33,2.09-0.85l1.88,1.88c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0,0,0,0,0,0c0.29-0.29,0.29-0.77,0-1.06l-18-18c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06l3.5,3.5L5,8 z M16,19.5H8c-0.83,0-1.5-0.67-1.5-1.5V8.62l0.03-0.03l10.5,10.5C16.76,19.34,16.4,19.5,16,19.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_vpn.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_vpn.xml
deleted file mode 100644
index e5c1f4e..0000000
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_vpn.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M7.5,9A2.5,2.5,0,1,0,10,11.5,2.5,2.5,0,0,0,7.5,9Zm0,4A1.5,1.5,0,1,1,9,11.5,1.5,1.5,0,0,1,7.5,13Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.5,9H12.39A5.5,5.5,0,0,0,2.12,10.32,5.58,5.58,0,0,0,3.23,15a5.49,5.49,0,0,0,9.16-1H15v1.5A1.5,1.5,0,0,0,16.5,17h2A1.5,1.5,0,0,0,20,15.5V14h1.5a0.5 0.5 ,0,0,0,0.5-0.5v-4A0.5 0.5 ,0,0,0,21.5,9ZM21,13H19.5a0.5 0.5 ,0,0,0-0.5 0.5 v2a0.5 0.5 ,0,0,1-0.5 0.5 h-2a0.5 0.5 ,0,0,1-0.5-0.5v-2a0.5 0.5 ,0,0,0-0.5-0.5H12.08a0.51 0.51 ,0,0,0-0.46 0.3 ,4.5,4.5,0,0,1-7.61,1,4.57,4.57,0,0,1-0.91-3.82A4.48,4.48,0,0,1,6.7,7.07,4.53,4.53,0,0,1,11.62,9.7a0.51 0.51 ,0,0,0,0.46 0.3 H21Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml
index ad48771..e90bd08 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml
@@ -1,54 +1,24 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0,0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.06,5.06,0,0,1,6.77-0.32,3.85,3.85,0,0,1,0.82-0.62A6.08,6.08,0,0,0,7.7,13.78Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.15,15.15a0.48 0.48 ,0,0,0,0,0.7L18.29,18l-2.14,2.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14A0.48 0.48 ,0,0,0,16.15,15.15Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L19,20.06l1.86,1.86 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml
index cc87827..ef405ad 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml
@@ -1,51 +1,24 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M5.58,11.66a9.07,9.07,0,0,1,12.83,0,0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71A0.51 0.51 ,0,0,0,5.58,11.66Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M2.15,8.85a0.48 0.48 ,0,0,0,0.7,0,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0A0.48 0.48 ,0,0,0,2.15,8.85Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.06,5.06,0,0,1,6.77-0.32,3.85,3.85,0,0,1,0.82-0.62A6.08,6.08,0,0,0,7.7,13.78Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.15,20.85a0.48 0.48 ,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14a0.49 0.49 ,0,0,0-0.7 0.7 L18.29,18l-2.14,2.15A0.48 0.48 ,0,0,0,16.15,20.85Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L19,20.06l1.86,1.86 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml
index eceaa74..60798d6 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml
@@ -1,48 +1,24 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M18.41,11.66a0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5.06,5.06,0,0,1,6.77-0.32,3.85,3.85,0,0,1,0.82-0.62A6.08,6.08,0,0,0,7.7,13.78Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.15,15.15a0.48 0.48 ,0,0,0,0,0.7L18.29,18l-2.14,2.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14A0.48 0.48 ,0,0,0,16.15,15.15Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L19,20.06l1.86,1.86 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml
index 7640376..acd2c9a 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml
@@ -1,45 +1,24 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.41,11.66a0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M2.15,8.85a0.48 0.48 ,0,0,0,0.7,0,12.8,12.8,0,0,1,18.3,0,0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0A0.48 0.48 ,0,0,0,2.15,8.85Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,12A6.05,6.05,0,0,0,7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5,5,0,0,1,6.77-0.32,3.77,3.77,0,0,1,0.84-0.63A6,6,0,0,0,12,12Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.15,15.15a0.48 0.48 ,0,0,0,0,0.7L18.29,18l-2.14,2.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14A0.48 0.48 ,0,0,0,16.15,15.15Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L19,20.06l1.86,1.86 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml
index 8213e1c..3bb1a96 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml
@@ -1,42 +1,24 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.41,11.66a0.52 0.52 ,0,0,0,0.71,0,0.51 0.51 ,0,0,0,0-0.71A10.08,10.08,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.07,9.07,0,0,1,12.83,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.5,9a0.47 0.47 ,0,0,0,0.35-0.15 0.48 0.48,0,0,0,0-0.7,13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.8,12.8,0,0,1,18.3,0A0.47 0.47 ,0,0,0,21.5,9Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,12A6.05,6.05,0,0,0,7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0,5,5,0,0,1,6.77-0.32,3.77,3.77,0,0,1,0.84-0.63A6,6,0,0,0,12,12Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.15,15.15a0.48 0.48 ,0,0,0,0,0.7L18.29,18l-2.14,2.15a0.48 0.48 ,0,0,0,0,0.7 0.48 0.48,0,0,0,0.7,0L19,18.71l2.15,2.14a0.48 0.48 ,0,0,0,0.7,0,0.48 0.48 ,0,0,0,0-0.7L19.71,18l2.14-2.15a0.49 0.49 ,0,1,0-0.7-0.7L19,17.29l-2.15-2.14A0.48 0.48 ,0,0,0,16.15,15.15Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.89,0,1.73,0.24,2.5,0.65c0.46-0.37,0.99-0.65,1.58-0.79C14.9,12.24,13.49,11.75,12,11.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.92,16.08c-0.29-0.29-0.77-0.29-1.06,0L19,17.94l-1.86-1.86c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L17.94,19 l-1.86,1.86c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L19,20.06l1.86,1.86 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L20.06,19l1.86-1.86 C22.22,16.84,22.22,16.37,21.92,16.08z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,18.5c0-0.44-0.2-0.84-0.5-1.11C12.73,17.15,12.39,17,12,17c-0.83,0-1.5,0.67-1.5,1.5S11.17,20,12,20 c0.39,0,0.73-0.15,1-0.39C13.3,19.34,13.5,18.95,13.5,18.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.89,11.62c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C17.83,8.43,15,7.25,12,7.25s-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75S17.05,9.77,18.89,11.62z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06C20.16,4.39,16.21,2.75,12,2.75 S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25S19.38,5.74,22.08,8.43z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml
index 86c03c6..906b3e7 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml
@@ -1,57 +1,25 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M 11.99 16.5 C 12.8184271247 16.5 13.49 17.1715728753 13.49 18 C 13.49 18.8284271247 12.8184271247 19.5 11.99 19.5 C 11.1615728753 19.5 10.49 18.8284271247 10.49 18 C 10.49 17.1715728753 11.1615728753 16.5 11.99 16.5 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M12,8A10,10,0,0,0,4.87,11a0.5 0.5 ,0,0,0,0,0.71 0.51 0.51,0,0,0,0.71,0,9.08,9.08,0,0,1,9.94-1.95A5.11,5.11,0,0,1,16.35,9,10,10,0,0,0,12,8Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.85,8.15a13.77,13.77,0,0,0-19.7,0,0.49 0.49 ,0,0,0,0.7 0.7 ,12.79,12.79,0,0,1,17.42-0.79A5.51,5.51,0,0,1,22,8.6 0.47 0.47,0,0,0,21.85,8.15Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M7.7,13.78a0.51 0.51 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.71,0A5.06,5.06,0,0,1,14,13.43a5.9,5.9,0,0,1,0.11-1A6.07,6.07,0,0,0,7.7,13.78Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17.1,11.27a3.42,3.42,0,0,0-0.89,1.64 0.5 0.5,0,0,0,0.37 0.6 0.5 0.5 ,0,0,0,0.6-0.37A2.56,2.56,0,0,1,17.81,12a2.4,2.4,0,0,1,3.38,0,2.18,2.18,0,0,1,0.64,1.76A1.85,1.85,0,0,1,21,15.12a3.13,3.13,0,0,1-0.36 0.22 A2.8,2.8,0,0,0,19,17.5a0.51 0.51 ,0,0,0,0.41 0.58 h0.08a0.5 0.5 ,0,0,0,0.5-0.41,1.81,1.81,0,0,1,1.14-1.46l0.42-0.26a2.86,2.86,0,0,0,1.27-2.12,3.21,3.21,0,0,0-0.92-2.56A3.43,3.43,0,0,0,17.1,11.27Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 19.5 19.5 C 19.9142135624 19.5 20.25 19.8357864376 20.25 20.25 C 20.25 20.6642135624 19.9142135624 21 19.5 21 C 19.0857864376 21 18.75 20.6642135624 18.75 20.25 C 18.75 19.8357864376 19.0857864376 19.5 19.5 19.5 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M12,7.25c-3,0-5.83,1.17-7.95,3.3c-0.29,0.29-0.29,0.77,0,1.06c0.29,0.29,0.77,0.29,1.06,0 C6.95,9.77,9.4,8.75,12,8.75c1.17,0,2.31,0.22,3.38,0.61c0.46-0.4,0.98-0.73,1.55-0.96C15.41,7.66,13.74,7.25,12,7.25z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M22.08,8.43c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 C20.16,4.39,16.21,2.75,12,2.75S3.84,4.39,0.86,7.37c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0C4.62,5.74,8.19,4.25,12,4.25 S19.38,5.74,22.08,8.43z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M12,11.75c-1.8,0-3.5,0.7-4.78,1.96c-0.29,0.29-0.3,0.77-0.01,1.06c0.29,0.29,0.77,0.3,1.06,0.01 c1-0.99,2.32-1.53,3.73-1.53c0.52,0,1.02,0.1,1.5,0.24c0-0.53,0.08-1.03,0.22-1.51C13.16,11.84,12.59,11.75,12,11.75z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.42,11.09c-0.47,0.48-0.8,1.09-0.95,1.76c-0.09,0.4,0.16,0.81,0.56,0.9c0.4,0.1,0.81-0.16,0.9-0.56 c0.09-0.41,0.29-0.77,0.56-1.05c0.81-0.83,2.21-0.83,3.02,0c0.42,0.43,0.63,1,0.57,1.57c-0.05,0.5-0.31,0.92-0.72,1.2 c-0.11,0.08-0.23,0.14-0.35,0.21c-0.64,0.37-1.51,0.88-1.75,2.34c-0.07,0.41,0.21,0.79,0.62,0.86c0.04,0.01,0.08,0.01,0.12,0.01 c0.36,0,0.68-0.26,0.74-0.63c0.13-0.76,0.48-0.97,1.03-1.28c0.15-0.09,0.3-0.17,0.44-0.27c0.79-0.53,1.28-1.35,1.37-2.3 c0.1-1.01-0.26-2.02-0.99-2.77C20.21,9.68,17.8,9.68,16.42,11.09z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 19 20 C 19.5522847498 20 20 20.4477152502 20 21 C 20 21.5522847498 19.5522847498 22 19 22 C 18.4477152502 22 18 21.5522847498 18 21 C 18 20.4477152502 18.4477152502 20 19 20 Z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_screenshot_delete.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_screenshot_delete.xml
index 174f36e..c66f918 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_screenshot_delete.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_screenshot_delete.xml
@@ -1,36 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M9,20h6a3,3,0,0,0,3-3V6h0.5a0.5 0.5 ,0,0,0,0-1H15L14,4H10L9,5H5.5a0.5 0.5 ,0,0,0,0,1H6V17A3,3,0,0,0,9,20ZM17,6V17a2,2,0,0,1-2,2H9a2,2,0,0,1-2-2V6Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,16a0.5 0.5 ,0,0,0,0.5-0.5v-7A0.5 0.5 ,0,0,0,14,8a0.5 0.5 ,0,0,0-0.5 0.5 v7A0.5 0.5 ,0,0,0,14,16Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10,16a0.5 0.5 ,0,0,0,0.5-0.5v-7a0.5 0.5 ,0,0,0-1,0v7A0.5 0.5 ,0,0,0,10,16Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M9,20h6c1.66,0,3-1.34,3-3V6h0.5c0.41,0,0.75-0.34,0.75-0.75S18.91,4.5,18.5,4.5H18h-3l-1-1h-4l-1,1H6H5.5 c-0.41,0-0.75,0.34-0.75,0.75S5.09,6,5.5,6H6v11C6,18.66,7.34,20,9,20z M16.5,6v11c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V6H16.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.97,16c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v6.5 C13.22,15.66,13.55,16,13.97,16z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M10,16c0.41,0,0.75-0.34,0.75-0.75v-6.5C10.75,8.34,10.41,8,10,8S9.25,8.34,9.25,8.75v6.5C9.25,15.66,9.59,16,10,16z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings.xml
new file mode 100644
index 0000000..eb4b99b
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,8.5c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5c1.93,0,3.5-1.57,3.5-3.5S13.93,8.5,12,8.5z M12,14c-1.1,0-2-0.9-2-2 s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,14,12,14z M21.29,13.9l-1.83-1.05c-0.3-0.17-0.49-0.49-0.48-0.84v-0.01 c0-0.35,0.18-0.67,0.48-0.84l1.83-1.05c0.48-0.28,0.64-0.89,0.37-1.37l-2-3.46c-0.19-0.32-0.52-0.5-0.87-0.5 c-0.17,0-0.34,0.04-0.5,0.13l-1.84,1.06c-0.14,0.08-0.29,0.12-0.45,0.12c-0.17,0-0.35-0.05-0.5-0.14c0,0-0.01,0-0.01-0.01 C15.2,5.77,15,5.47,15,5.12V3c0-0.55-0.45-1-1-1h-4C9.45,2,9,2.45,9,3v2.12c0,0.34-0.2,0.65-0.5,0.82c0,0-0.01,0-0.01,0.01 c-0.16,0.09-0.33,0.14-0.5,0.14c-0.15,0-0.31-0.04-0.45-0.12L5.71,4.9c-0.16-0.09-0.33-0.13-0.5-0.13c-0.35,0-0.68,0.18-0.87,0.5 l-2,3.46C2.06,9.21,2.23,9.82,2.71,10.1l1.83,1.05c0.3,0.17,0.49,0.49,0.48,0.84v0.01c0,0.35-0.18,0.67-0.48,0.84L2.71,13.9 c-0.48,0.28-0.64,0.89-0.37,1.37l2,3.46c0.19,0.32,0.52,0.5,0.87,0.5c0.17,0,0.34-0.04,0.5-0.13l1.84-1.06 c0.14-0.08,0.29-0.12,0.45-0.12c0.17,0,0.35,0.05,0.5,0.14c0,0,0.01,0,0.01,0.01C8.8,18.23,9,18.53,9,18.88V21c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-2.12c0-0.34,0.2-0.65,0.5-0.82c0,0,0.01,0,0.01-0.01c0.16-0.09,0.33-0.14,0.5-0.14c0.15,0,0.31,0.04,0.45,0.12 l1.84,1.06c0.16,0.09,0.33,0.13,0.5,0.13c0.35,0,0.68-0.18,0.87-0.5l2-3.46C21.94,14.79,21.77,14.18,21.29,13.9z M18.61,17.55 l-1.41-0.81c-0.36-0.21-0.78-0.32-1.2-0.32c-0.43,0-0.86,0.12-1.25,0.34c-0.77,0.44-1.25,1.25-1.25,2.12v1.62h-3v-1.62 c0-0.87-0.48-1.68-1.26-2.12c-0.38-0.22-0.81-0.33-1.25-0.33c-0.42,0-0.84,0.11-1.2,0.32l-1.41,0.81l-1.5-2.6l1.39-0.8 c0.76-0.44,1.24-1.26,1.23-2.15c0-0.88-0.47-1.7-1.23-2.14l-1.39-0.8l1.5-2.6L6.8,7.26c0.36,0.21,0.78,0.32,1.2,0.32 c0.43,0,0.86-0.12,1.25-0.34c0.77-0.44,1.25-1.25,1.25-2.12V3.5h3v1.62c0,0.87,0.48,1.68,1.26,2.12c0.38,0.22,0.81,0.33,1.25,0.33 c0.42,0,0.84-0.11,1.2-0.32l1.41-0.81l1.5,2.6l-1.39,0.8c-0.76,0.44-1.24,1.26-1.23,2.15c0,0.88,0.47,1.7,1.23,2.14l1.39,0.8 L18.61,17.55z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings_16dp.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings_16dp.xml
index 33d172c..73d353a 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings_16dp.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_settings_16dp.xml
@@ -21,13 +21,9 @@
     android:viewportHeight="24">
 
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M12,8.5c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5c1.93,0,3.5-1.57,3.5-3.5S13.93,8.5,12,8.5z M12,14c-1.1,0-2-0.9-2-2 s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,14,12,14z" />
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M5.31,19.26a1.6,1.6,0,0,0,0.53-0.09l1.8-0.7c0.26 0.16 0.52 0.31 0.79 0.45 l0.27,1.84A1.44,1.44,0,0,0,10.15,22h3.7a1.46,1.46,0,0,0,1.46-1.19l0.27-1.87c0.26-0.13 0.52 -0.28 0.78 -0.44l1.8 0.7 a1.47,1.47,0,0,0,0.54 0.1 A1.44,1.44,0,0,0,20,18.58l1.86-3.14a1.4,1.4,0,0,0-0.37-1.81l-1.52-1.17c0-0.14,0-0.29,0-0.45s0-0.3,0-0.44l1.52-1.17a1.41,1.41,0,0,0,0.36-1.83L20,5.47a1.46,1.46,0,0,0-1.29-0.73,1.69,1.69,0,0,0-0.53 0.09 l-1.8 0.7 c-0.26-0.16-0.52-0.31-0.79-0.45l-0.27-1.84A1.44,1.44,0,0,0,13.84,2h-3.7A1.45,1.45,0,0,0,8.7,3.22L8.43,5.08q-0.39 0.21 -0.78 0.45 L5.84,4.82a1.47,1.47,0,0,0-0.54-0.1,1.43,1.43,0,0,0-1.25 0.72 L2.2,8.55a1.37,1.37,0,0,0,0.37,1.83l1.52,1.17c0,0.14,0,0.3,0,0.45s0,0.3,0,0.44L2.56,13.61a1.42,1.42,0,0,0-0.36,1.83L4,18.53A1.46,1.46,0,0,0,5.31,19.26ZM3.16,14.4l1.53-1.16 0.43 -0.33,0-0.53c0-0.13,0-0.25,0-0.38s0-0.26,0-0.39l0-0.53-0.42-0.33L3.17,9.58a0.38 0.38 ,0,0,1-0.11-0.52L4.92,5.93a0.43 0.43 ,0,0,1,0.38-0.21 0.47 0.47,0,0,1,0.17,0l1.81 0.71 0.48 0.19 0.43-0.27A6.39,6.39,0,0,1,8.9,6l0.45-0.24 0.07 -0.5 0.27 -1.88A0.44 0.44 ,0,0,1,10.14,3h3.7a0.44 0.44 ,0,0,1,0.46 0.38 l0.27,1.85 0.08 0.51 0.46 0.24a5.3,5.3,0,0,1,0.7 0.4 l0.43 0.27 0.47-0.19,1.78-0.69a0.63 0.63 ,0,0,1,0.19,0,0.47 0.47 ,0,0,1,0.43 0.24 l1.83,3.08a0.42 0.42 ,0,0,1-0.1 0.55 l-1.52,1.16-0.42 0.33 ,0,0.53c0,0.13,0,0.25,0,0.38s0,0.26,0,0.39l0,0.53 0.42 0.33,1.51,1.15a0.42 0.42 ,0,0,1,0.13 0.52 l-1.87,3.16a0.43 0.43 ,0,0,1-0.39 0.21 0.57 0.57 ,0,0,1-0.18,0l-1.8-0.71-0.47-0.18-0.43 0.27 a7.46,7.46,0,0,1-0.71 0.41 l-0.45 0.24 -0.07 0.5 -0.27,1.86a0.47 0.47 ,0,0,1-0.47 0.34 h-3.7a0.44 0.44 ,0,0,1-0.46-0.38l-0.27-1.85-0.08-0.51L8.88,18a5.3,5.3,0,0,1-0.7-0.4l-0.43-0.27-0.47 0.19 -1.78 0.69 a0.58 0.58 ,0,0,1-0.19,0A0.48 0.48 ,0,0,1,4.89,18L3.08,15A0.42 0.42 ,0,0,1,3.16,14.4Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,15.91A3.92,3.92,0,1,0,8,12,4,4,0,0,0,12,15.91Zm0-6.83A2.92,2.92,0,1,1,9,12,3,3,0,0,1,12,9.08Z" />
-</vector>
+        android:fillColor="#FFFFFF"
+        android:pathData="M19.47,11.15l1.83-1.05c0.48-0.28,0.64-0.89,0.37-1.37l-2-3.46c-0.19-0.32-0.52-0.5-0.87-0.5c-0.17,0-0.34,0.04-0.5,0.13 l-1.84,1.06c-0.14,0.08-0.29,0.12-0.45,0.12c-0.17,0-0.35-0.05-0.5-0.14c0,0-0.01,0-0.01-0.01C15.2,5.77,15,5.47,15,5.12V3 c0-0.55-0.45-1-1-1h-4C9.45,2,9,2.45,9,3v2.12c0,0.34-0.2,0.65-0.5,0.82c0,0-0.01,0-0.01,0.01c-0.16,0.09-0.33,0.14-0.5,0.14 c-0.15,0-0.31-0.04-0.45-0.12L5.71,4.9c-0.16-0.09-0.33-0.13-0.5-0.13c-0.35,0-0.68,0.18-0.87,0.5l-2,3.46 C2.06,9.21,2.23,9.82,2.71,10.1l1.83,1.05c0.3,0.17,0.49,0.49,0.48,0.84c0,0,0,0.01,0,0.01c0,0.35-0.18,0.67-0.48,0.84L2.71,13.9 c-0.48,0.28-0.64,0.89-0.37,1.37l2,3.46c0.19,0.32,0.52,0.5,0.87,0.5c0.17,0,0.34-0.04,0.5-0.13l1.84-1.06 c0.14-0.08,0.29-0.12,0.45-0.12c0.17,0,0.35,0.05,0.5,0.14c0,0,0.01,0,0.01,0.01C8.8,18.23,9,18.53,9,18.88V21c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-2.12c0-0.34,0.2-0.65,0.5-0.82c0,0,0.01,0,0.01-0.01c0.16-0.09,0.33-0.14,0.5-0.14c0.15,0,0.31,0.04,0.45,0.12 l1.84,1.06c0.16,0.09,0.33,0.13,0.5,0.13c0.35,0,0.68-0.18,0.87-0.5l2-3.46c0.28-0.48,0.11-1.09-0.37-1.37l-1.83-1.05 c-0.3-0.17-0.49-0.49-0.48-0.84c0,0,0-0.01,0-0.01C18.98,11.65,19.17,11.33,19.47,11.15z M18.72,14.15l1.39,0.8l-1.5,2.6 l-1.41-0.81c-0.36-0.21-0.78-0.32-1.2-0.32c-0.43,0-0.86,0.12-1.25,0.34c-0.77,0.44-1.25,1.25-1.25,2.12v1.62h-3v-1.62 c0-0.87-0.48-1.68-1.26-2.12c-0.38-0.22-0.81-0.33-1.25-0.33c-0.42,0-0.84,0.11-1.2,0.32l-1.41,0.81l-1.5-2.6l1.39-0.8 c0.76-0.44,1.24-1.26,1.23-2.15c0-0.88-0.47-1.7-1.23-2.14l-1.39-0.8l1.5-2.6L6.8,7.26c0.36,0.21,0.78,0.32,1.2,0.32 c0.43,0,0.86-0.12,1.25-0.34c0.77-0.44,1.25-1.25,1.25-2.12V3.5h3v1.62c0,0.87,0.48,1.68,1.26,2.12c0.38,0.22,0.81,0.33,1.25,0.33 c0.42,0,0.84-0.11,1.2-0.32l1.41-0.81l1.5,2.6l-1.39,0.8c-0.76,0.44-1.24,1.26-1.23,2.15C17.48,12.89,17.96,13.71,18.72,14.15z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_airplane.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_airplane.xml
deleted file mode 100644
index a5ef380..0000000
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_airplane.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.8,15l7.2-0.73v3.49L8,19.38a1.52,1.52,0,0,0-0.54,1.16v1a0.52 0.52 ,0,0,0,0.17 0.38 0.51 0.51 ,0,0,0,0.39 0.12 L12,21.5l3.94 0.5 H16a0.5 0.5 ,0,0,0,0.33-0.12 0.52 0.52,0,0,0,0.17-0.38v-1A1.52,1.52,0,0,0,16,19.38l-2-1.62V14.27l7.2 0.73 a0.51 0.51 ,0,0,0,0.55-0.5,3.49,3.49,0,0,0-2.15-3.23L14,8.94V3.5a2,2,0,0,0-4,0V8.94L4.4,11.27A3.49,3.49,0,0,0,2.25,14.5a0.51 0.51 ,0,0,0,0.55 0.5 Zm2-2.81,5.9-2.45A0.5 0.5 ,0,0,0,11,9.28V3.5a1,1,0,0,1,2,0V9.28a0.5 0.5 ,0,0,0,0.31 0.46 l5.9,2.45a2.51,2.51,0,0,1,1.48,1.75l-7.14-0.72a0.52 0.52 ,0,0,0-0.38 0.13 0.5 0.5 ,0,0,0-0.17 0.37 V18a0.53 0.53 ,0,0,0,0.18 0.39 l2.14,1.76a0.53 0.53 ,0,0,1,0.18 0.39 v0.39l-3.44-0.43h-0.12l-3.44 0.43 v-0.39a0.53 0.53 ,0,0,1,0.18-0.39l2.14-1.76A0.53 0.53 ,0,0,0,11,18V13.72a0.5 0.5 ,0,0,0-0.17-0.37 0.52 0.52,0,0,0-0.38-0.13l-7.14 0.72 A2.51,2.51,0,0,1,4.79,12.19Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_flashlight.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_flashlight.xml
deleted file mode 100644
index 1526691..0000000
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_signal_flashlight.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M11,22h2a2,2,0,0,0,2-2V10a6.84,6.84,0,0,0,3-6V3H6V4a6.84,6.84,0,0,0,3,6V20A2,2,0,0,0,11,22ZM17,4a8.26,8.26,0,0,1-0.07,1H7.07A8.26,8.26,0,0,1,7,4ZM7.28,6h9.45a5.24,5.24,0,0,1-2.24,3.14L14,9.43V20a1,1,0,0,1-1,1H11a1,1,0,0,1-1-1V9.43l-0.49-0.29A5.25,5.25,0,0,1,7.28,6Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 13 C 12.5522847498 13 13 13.4477152502 13 14 C 13 14.5522847498 12.5522847498 15 12 15 C 11.4477152502 15 11 14.5522847498 11 14 C 11 13.4477152502 11.4477152502 13 12 13 Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_swap_vert.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_swap_vert.xml
index 2f3ac2e..528c718 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_swap_vert.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_swap_vert.xml
@@ -1,33 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.85,16.65a0.48 0.48 ,0,0,0-0.7,0L16,18.79V10.5a0.5 0.5 ,0,0,0-1,0v8.29l-2.15-2.14a0.49 0.49 ,0,0,0-0.7 0.7 l3.35,3.36,3.35-3.36A0.48 0.48 ,0,0,0,18.85,16.65Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M11.85,6.64l-3-3h0L8.5,3.29l-0.35 0.35 h0l-3,3a0.5 0.5 ,0,0,0,0,0.71 0.5 0.5,0,0,0,0.7,0L8,5.2v8.3a0.5 0.5 ,0,0,0,1,0V5.2l2.15,2.15a0.48 0.48 ,0,0,0,0.7,0A0.5 0.5 ,0,0,0,11.85,6.64Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M19.78,16.72c-0.29-0.29-0.77-0.29-1.06,0l-2.47,2.47v-8.44c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v8.44 l-2.47-2.47c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l4.28,4.28l4.28-4.28C20.07,17.49,20.07,17.01,19.78,16.72z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M7.75,4.81v8.44C7.75,13.66,8.09,14,8.5,14s0.75-0.34,0.75-0.75V4.81l2.47,2.47c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L8.5,1.94L4.22,6.22c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0L7.75,4.81z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml
new file mode 100644
index 0000000..858126e
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml
@@ -0,0 +1,25 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="16dp" android:viewportHeight="24" android:viewportWidth="24" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.25,4.75h-2.4C17.55,4.02,16.84,3.5,16,3.5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2c0.84,0,1.55-0.52,1.85-1.25h2.4 C20.66,6.25,21,5.91,21,5.5S20.66,4.75,20.25,4.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M11.98,4.75H3.75C3.34,4.75,3,5.09,3,5.5s0.34,0.75,0.75,0.75h8.23c0.01,0,0.01,0,0.02,0V4.75 C11.99,4.75,11.99,4.75,11.98,4.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.25,17.75h-5.4c-0.3-0.73-1.01-1.25-1.85-1.25c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2c0.84,0,1.55-0.52,1.85-1.25h5.4 c0.41,0,0.75-0.34,0.75-0.75S20.66,17.75,20.25,17.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8.98,17.75H3.75C3.34,17.75,3,18.09,3,18.5s0.34,0.75,0.75,0.75h5.23c0.01,0,0.01,0,0.02,0v-1.49 C8.99,17.75,8.99,17.75,8.98,17.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M7,10c-0.84,0-1.55,0.52-1.85,1.25h-1.4C3.34,11.25,3,11.59,3,12s0.34,0.75,0.75,0.75h1.4C5.45,13.48,6.16,14,7,14 c1.1,0,2-0.9,2-2C9,10.9,8.1,10,7,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.25,11.25h-9.23c-0.01,0-0.01,0-0.02,0v1.49c0.01,0,0.01,0,0.02,0h9.23c0.41,0,0.75-0.34,0.75-0.75 S20.66,11.25,20.25,11.25z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm.xml
index c67e897..0779913 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm.xml
@@ -21,19 +21,15 @@
     android:viewportHeight="24">
 
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M12,4c-4.97,0-9,4.03-9,9c0,4.97,4.03,9,9,9s9-4.03,9-9C21,8.03,16.97,4,12,4z M12,20.5c-4.14,0-7.5-3.36-7.5-7.5 S7.86,5.5,12,5.5s7.5,3.36,7.5,7.5S16.14,20.5,12,20.5z" />
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M17.1,4.22c0.13-0.15,0.31-0.25,0.51-0.26c0.2-0.02,0.39,0.04,0.55,0.17l1.53,1.29c0.15,0.13,0.25,0.31,0.26,0.51 c0.02,0.2-0.04,0.39-0.17,0.54c-0.27,0.32-0.23,0.79,0.09,1.06c0.14,0.12,0.31,0.18,0.48,0.18c0.21,0,0.43-0.09,0.57-0.27 c0.8-0.95,0.68-2.37-0.27-3.17l-1.53-1.29c-0.46-0.39-1.04-0.57-1.64-0.52c-0.6,0.05-1.14,0.33-1.53,0.79 c-0.27,0.32-0.23,0.79,0.09,1.06C16.37,4.58,16.84,4.54,17.1,4.22z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M12,4a9,9,0,1,0,9,9A9,9,0,0,0,12,4Zm0,17a8,8,0,1,1,8-8A8,8,0,0,1,12,21Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M3.65,7.71c0.17,0,0.34-0.06,0.48-0.18c0.32-0.27,0.36-0.74,0.09-1.06C4.09,6.32,4.03,6.13,4.05,5.93 c0.02-0.2,0.11-0.38,0.26-0.51l1.53-1.29C5.99,4,6.19,3.94,6.39,3.96c0.2,0.02,0.38,0.11,0.51,0.26c0.27,0.32,0.74,0.36,1.06,0.09 c0.32-0.27,0.36-0.74,0.09-1.06C7.66,2.8,7.11,2.52,6.52,2.46C5.92,2.41,5.34,2.6,4.88,2.98L3.34,4.28 C2.39,5.07,2.27,6.5,3.07,7.44C3.22,7.62,3.43,7.71,3.65,7.71z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M17.51,2.71a2,2,0,0,0-1.36 0.71 0.5 0.5 ,0,0,0,0.76 0.64 ,1,1,0,0,1,1.41-0.12l1.53,1.29a1,1,0,0,1,0.35 0.68 ,1,1,0,0,1-0.23 0.73 0.49 0.49 ,0,0,0,0.06 0.7 0.51 0.51 ,0,0,0,0.32 0.12 0.5 0.5 ,0,0,0,0.39-0.18,2,2,0,0,0,0.46-1.46,2,2,0,0,0-0.7-1.35L19,3.18A1.92,1.92,0,0,0,17.51,2.71Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.65,7.46A0.51 0.51 ,0,0,0,4,7.34 0.49 0.49,0,0,0,4,6.64a1,1,0,0,1-0.23-0.73,1,1,0,0,1,0.35-0.68L5.68,3.94a1,1,0,0,1,0.73-0.23,1,1,0,0,1,0.68 0.35 0.5 0.5 ,0,1,0,0.76-0.64,2,2,0,0,0-1.36-0.71A1.92,1.92,0,0,0,5,3.18L3.5,4.47a2,2,0,0,0-0.7,1.35,2,2,0,0,0,0.46,1.46A0.5 0.5 ,0,0,0,3.65,7.46Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.5,12.79V8a0.5 0.5 ,0,0,0-1,0v5.21l3.13,3.12a0.47 0.47 ,0,0,0,0.35 0.15 0.5 0.5 ,0,0,0,0.35-0.85Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M12.75,12.69V7.75C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75v5.56l2.7,2.7c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L12.75,12.69z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
new file mode 100644
index 0000000..383f6d8
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
@@ -0,0 +1,23 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M8.55,6.35C9.58,5.81,10.76,5.5,12,5.5c4.14,0,7.5,3.36,7.5,7.5c0,1.24-0.31,2.42-0.85,3.45l1.1,1.1 C20.54,16.22,21,14.66,21,13c0-4.97-4.03-9-9-9c-1.66,0-3.22,0.46-4.55,1.25L8.55,6.35z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.1,4.22c0.13-0.15,0.31-0.25,0.51-0.26c0.2-0.02,0.39,0.04,0.55,0.17l1.53,1.29c0.15,0.13,0.25,0.31,0.26,0.51 c0.02,0.2-0.04,0.39-0.17,0.54c-0.27,0.32-0.23,0.79,0.09,1.06c0.14,0.12,0.31,0.18,0.48,0.18c0.21,0,0.43-0.09,0.57-0.27 c0.8-0.95,0.68-2.37-0.27-3.17l-1.53-1.29c-0.46-0.39-1.04-0.57-1.64-0.52c-0.6,0.05-1.14,0.33-1.53,0.79 c-0.27,0.32-0.23,0.79,0.09,1.06C16.37,4.58,16.84,4.54,17.1,4.22z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.39,3.96c0.2,0.02,0.38,0.11,0.51,0.26c0.27,0.32,0.74,0.36,1.06,0.09c0.32-0.27,0.36-0.74,0.09-1.06 C7.66,2.8,7.11,2.52,6.52,2.46c-0.52-0.04-1.03,0.1-1.46,0.39l1.12,1.12C6.25,3.97,6.32,3.95,6.39,3.96z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.03,2.97c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06L2.84,4.9C2.39,5.69,2.45,6.71,3.07,7.44 c0.15,0.18,0.36,0.27,0.57,0.27c0.17,0,0.34-0.06,0.48-0.18c0.32-0.27,0.36-0.74,0.09-1.06c-0.09-0.1-0.13-0.22-0.15-0.35 l1.06,1.06C3.8,8.76,3,10.78,3,13c0,4.97,4.03,9,9,9c2.22,0,4.24-0.8,5.81-2.13l2.16,2.16c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0,0,0,0,0,0c0.29-0.29,0.29-0.77,0-1.06L3.03,2.97z M12,20.5c-4.14,0-7.5-3.36-7.5-7.5 c0-1.8,0.64-3.45,1.7-4.74L16.74,18.8C15.45,19.86,13.8,20.5,12,20.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml
new file mode 100644
index 0000000..5dcccdf
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml
@@ -0,0 +1,24 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="19dp" android:viewportHeight="24" android:viewportWidth="24" android:width="19dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M9,4C7.9,4,7,4.9,7,6v12c0,1.1,0.9,2,2,2h6c1.1,0,2-0.9,2-2V6c0-1.1-0.9-2-2-2H9z M15.5,6v12c0,0.28-0.22,0.5-0.5,0.5H9 c-0.28,0-0.5-0.22-0.5-0.5V6c0-0.28,0.22-0.5,0.5-0.5h6C15.28,5.5,15.5,5.72,15.5,6z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.75,17c0.41,0,0.75-0.34,0.75-0.75v-8.5C19.5,7.34,19.16,7,18.75,7S18,7.34,18,7.75v8.5C18,16.66,18.34,17,18.75,17z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.75,9C21.34,9,21,9.34,21,9.75v4.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-4.5C22.5,9.34,22.16,9,21.75,9z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3,14.25v-4.5C3,9.34,2.66,9,2.25,9S1.5,9.34,1.5,9.75v4.5C1.5,14.66,1.84,15,2.25,15S3,14.66,3,14.25z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M4.5,16.25C4.5,16.66,4.84,17,5.25,17S6,16.66,6,16.25v-8.5C6,7.34,5.66,7,5.25,7S4.5,7.34,4.5,7.75V16.25z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_camera.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_camera.xml
new file mode 100644
index 0000000..66b4a35
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_camera.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M22,8c0-1.66-1.34-3-3-3h-2l-2-2H9L7,5H5C3.34,5,2,6.34,2,8v13h20V8z M20.5,19.5h-17V8c0-0.83,0.67-1.5,1.5-1.5h14 c0.83,0,1.5,0.67,1.5,1.5V19.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,8.5c-2.49,0-4.5,2.01-4.5,4.5s2.01,4.5,4.5,4.5s4.5-2.01,4.5-4.5S14.49,8.5,12,8.5z M12,16c-1.65,0-3-1.35-3-3 c0-1.65,1.35-3,3-3c1.65,0,3,1.35,3,3C15,14.65,13.65,16,12,16z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_mic_none.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_mic_none.xml
new file mode 100644
index 0000000..15c2be7
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_mic_none.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.25,17.96v3.29c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-3.29c3.51-0.38,6.25-3.39,6.25-7.04 c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75c0,3.08-2.47,5.58-5.5,5.58S6.5,14,6.5,10.92c0-0.41-0.34-0.75-0.75-0.75 S5,10.5,5,10.92C5,14.57,7.74,17.58,11.25,17.96z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9,5v6c0,1.66,1.34,3,3,3s3-1.34,3-3V5c0-1.66-1.34-3-3-3S9,3.34,9,5z M13.5,5v6c0,0.83-0.67,1.5-1.5,1.5 s-1.5-0.67-1.5-1.5V5c0-0.83,0.67-1.5,1.5-1.5S13.5,4.17,13.5,5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml
new file mode 100644
index 0000000..752c33d
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 7.5 9.5 C 8.60456949966 9.5 9.5 10.3954305003 9.5 11.5 C 9.5 12.6045694997 8.60456949966 13.5 7.5 13.5 C 6.39543050034 13.5 5.5 12.6045694997 5.5 11.5 C 5.5 10.3954305003 6.39543050034 9.5 7.5 9.5 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,9h-8.63C11.46,7.22,9.63,6,7.5,6C7.16,6,6.81,6.03,6.46,6.1C4.32,6.49,2.57,8.18,2.13,10.3C1.38,13.86,4.07,17,7.5,17 c2.13,0,3.96-1.22,4.87-3H14v3h6v-3h1c0.55,0,1-0.45,1-1v-3C22,9.45,21.55,9,21,9z M20.5,12.5h-2v3h-3v-3h-4.14 c-0.45,1.72-2,3-3.86,3c-2.21,0-4-1.79-4-4s1.79-4,4-4c1.86,0,3.41,1.28,3.86,3h9.14V12.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
new file mode 100644
index 0000000..3e7c1d7
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="@*android:color/accent_device_default" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml
index 428d453..0a5abfe 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,18V11a9,9,0,0,0-9.6-9A9.21,9.21,0,0,0,3,11.31V17.2C3,19.66,4.34,21,6,21H8a1,1,0,0,0,1-1V14a1,1,0,0,0-1-1H5V11.29A7.19,7.19,0,0,1,11.79,4,7,7,0,0,1,19,11v2H16a1,1,0,0,0-1,1v6a1,1,0,0,0,1,1h2A3,3,0,0,0,21,18Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,18v-7c0-5.17-4.36-9.32-9.6-8.98C6.62,2.33,3,6.52,3,11.31v5.89C3,19.66,4.34,21,6,21h2c0.55,0,1-0.45,1-1v-6 c0-0.55-0.45-1-1-1H5v-1.71C5,7.45,7.96,4.11,11.79,4C15.76,3.89,19,7.06,19,11v2h-3c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h2 C19.66,21,21,19.66,21,18z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_expand_more.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_expand_more.xml
index 3ef7dd1..e7f09a1 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_expand_more.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_expand_more.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19.29,8.29a1,1,0,0,0-1.41,0L12,14.17,6.12,8.29A1,1,0,1,0,4.71,9.71l6.58,6.58a1,1,0,0,0,1.42,0l6.58-6.58A1,1,0,0,0,19.29,8.29Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M19.29,8.29c-0.39-0.39-1.02-0.39-1.41,0L12,14.17L6.12,8.29c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41 l6.59,6.59c0.39,0.39,1.02,0.39,1.41,0l6.59-6.59C19.68,9.32,19.68,8.68,19.29,8.29z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_faster_emergency.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_faster_emergency.xml
new file mode 100644
index 0000000..eecf698
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_faster_emergency.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorError" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:pathData="M0 0h24v24H0z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19 3H5c-1.1 0-1.99 0.9 -1.99 2L3 19c0 1.1 0.9 2 2 2h14c1.1 0 2-0.9 2-2V5c0-1.1-0.9-2-2-2zm-1 11h-4v4h-4v-4H6v-4h4V6h4v4h4v4z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_info_outline_24.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_info_outline_24.xml
index e39a2a0..9a17877 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_info_outline_24.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_info_outline_24.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2,12A10,10,0,1,0,12,2,10,10,0,0,0,2,12Zm11,5.42a1,1,0,0,1-2,0V10.68a1,1,0,0,1,2,0ZM12,5.58a1.35,1.35,0,1,1-1.35,1.35A1.34,1.34,0,0,1,12,5.58Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_invert_colors.xml
deleted file mode 100644
index 0564c73..0000000
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_invert_colors.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17.44,7.71,12.7,3a1,1,0,0,0-1.41,0h0L6.56,7.71a8.21,8.21,0,0,0-0.62,11.1,8,8,0,0,0,12.12,0A8.21,8.21,0,0,0,17.44,7.71ZM12,19.59A6,6,0,0,1,7.76,9.35L12,5.1Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml
new file mode 100644
index 0000000..13a5c0df
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4,10v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10c0-1.1-0.9-2-2-2h-2c0-1.1,0-2.36,0-3c0-2.21-1.79-4-4-4C9.79,1,8,2.79,8,5 c0,0.56,0,1.86,0,3H6C4.9,8,4,8.9,4,10z M12,17c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2s2,0.9,2,2C14,16.1,13.1,17,12,17z M10,5 c0-1.1,0.9-2,2-2s2,0.9,2,2v3h-4V5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_bugreport.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_bugreport.xml
new file mode 100644
index 0000000..de37f9f
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_bugreport.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M3,17c0,0.55,0.45,1,1,1h2.81c1.04,1.79,2.97,3,5.19,3s4.15-1.21,5.19-3H20c0.55,0,1-0.45,1-1s-0.45-1-1-1h-2.09 c0.05-0.33,0.09-0.66,0.09-1v-1h2c0.55,0,1-0.45,1-1s-0.45-1-1-1h-2v-1c0-0.34-0.04-0.67-0.09-1H20c0.55,0,1-0.45,1-1s-0.45-1-1-1 h-2.81c-0.45-0.78-1.07-1.45-1.82-1.96l0.93-0.93c0.39-0.39,0.39-1.02,0-1.41s-1.02-0.39-1.41,0l-1.47,1.47 C12.96,5.06,12.49,5,12,5s-0.96,0.06-1.41,0.17L9.12,3.7c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41l0.92,0.92 C7.88,6.55,7.26,7.22,6.81,8H4C3.45,8,3,8.45,3,9s0.45,1,1,1h2.09C6.04,10.33,6,10.66,6,11v1H4c-0.55,0-1,0.45-1,1s0.45,1,1,1h2v1 c0,0.34,0.04,0.67,0.09,1H4C3.45,16,3,16.45,3,17z M10,10h4v2h-4V10z M10,14h4v2h-4V14z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml
new file mode 100644
index 0000000..e1b5bad
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M18,1c-2.21,0-4,1.79-4,4v3H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10c0-1.1-0.9-2-2-2h-2V5 c0-1.1,0.9-2,2-2s2,0.9,2,2c0,0.55,0.45,1,1,1s1-0.45,1-1C22,2.79,20.21,1,18,1z M12,17c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2 s2,0.9,2,2C14,16.1,13.1,17,12,17z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_power_off.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_power_off.xml
new file mode 100644
index 0000000..ad46d1e
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_power_off.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,13c0.6,0,1-0.4,1-1V4c0-0.6-0.4-1-1-1s-1,0.4-1,1v8C11,12.6,11.4,13,12,13z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.6,5.9c-0.4-0.4-1.1-0.4-1.5,0c-0.4,0.4-0.4,1,0,1.4c1.3,1.4,2.1,3.4,1.8,5.6c-0.4,3.2-3,5.7-6.2,6.1 C8.6,19.4,5,16.1,5,12c0-1.8,0.7-3.5,1.9-4.8c0.4-0.4,0.4-1,0-1.4c-0.4-0.4-1-0.4-1.4,0C4,7.4,3.1,9.5,3,11.7 c-0.1,4.9,3.8,9.1,8.7,9.3c5.1,0.2,9.3-3.9,9.3-9C21,9.6,20.1,7.5,18.6,5.9z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
index 8b9f562..28ad305 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
@@ -1,55 +1,29 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,21H21a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2H3A2,2,0,0,0,1,6V19A2,2,0,0,0,3,21ZM3,6H21V19H3Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9 8 H 11 V 10 H 9 V 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5 8 H 7 V 10 H 5 V 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 8 16 H 16 V 17 H 8 V 16 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13 8 H 15 V 10 H 13 V 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9 12 H 11 V 14 H 9 V 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5 12 H 7 V 14 H 5 V 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13 12 H 15 V 14 H 13 V 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17 8 H 19 V 10 H 17 V 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17 12 H 19 V 14 H 17 V 12 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21,19H3V6h18V19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C11,8.22,10.78,8,10.5,8h-1C9.22,8,9,8.22,9,8.5v1C9,9.78,9.22,10,9.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5.5,10h1C6.78,10,7,9.78,7,9.5v-1C7,8.22,6.78,8,6.5,8h-1C5.22,8,5,8.22,5,8.5v1C5,9.78,5.22,10,5.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C15,8.22,14.78,8,14.5,8h-1C13.22,8,13,8.22,13,8.5v1C13,9.78,13.22,10,13.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1C9.22,12,9,12.22,9,12.5v1C9,13.78,9.22,14,9.5,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5.5,14h1C6.78,14,7,13.78,7,13.5v-1C7,12.22,6.78,12,6.5,12h-1C5.22,12,5,12.22,5,12.5v1C5,13.78,5.22,14,5.5,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C13,13.78,13.22,14,13.5,14 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,8.22,18.78,8,18.5,8h-1C17.22,8,17,8.22,17,8.5v1C17,9.78,17.22,10,17.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C17,13.78,17.22,14,17.5,14 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8.5,17h7c0.28,0,0.5-0.22,0.5-0.5S15.78,16,15.5,16h-7C8.22,16,8,16.22,8,16.5S8.22,17,8.5,17z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml
index 217845d..31d2de7 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20.71,7a1,1,0,0,0,0-1.41h0L18.37,3.29a1,1,0,0,0-1.41,0h0L15.13,5.12l3.75,3.75Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,18.08V20.5a0.5 0.5 ,0,0,0,0.5 0.5 H5.92a2,2,0,0,0,1.41-0.59L17.81,9.94,14.06,6.19,3.59,16.66A2,2,0,0,0,3,18.08Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M3.29,16.96C3.11,17.14,3,17.4,3,17.66v2.84C3,20.78,3.22,21,3.5,21h2.84c0.27,0,0.52-0.11,0.71-0.29L17.81,9.94 l-3.75-3.75L3.29,16.96z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.71,5.63C20.71,5.63,20.71,5.63,20.71,5.63l-2.34-2.34c-0.39-0.39-1.02-0.39-1.41,0c0,0,0,0,0,0l-1.83,1.83l3.75,3.75 l1.83-1.83C21.1,6.65,21.1,6.02,20.71,5.63z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml
index 2eaa368..6a3d3b8 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M9.78,7.06,9.13,3.8a1,1,0,0,0-1-0.8H4A1,1,0,0,0,3,4a17.92,17.92,0,0,0,2.43,8,18.08,18.08,0,0,0,6.5,6.5,17.92,17.92,0,0,0,8,2.43,1,1,0,0,0,1-1V15.82a1,1,0,0,0-0.8-1l-3.26-0.65a1,1,0,0,0-0.9 0.27 l-2.62,2.62a16.14,16.14,0,0,1-6.5-6.5L9.51,8A1,1,0,0,0,9.78,7.06Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M9.78,7.06L9.13,3.8C9.04,3.34,8.63,3,8.15,3H4C3.44,3,2.97,3.47,3,4.03c0.17,2.91,1.04,5.63,2.43,8.01 c1.57,2.69,3.81,4.93,6.5,6.5c2.38,1.39,5.1,2.26,8.01,2.43c0.56,0.03,1.03-0.44,1.03-1v-4.15c0-0.48-0.34-0.89-0.8-0.98 l-3.26-0.65c-0.33-0.07-0.67,0.04-0.9,0.27l-2.62,2.62c-2.75-1.49-5.01-3.75-6.5-6.5l2.62-2.62C9.75,7.72,9.85,7.38,9.78,7.06z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_airplane.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_airplane.xml
new file mode 100644
index 0000000..92ea82b
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_airplane.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.65,15.8L10,13.5V19l-1.6,1.2C8.15,20.39,8,20.69,8,21v0.67c0,0.17,0.14,0.28,0.31,0.24c1.94-0.55,1.3-0.37,3.19-0.91 c1.21,0.35,1.99,0.57,3.19,0.91c0.17,0.04,0.31-0.07,0.31-0.24V21c0-0.31-0.15-0.61-0.4-0.8L13,19v-5.5l7.35,2.3 c0.32,0.1,0.65-0.14,0.65-0.48v-0.49c0-0.52-0.27-1-0.7-1.27L13,9V3.5C13,2.67,12.33,2,11.5,2S10,2.67,10,3.5V9l-7.3,4.56 C2.27,13.83,2,14.31,2,14.83v0.49C2,15.66,2.33,15.9,2.65,15.8z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml
new file mode 100644
index 0000000..f5d52d1
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M16.41,10.96h2.83l-8.18-8.18c-0.62-0.62-1.65-0.6-2.29,0.04L4.27,7.31L2.85,5.89C2.54,5.58,2,5.8,2,6.25v4.25 C2,10.78,2.22,11,2.5,11h4.25c0.45,0,0.67-0.54,0.35-0.85L5.69,8.73l4.24-4.24L16.41,10.96z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22,13.51c0-0.28-0.22-0.5-0.5-0.5h-4.25c-0.45,0-0.67,0.54-0.35,0.85l1.34,1.34l-4.31,4.31l-6.48-6.48H4.61l8.19,8.19 c0.62,0.62,1.65,0.6,2.29-0.04l4.57-4.55l1.49,1.49c0.32,0.31,0.85,0.09,0.85-0.35V13.51z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
new file mode 100644
index 0000000..2749ec6
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_dnd.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_dnd.xml
new file mode 100644
index 0000000..88f2bab
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_dnd.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,22c5.52,0,10-4.48,10-10c0-5.52-4.48-10-10-10S2,6.48,2,12C2,17.52,6.48,22,12,22z M8,11h8c0.55,0,1,0.45,1,1 s-0.45,1-1,1H8c-0.55,0-1-0.45-1-1S7.45,11,8,11z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_flashlight.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_flashlight.xml
new file mode 100644
index 0000000..fa701de
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_flashlight.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M10,22h4c0.55,0,1-0.45,1-1V10c1.1,0,2-0.9,2-2V5.5H7V8c0,1.1,0.9,2,2,2v11C9,21.55,9.45,22,10,22z M11,12 c0-0.55,0.45-1,1-1s1,0.45,1,1v2c0,0.55-0.45,1-1,1s-1-0.45-1-1V12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17,3c0-0.55-0.45-1-1-1H8C7.45,2,7,2.45,7,3v0.96h10V3z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_night_display_on.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_night_display_on.xml
index f12beec..d4f3484 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_night_display_on.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_night_display_on.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17.32,4.13a1,1,0,0,0-0.19-1.9A10,10,0,1,0,15,22a9.91,9.91,0,0,0,2.12-0.23,1,1,0,0,0,0.2-1.9,8.48,8.48,0,0,1,0-15.74Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21.82,16.31c-0.17-0.25-0.47-0.38-0.76-0.32c-0.71,0.13-1.37,0.19-2.03,0.19c-6.19,0-11.22-5.05-11.22-11.26 C7.81,4.27,7.87,3.6,8,2.88c0.05-0.3-0.08-0.59-0.33-0.76c-0.25-0.17-0.58-0.16-0.83,0C3.81,4.14,2,7.52,2,11.16 C2,17.14,6.85,22,12.8,22c3.63,0,7-1.82,9.01-4.87C21.98,16.88,21.98,16.56,21.82,16.31z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_restart.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_restart.xml
new file mode 100644
index 0000000..f0b9db4
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_restart.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M6,12c0-0.71,0.11-1.34,0.35-1.93c0.2-0.51-0.05-1.09-0.56-1.3c-0.52-0.21-1.1,0.05-1.3,0.56C4.16,10.16,4,11.03,4,12 c0,4.07,3.06,7.44,7,7.94v-2.03C8.17,17.43,6,14.97,6,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.01,4V1.72c0-0.45-0.54-0.67-0.86-0.35L7.43,5.13c-0.2,0.2-0.19,0.53,0.02,0.72l3.73,3.45 c0.32,0.3,0.84,0.07,0.84-0.37V6C15.32,6.01,18,8.69,18,12c0,2.97-2.17,5.43-5,5.91v2.03c3.94-0.5,7-3.86,7-7.94 C20,7.59,16.42,4.01,12.01,4z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_screenshot.xml
new file mode 100644
index 0000000..da10874
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_screenshot.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17,23c1.1,0,2-0.9,2-2V3c0-1.1-0.9-2-2-2H7C5.9,1,5,1.9,5,3v18c0,1.1,0.9,2,2,2H17z M7,4h10v16H7V4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M11.25,5H9C8.45,5,8,5.45,8,6v2.25C8,8.66,8.34,9,8.75,9S9.5,8.66,9.5,8.25V6.5h1.75C11.66,6.5,12,6.16,12,5.75 C12,5.34,11.66,5,11.25,5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15.25,15c-0.41,0-0.75,0.34-0.75,0.75v1.75h-1.75c-0.41,0-0.75,0.34-0.75,0.75c0,0.41,0.34,0.75,0.75,0.75H15 c0.55,0,1-0.45,1-1v-2.25C16,15.34,15.66,15,15.25,15z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
new file mode 100644
index 0000000..2749ec6
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_signal_location.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_signal_location.xml
index 1d107b9..c759080 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_signal_location.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_signal_location.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,2A7,7,0,0,0,5,9c0,4.17,4.42,9.92,6.24,12.11a1,1,0,0,0,1.53,0C14.58,18.92,19,13.17,19,9A7,7,0,0,0,12,2Zm0,9.5A2.5,2.5,0,1,1,14.5,9,2.5,2.5,0,0,1,12,11.5Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12.77,21.11C14.58,18.92,19,13.17,19,9c0-3.87-3.13-7-7-7S5,5.13,5,9c0,4.17,4.42,9.92,6.24,12.11 C11.64,21.59,12.37,21.59,12.77,21.11z M9.5,9c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5c0,1.38-1.12,2.5-2.5,2.5S9.5,10.38,9.5,9z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_0.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_0.xml
index 0f7c589..01a0a28 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_0.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_0.xml
@@ -1,31 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M23.66,8.11c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_1.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_1.xml
index aa13b7e..86a0a71 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_1.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_1.xml
@@ -1,34 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.82,21.6l5.11-6.36a9,9,0,0,0-11.87,0l5.1,6.35A1.07,1.07,0,0,0,12.82,21.6Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M23.66,8.11c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.82,21.6l5.11-6.36C16.29,13.79,14.18,13,12,13c-2.28,0-4.35,0.85-5.94,2.25l5.1,6.35 C11.59,22.13,12.39,22.13,12.82,21.6z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_2.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_2.xml
index b6d1b72..243d9db 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_2.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_2.xml
@@ -1,34 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.82,21.6l7-8.7a12,12,0,0,0-15.63,0l7,8.7A1.07,1.07,0,0,0,12.82,21.6Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M23.66,8.11c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.82,21.6l6.99-8.7C17.71,11.1,14.99,10,12,10s-5.72,1.1-7.82,2.91l6.98,8.7C11.59,22.13,12.39,22.13,12.82,21.6z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_3.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_3.xml
index fe57182..c054b22 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_3.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_3.xml
@@ -1,34 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.82,21.6l8.25-10.26a14,14,0,0,0-18.14,0l8.23,10.26A1.07,1.07,0,0,0,12.82,21.6Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M23.66,8.11c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.82,21.6l8.25-10.26C18.54,9.18,15.32,8,12,8c-3.46,0-6.63,1.26-9.07,3.35l8.23,10.26 C11.59,22.13,12.39,22.13,12.82,21.6z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_4.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_4.xml
index d8aa0c2..ee26fc7 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_4.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_wifi_signal_4.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,3A20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L23.66,8.11a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,3C6.44,3,2.33,5.36,0.56,6.57C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L23.66,8.11 c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_empty_recents.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_empty_recents.xml
deleted file mode 100644
index 1d4c8d7..0000000
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_empty_recents.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17,18V6c0-1.1-0.9-2-2-2H9C7.9,4,7,4.9,7,6v12c0,1.1,0.9,2,2,2h6C16.1,20,17,19.1,17,18z M8.5,18V6 c0-0.28,0.22-0.5,0.5-0.5h6c0.28,0,0.5,0.22,0.5,0.5v12c0,0.28-0.22,0.5-0.5,0.5H9C8.72,18.5,8.5,18.28,8.5,18z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,17c0.55,0,1-0.45,1-1V8c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1v8c0,0.55,0.45,1,1,1H21z M19.5,8.5h1v7h-1V8.5z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M5,7H3C2.45,7,2,7.45,2,8v8c0,0.55,0.45,1,1,1h2c0.55,0,1-0.45,1-1V8C6,7.45,5.55,7,5,7z M4.5,15.5h-1v-7h1V15.5z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_airplanemode_active.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_airplanemode_active.xml
new file mode 100644
index 0000000..ebd7a28
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_airplanemode_active.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.65,15.8L10,13.5V19l-1.6,1.2C8.15,20.39,8,20.69,8,21v0.67c0,0.17,0.14,0.28,0.31,0.24c1.94-0.55,1.3-0.37,3.19-0.91 c1.21,0.35,1.99,0.57,3.19,0.91c0.17,0.04,0.31-0.07,0.31-0.24V21c0-0.31-0.15-0.61-0.4-0.8L13,19v-5.5l7.35,2.3 c0.32,0.1,0.65-0.14,0.65-0.48v-0.49c0-0.52-0.27-1-0.7-1.27L13,9V3.5C13,2.67,12.33,2,11.5,2S10,2.67,10,3.5V9l-7.3,4.56 C2.27,13.83,2,14.31,2,14.83v0.49C2,15.66,2.33,15.9,2.65,15.8z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml
index 015e73e..670e181 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml
@@ -1,52 +1,28 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 4.5 4 L 7.5 4 Q 8 4 8 4.5 L 8 7.5 Q 8 8 7.5 8 L 4.5 8 Q 4 8 4 7.5 L 4 4.5 Q 4 4 4.5 4 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 10.5 4 L 13.5 4 Q 14 4 14 4.5 L 14 7.5 Q 14 8 13.5 8 L 10.5 8 Q 10 8 10 7.5 L 10 4.5 Q 10 4 10.5 4 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 16.5 4 L 19.5 4 Q 20 4 20 4.5 L 20 7.5 Q 20 8 19.5 8 L 16.5 8 Q 16 8 16 7.5 L 16 4.5 Q 16 4 16.5 4 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 4.5 10 L 7.5 10 Q 8 10 8 10.5 L 8 13.5 Q 8 14 7.5 14 L 4.5 14 Q 4 14 4 13.5 L 4 10.5 Q 4 10 4.5 10 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 10.5 10 L 13.5 10 Q 14 10 14 10.5 L 14 13.5 Q 14 14 13.5 14 L 10.5 14 Q 10 14 10 13.5 L 10 10.5 Q 10 10 10.5 10 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 16.5 10 L 19.5 10 Q 20 10 20 10.5 L 20 13.5 Q 20 14 19.5 14 L 16.5 14 Q 16 14 16 13.5 L 16 10.5 Q 16 10 16.5 10 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 4.5 16 L 7.5 16 Q 8 16 8 16.5 L 8 19.5 Q 8 20 7.5 20 L 4.5 20 Q 4 20 4 19.5 L 4 16.5 Q 4 16 4.5 16 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 10.5 16 L 13.5 16 Q 14 16 14 16.5 L 14 19.5 Q 14 20 13.5 20 L 10.5 20 Q 10 20 10 19.5 L 10 16.5 Q 10 16 10.5 16 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 16.5 16 L 19.5 16 Q 20 16 20 16.5 L 20 19.5 Q 20 20 19.5 20 L 16.5 20 Q 16 20 16 19.5 L 16 16.5 Q 16 16 16.5 16 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M7.5,4h-3C4.22,4,4,4.22,4,4.5v3C4,7.78,4.22,8,4.5,8h3C7.78,8,8,7.78,8,7.5v-3C8,4.22,7.78,4,7.5,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,4h-3C10.22,4,10,4.22,10,4.5v3C10,7.78,10.22,8,10.5,8h3C13.78,8,14,7.78,14,7.5v-3C14,4.22,13.78,4,13.5,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.5,4h-3C16.22,4,16,4.22,16,4.5v3C16,7.78,16.22,8,16.5,8h3C19.78,8,20,7.78,20,7.5v-3C20,4.22,19.78,4,19.5,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M7.5,10h-3C4.22,10,4,10.22,4,10.5v3C4,13.78,4.22,14,4.5,14h3C7.78,14,8,13.78,8,13.5v-3C8,10.22,7.78,10,7.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,10h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C14,10.22,13.78,10,13.5,10 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.5,10h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C20,10.22,19.78,10,19.5,10 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M7.5,16h-3C4.22,16,4,16.22,4,16.5v3C4,19.78,4.22,20,4.5,20h3C7.78,20,8,19.78,8,19.5v-3C8,16.22,7.78,16,7.5,16z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,16h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C14,16.22,13.78,16,13.5,16 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.5,16h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C20,16.22,19.78,16,19.5,16 z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml
new file mode 100644
index 0000000..103985b
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11,11H9c-0.55,0-1,0.45-1,1s0.45,1,1,1h2v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2h2c0.55,0,1-0.45,1-1s-0.45-1-1-1h-2V9 c0-0.55-0.45-1-1-1s-1,0.45-1,1V11z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13,2.05v2.52c3.66,0.49,6.5,3.63,6.5,7.43c0,1.01-0.2,1.97-0.56,2.85l2.18,1.26C21.68,14.85,22,13.46,22,12 C22,6.81,18.05,2.55,13,2.05z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,19.5c-4.14,0-7.5-3.36-7.5-7.5c0-3.8,2.84-6.93,6.5-7.43V2.05C5.95,2.55,2,6.81,2,12c0,5.52,4.48,10,10,10 c3.34,0,6.3-1.65,8.11-4.17l-2.18-1.26C16.56,18.35,14.41,19.5,12,19.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
index 0b12655..f5be375 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M3,20H6a1,1,0,0,0,0-2H3V6H20a1,1,0,0,0,0-2H3A2,2,0,0,0,1,6V18A2,2,0,0,0,3,20Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M23,19V9a1.08,1.08,0,0,0-1-1H16a1.08,1.08,0,0,0-1,1V19a1.08,1.08,0,0,0,1,1h6A1.08,1.08,0,0,0,23,19Zm-2-1H17V10h4Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M9,12v1.78a3,3,0,0,0,0,4.44V20h4V18.22a3,3,0,0,0,0-4.44V12Zm2,5.5A1.5,1.5,0,1,1,12.5,16,1.5,1.5,0,0,1,11,17.5Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M6,18H3V6h17c0.55,0,1-0.45,1-1s-0.45-1-1-1H3C1.9,4,1,4.9,1,6v12c0,1.1,0.9,2,2,2h3c0.55,0,1-0.45,1-1S6.55,18,6,18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13,12H9v1.78C8.39,14.33,8,15.11,8,16s0.39,1.67,1,2.22V20h4v-1.78c0.61-0.55,1-1.34,1-2.22s-0.39-1.67-1-2.22V12z M11,17.5c-0.83,0-1.5-0.67-1.5-1.5c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C12.5,16.83,11.83,17.5,11,17.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22,8h-6c-0.5,0-1,0.5-1,1v10c0,0.5,0.5,1,1,1h6c0.5,0,1-0.5,1-1V9C23,8.5,22.5,8,22,8z M21,18h-4v-8h4V18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml
index 097894d..7b41ed4 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm0,16.81a1.3,1.3,0,1,1,1.3-1.3A1.3,1.3,0,0,1,12,18.81Zm1.07-4.62a1,1,0,0,1-1.13 0.79 ,1,1,0,0,1-0.83-1.23c0.52-2.61,2.66-2.84,2.87-4.5a2,2,0,0,0-1.34-2.17,2,2,0,0,0-2.55,1.37,1,1,0,1,1-1.93-0.53A4,4,0,0,1,16,9.13C15.92,11.57,13.5,11.74,13.07,14.19Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,22c5.52,0,10-4.48,10-10c0-5.52-4.48-10-10-10S2,6.48,2,12C2,17.52,6.48,22,12,22z M12,18.96 c-0.69,0-1.25-0.56-1.25-1.25c0-0.69,0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25C13.25,18.4,12.69,18.96,12,18.96z M8.16,7.92 c0.63-2.25,2.91-3.38,5.05-2.74c1.71,0.51,2.84,2.16,2.78,3.95c-0.07,2.44-2.49,2.61-2.92,5.06c-0.09,0.52-0.59,0.87-1.13,0.79 c-0.57-0.08-0.94-0.66-0.83-1.23c0.52-2.61,2.66-2.84,2.87-4.5c0.12-0.96-0.42-1.87-1.34-2.17c-1.04-0.33-2.21,0.16-2.55,1.37 C9.97,8.9,9.57,9.19,9.12,9.19C8.46,9.19,7.99,8.56,8.16,7.92z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml
index 80f3d1e7..c6b3d04 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M7,1A2,2,0,0,0,5,3V21a2,2,0,0,0,2,2H17a2,2,0,0,0,2-2V3a2,2,0,0,0-2-2ZM17,19H7V5H17Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,11.62a1,1,0,0,0-1,0.9v3.59a1,1,0,0,0,2,0V12.52A1,1,0,0,0,12,11.62Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 7.06 C 12.6903559373 7.06 13.25 7.61964406271 13.25 8.31 C 13.25 9.00035593729 12.6903559373 9.56 12 9.56 C 11.3096440627 9.56 10.75 9.00035593729 10.75 8.31 C 10.75 7.61964406271 11.3096440627 7.06 12 7.06 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17,1.01L7,1C5.9,1,5,1.9,5,3v18c0,1.1,0.9,2,2,2h10c1.1,0,2-0.9,2-2V3C19,1.9,18.1,1.01,17,1.01z M17,19H7V5h10V19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.6903559373 7 13.25 7.55964406271 13.25 8.25 C 13.25 8.94035593729 12.6903559373 9.5 12 9.5 C 11.3096440627 9.5 10.75 8.94035593729 10.75 8.25 C 10.75 7.55964406271 11.3096440627 7 12 7 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,11c-0.55,0-1,0.4-1,0.9v4.21c0,0.5,0.45,0.9,1,0.9s1-0.4,1-0.9V11.9C13,11.4,12.55,11,12,11z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml
index 9c8287b..93df380 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -1,40 +1,24 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M20.76,5l0-0.06a1,1,0,0,0-1.2-0.72A35.66,35.66,0,0,1,12,5a35.66,35.66,0,0,1-7.54-0.76A1,1,0,0,0,3.26,5l0,0.06A1,1,0,0,0,4,6.24,37,37,0,0,0,9,7V19a1,1,0,0,0,2,0V14h2v5a1,1,0,0,0,2,0V7a37,37,0,0,0,5-0.76A1,1,0,0,0,20.76,5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.76,5.02l-0.02-0.06c-0.13-0.53-0.67-0.85-1.2-0.73C17.16,4.77,14.49,5,12,5S6.84,4.77,4.46,4.24 c-0.54-0.12-1.07,0.19-1.2,0.73L3.24,5.02C3.11,5.56,3.43,6.12,3.97,6.24C5.59,6.61,7.34,6.86,9,7v12c0,0.55,0.45,1,1,1 s1-0.45,1-1v-5h2v5c0,0.55,0.45,1,1,1s1-0.45,1-1V7c1.66-0.14,3.41-0.39,5.03-0.76C20.57,6.12,20.89,5.56,20.76,5.02z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml
index ea418a8..77ec8ea 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -1,31 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,4a8,8,0,0,1,6.36,12.83c-1.43-1.74-4.9-2.33-6.36-2.33s-4.93 0.59 -6.36,2.33A8,8,0,0,1,12,4Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 6 C 13.9329966244 6 15.5 7.56700337559 15.5 9.5 C 15.5 11.4329966244 13.9329966244 13 12 13 C 10.0670033756 13 8.5 11.4329966244 8.5 9.5 C 8.5 7.56700337559 10.0670033756 6 12 6 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,6c1.93,0,3.5,1.57,3.5,3.5S13.93,13,12,13 s-3.5-1.57-3.5-3.5S10.07,6,12,6z M12,20c-2.65,0-5-1.3-6.46-3.29C5.88,16.43,8.29,14.5,12,14.5s6.12,1.93,6.46,2.21 C17,18.7,14.65,20,12,20z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml
index 1c5df00..08f27c4 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M10,2V4H8.33A1.34,1.34,0,0,0,7,5.33V20.66A1.34,1.34,0,0,0,8.33,22h7.33A1.34,1.34,0,0,0,17,20.67V5.33A1.34,1.34,0,0,0,15.67,4H14V2Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M10,2v2H8.33C7.6,4,7,4.6,7,5.33v15.33C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V5.33C17,4.6,16.4,4,15.67,4 H14V2H10z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_delete.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_delete.xml
new file mode 100644
index 0000000..c59fb59
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_delete.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M18,4h-2.5l-0.71-0.71C14.61,3.11,14.35,3,14.09,3H9.9C9.64,3,9.38,3.11,9.2,3.29L8.49,4h-2.5c-0.55,0-1,0.45-1,1 s0.45,1,1,1h12c0.55,0,1-0.45,1-1C19,4.45,18.55,4,18,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml
index 02e15d2..3b32cbf 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M4,15.3V19a1,1,0,0,0,1,1H8.69l2.6,2.6a1,1,0,0,0,1.41,0L15.3,20H19a1,1,0,0,0,1-1V15.31l2.6-2.6a1,1,0,0,0,0-1.41L20,8.69V5a1,1,0,0,0-1-1H15.31l-2.6-2.6a1,1,0,0,0-1.41,0L8.69,4H5A1,1,0,0,0,4,5V8.69l-2.6,2.6a1,1,0,0,0,0,1.41ZM12,6a6,6,0,0,1,0,12Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4,15.3V19c0,0.55,0.45,1,1,1h3.69l2.6,2.6c0.39,0.39,1.02,0.39,1.41,0l2.6-2.6H19c0.55,0,1-0.45,1-1v-3.69l2.6-2.6 c0.39-0.39,0.39-1.02,0-1.41L20,8.69V5c0-0.55-0.45-1-1-1h-3.69l-2.6-2.6c-0.39-0.39-1.02-0.39-1.41,0L8.69,4H5C4.45,4,4,4.45,4,5 v3.69l-2.6,2.6c-0.39,0.39-0.39,1.02,0,1.41L4,15.3z M12,6c3.31,0,6,2.69,6,6s-2.69,6-6,6V6z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml
index 818236b..c759080 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,2A7,7,0,0,0,5,9c0,4.17,4.42,9.92,6.24,12.11a1,1,0,0,0,1.53,0C14.58,18.92,19,13.17,19,9A7,7,0,0,0,12,2Zm0,9.5A2.5,2.5,0,1,1,14.5,9,2.5,2.5,0,0,1,12,11.5Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12.77,21.11C14.58,18.92,19,13.17,19,9c0-3.87-3.13-7-7-7S5,5.13,5,9c0,4.17,4.42,9.92,6.24,12.11 C11.64,21.59,12.37,21.59,12.77,21.11z M9.5,9c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5c0,1.38-1.12,2.5-2.5,2.5S9.5,10.38,9.5,9z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml
index b080882..9b74c81 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,19a12,12,0,0,0,2-0.17v-2A10.13,10.13,0,0,1,12,17a9.77,9.77,0,0,1-8.82-5.5,9.82,9.82,0,0,1,17.64,0H23a11.82,11.82,0,0,0-22,0A11.83,11.83,0,0,0,12,19Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M16.5,11.5a4.55,4.55,0,1,0-2.38,3.95,5,5,0,0,1,2.31-3.22A4.4,4.4,0,0,0,16.5,11.5ZM12,14.2a2.7,2.7,0,1,1,2.7-2.7A2.7,2.7,0,0,1,12,14.2Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M23,21V17a1.08,1.08,0,0,0-1-1v-0.5a2.5,2.5,0,0,0-5,0V16a1.08,1.08,0,0,0-1,1v4a1.08,1.08,0,0,0,1,1h5A1.08,1.08,0,0,0,23,21Zm-2.5-5h-2v-0.5a1,1,0,0,1,2,0Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M16.48,11.7c0.74-0.44,1.6-0.7,2.52-0.7h3.78C20.93,6.88,16.81,4,12,4C7,4,2.73,7.11,1,11.5C2.73,15.89,7,19,12,19 c0.68,0,1.35-0.06,2-0.17V16c0-0.18,0.03-0.34,0.05-0.51C13.43,15.8,12.74,16,12,16c-2.49,0-4.5-2.01-4.5-4.5 C7.5,9.01,9.51,7,12,7s4.5,2.01,4.5,4.5C16.5,11.57,16.48,11.64,16.48,11.7z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 9 C 13.3807118746 9 14.5 10.1192881254 14.5 11.5 C 14.5 12.8807118746 13.3807118746 14 12 14 C 10.6192881254 14 9.5 12.8807118746 9.5 11.5 C 9.5 10.1192881254 10.6192881254 9 12 9 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22,16v-0.5c0-1.4-1.1-2.5-2.5-2.5S17,14.1,17,15.5V16c-0.5,0-1,0.5-1,1v4c0,0.5,0.5,1,1,1h5c0.5,0,1-0.5,1-1v-4 C23,16.5,22.5,16,22,16z M20.5,16h-2v-0.5c0-0.53,0.47-1,1-1s1,0.47,1,1V16z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml
index 39ac0d7..9f1bd70 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M23,6a1,1,0,0,0,0.92-1.2A5,5,0,0,0,18.57,1a5.15,5.15,0,0,0-4.51,5.19V8H6a2,2,0,0,0-2,2V20a2,2,0,0,0,2,2H18a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2H16V6.12A3.18,3.18,0,0,1,18.44,3a3.1,3.1,0,0,1,3.62,2.27A1,1,0,0,0,23,6ZM12,17a2,2,0,1,1,2-2A2,2,0,0,1,12,17Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M18,1c-2.21,0-4,1.79-4,4v3H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10c0-1.1-0.9-2-2-2h-2V5 c0-1.1,0.9-2,2-2s2,0.9,2,2c0,0.55,0.45,1,1,1s1-0.45,1-1C22,2.79,20.21,1,18,1z M12,17c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2 s2,0.9,2,2C14,16.1,13.1,17,12,17z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
index 3c29998..9a17877 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M2,12A10,10,0,1,0,12,2,10,10,0,0,0,2,12Zm11,5.42a1,1,0,0,1-2,0V10.68a1,1,0,0,1,2,0ZM12,5.58a1.35,1.35,0,1,1-1.35,1.35A1.34,1.34,0,0,1,12,5.58Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
index 8fa846e..96fa695 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M11.29,19.29a1,1,0,0,0,1.42,0L14,18a1,1,0,0,0-0.22-1.58A3.92,3.92,0,0,0,12,16a4,4,0,0,0-1.77 0.41 A1,1,0,0,0,10,18Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M17.6,14.39l0.71-0.71a1,1,0,0,0-0.08-1.49,10,10,0,0,0-12.44,0,1,1,0,0,0-0.08,1.49l0.7 0.72 a1,1,0,0,0,1.32 0.08 A6.91,6.91,0,0,1,12,13a7,7,0,0,1,4.29,1.47A1,1,0,0,0,17.6,14.39Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M21.83,10.16l0.71-0.71A1,1,0,0,0,22.48,8a15.79,15.79,0,0,0-20.92,0,1,1,0,0,0-0.07,1.47l0.71 0.71 a1,1,0,0,0,1.35 0.07 ,12.79,12.79,0,0,1,16.94,0A1,1,0,0,0,21.83,10.16Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.29,19.29c0.39,0.39,1.03,0.4,1.42,0L14,18c0.47-0.47,0.38-1.28-0.22-1.58C13.25,16.15,12.64,16,12,16 c-0.64,0-1.24,0.15-1.77,0.41c-0.59,0.29-0.69,1.11-0.22,1.58L11.29,19.29z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.6,14.39l0.71-0.71c0.42-0.42,0.39-1.12-0.08-1.5C16.52,10.82,14.35,10,12,10c-2.34,0-4.5,0.81-6.21,2.17 c-0.47,0.37-0.51,1.07-0.09,1.49l0.71,0.71c0.35,0.36,0.92,0.39,1.32,0.08C8.91,13.54,10.39,13,12,13c1.61,0,3.1,0.55,4.29,1.47 C16.69,14.78,17.25,14.75,17.6,14.39z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.83,10.16l0.71-0.71c0.42-0.42,0.38-1.09-0.06-1.48C19.68,5.5,16.01,4,12,4C8.01,4,4.36,5.49,1.56,7.94 C1.12,8.33,1.08,9,1.49,9.41l0.71,0.71c0.37,0.37,0.96,0.4,1.35,0.06C5.81,8.2,8.77,7,12,7c3.25,0,6.22,1.22,8.49,3.22 C20.88,10.56,21.47,10.53,21.83,10.16z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml
index 82733b6..0d56332 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M4,14H20a2,2,0,0,0,0-4H4a2,2,0,0,0,0,4Zm1-3.1A1.1,1.1,0,1,1,3.9,12,1.1,1.1,0,0,1,5,10.9Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M4,8H20a2,2,0,0,0,0-4H4A2,2,0,0,0,4,8ZM5,4.9A1.1,1.1,0,1,1,3.9,6,1.1,1.1,0,0,1,5,4.9Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M4,20H20a2,2,0,0,0,0-4H4a2,2,0,0,0,0,4Zm1-3.1A1.1,1.1,0,1,1,3.9,18,1.1,1.1,0,0,1,5,16.9Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M19,10H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,10.9,20.1,10,19,10z M6,13.1c-0.61,0-1.1-0.49-1.1-1.1 s0.49-1.1,1.1-1.1s1.1,0.49,1.1,1.1S6.61,13.1,6,13.1z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,18c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14C20.1,20,21,19.1,21,18z M6,19.1c-0.61,0-1.1-0.49-1.1-1.1 s0.49-1.1,1.1-1.1s1.1,0.49,1.1,1.1S6.61,19.1,6,19.1z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19,4H5C3.9,4,3,4.9,3,6c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,4.9,20.1,4,19,4z M6,7.1C5.39,7.1,4.9,6.61,4.9,6 S5.39,4.9,6,4.9S7.1,5.39,7.1,6S6.61,7.1,6,7.1z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
index 9587e54..5cd1acd 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M10.29,5.7,7,9H4a1,1,0,0,0-1,1v4a1,1,0,0,0,1,1H7l3.29,3.29A1,1,0,0,0,12,17.58V6.41A1,1,0,0,0,10.29,5.7Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M16.5,12A4.5,4.5,0,0,0,14,8V16A4.47,4.47,0,0,0,16.5,12Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M14,19.54a0.91 0.91 ,0,0,0,1.22 0.86 ,9,9,0,0,0,0-16.8A0.91 0.91 ,0,0,0,14,4.46v0.19a0.92 0.92 ,0,0,0,0.61 0.85 ,7,7,0,0,1,0,13,0.92 0.92 ,0,0,0-0.61 0.85 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.4,8.78c-0.91-2.39-2.8-4.27-5.18-5.18C14.63,3.37,14,3.83,14,4.46v0.19c0,0.38,0.25,0.71,0.61,0.85 C17.18,6.54,19,9.06,19,12s-1.82,5.46-4.39,6.5C14.25,18.64,14,18.97,14,19.35v0.19c0,0.63,0.63,1.08,1.22,0.86 C19.86,18.62,22.18,13.42,20.4,8.78z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.5,12c0-1.71-0.97-3.27-2.5-4.03v8.05C15.48,15.29,16.5,13.77,16.5,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M10.29,5.7L7,9H4c-0.55,0-1,0.45-1,1v4c0,0.55,0.45,1,1,1h3l3.29,3.29c0.63,0.63,1.71,0.18,1.71-0.71V6.41 C12,5.52,10.92,5.07,10.29,5.7z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml
index 84c347b..43ca3cfae 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_wifi_tethering.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M15.46,16.46h0A1,1,0,0,0,17,16.35,5.9,5.9,0,0,0,18,13,6,6,0,1,0,7,16.35a1,1,0,0,0,1.51 0.11 h0a1,1,0,0,0,0.11-1.29A3.9,3.9,0,0,1,8,12.44a4,4,0,1,1,7.32,2.73A1,1,0,0,0,15.46,16.46Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M10.86,3.06A10,10,0,0,0,4.19,19.25a1,1,0,0,0,1.49 0.07 A1,1,0,0,0,5.75,18a8.05,8.05,0,0,1-1.59-6.61A8,8,0,0,1,20,13a7.89,7.89,0,0,1-1.77,5,1,1,0,0,0,0.08,1.31h0a1,1,0,0,0,1.49-0.07A9.9,9.9,0,0,0,22,13,10,10,0,0,0,10.86,3.06Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M10,13a2,2,0,1,0,2-2A2,2,0,0,0,10,13Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M15.46,16.46L15.46,16.46c0.44,0.44,1.17,0.4,1.51-0.1C17.62,15.4,18,14.25,18,13c0-3.75-3.45-6.7-7.34-5.86 c-2.24,0.48-4.04,2.3-4.52,4.54c-0.37,1.75,0.02,3.38,0.89,4.67c0.34,0.51,1.08,0.54,1.51,0.11l0.01-0.01 c0.34-0.34,0.37-0.88,0.1-1.28c-0.5-0.76-0.75-1.71-0.61-2.74c0.23-1.74,1.67-3.17,3.41-3.4C13.9,8.71,16,10.61,16,13 c0,0.8-0.24,1.54-0.64,2.17C15.09,15.58,15.11,16.11,15.46,16.46z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M10.86,3.06c-4.65,0.51-8.39,4.34-8.82,9c-0.25,2.72,0.6,5.25,2.15,7.18c0.37,0.46,1.07,0.49,1.49,0.07 C6.04,18.96,6.07,18.4,5.75,18c-1.4-1.75-2.09-4.1-1.6-6.61c0.61-3.13,3.14-5.65,6.28-6.24C15.54,4.18,20,8.07,20,13 c0,1.9-0.66,3.63-1.77,5c-0.32,0.39-0.28,0.96,0.08,1.31l0,0c0.42,0.42,1.12,0.39,1.49-0.08c1.38-1.7,2.2-3.88,2.2-6.24 C22,7.1,16.89,2.4,10.86,3.06z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 11 C 13.1045694997 11 14 11.8954305003 14 13 C 14 14.1045694997 13.1045694997 15 12 15 C 10.8954305003 15 10 14.1045694997 10 13 C 10 11.8954305003 10.8954305003 11 12 11 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm.xml
new file mode 100644
index 0000000..a80cd71
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4.1,6.6l3-2.6c0.4-0.3,0.5-1,0.1-1.4c-0.4-0.4-1-0.5-1.4-0.1l-3,2.6c-0.4,0.4-0.5,1-0.1,1.4C3,6.9,3.6,7,4.1,6.6z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,4c-5,0-9,4-9,9s4,9,9,9s9-4,9-9S17,4,12,4z M16.12,16.24c-0.21,0.34-0.64,0.45-0.98,0.24L11,14V8.75 C11,8.34,11.34,8,11.75,8s0.75,0.34,0.75,0.75v4.5l3.37,2C16.21,15.45,16.33,15.9,16.12,16.24z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.3,5.1l-3.1-2.6c-0.4-0.4-0.99-0.31-1.4,0.1c-0.4,0.4-0.3,1,0.1,1.4L20,6.6c0.41,0.37,1,0.3,1.4-0.1 C21.73,6.12,21.7,5.4,21.3,5.1z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm_dim.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm_dim.xml
new file mode 100644
index 0000000..a80cd71
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_alarm_dim.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4.1,6.6l3-2.6c0.4-0.3,0.5-1,0.1-1.4c-0.4-0.4-1-0.5-1.4-0.1l-3,2.6c-0.4,0.4-0.5,1-0.1,1.4C3,6.9,3.6,7,4.1,6.6z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,4c-5,0-9,4-9,9s4,9,9,9s9-4,9-9S17,4,12,4z M16.12,16.24c-0.21,0.34-0.64,0.45-0.98,0.24L11,14V8.75 C11,8.34,11.34,8,11.75,8s0.75,0.34,0.75,0.75v4.5l3.37,2C16.21,15.45,16.33,15.9,16.12,16.24z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.3,5.1l-3.1-2.6c-0.4-0.4-0.99-0.31-1.4,0.1c-0.4,0.4-0.3,1,0.1,1.4L20,6.6c0.41,0.37,1,0.3,1.4-0.1 C21.73,6.12,21.7,5.4,21.3,5.1z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml
new file mode 100644
index 0000000..a0144a4
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.06,10.94c-0.01-0.01-0.01-0.01-0.02-0.02c-0.59-0.58-1.53-0.57-2.1,0.02l-0.01,0.01c-0.58,0.59-0.58,1.53,0.01,2.11 c0.58,0.59,1.53,0.59,2.12,0C20.65,12.48,20.65,11.53,20.06,10.94z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.06,10.94l-0.01-0.01c-0.59-0.58-1.53-0.58-2.11,0.01l-0.01,0.01c-0.58,0.59-0.58,1.53,0.01,2.11 c0.58,0.59,1.53,0.59,2.12,0S6.65,11.53,6.06,10.94z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.51,12l3.75-3.74c0.41-0.41,0.41-1.07,0-1.48l-4.47-4.47l-0.03-0.03c-0.42-0.39-1.08-0.37-1.48,0.05 C11.1,2.52,11,2.78,11,3.04v6.44L6.95,5.43c-0.41-0.41-1.06-0.41-1.47,0c-0.41,0.41-0.41,1.06,0,1.47l5.09,5.1l-5.09,5.09 c-0.41,0.41-0.41,1.06,0,1.47c0.41,0.41,1.06,0.41,1.47,0L11,14.51v6.45c0,0.57,0.47,1.04,1.04,1.04c0.26,0,0.52-0.1,0.71-0.28 l0.05-0.05l4.46-4.46c0.41-0.41,0.41-1.07,0-1.48L13.51,12z M12.99,5.37l2.15,2.15l-2.15,2.15V5.37z M12.99,18.62v-4.3l2.15,2.15 L12.99,18.62z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
index fce6e94..74f5719 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
@@ -1,28 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M4,15.3V19a1,1,0,0,0,1,1H8.69l2.6,2.6a1,1,0,0,0,1.41,0L15.3,20H19a1,1,0,0,0,1-1V15.31l2.6-2.6a1,1,0,0,0,0-1.41L20,8.69V5a1,1,0,0,0-1-1H15.31l-2.6-2.6a1,1,0,0,0-1.41,0L8.69,4H5A1,1,0,0,0,4,5V8.69l-2.6,2.6a1,1,0,0,0,0,1.41ZM12,7a5,5,0,1,1-5,5A5,5,0,0,1,12,7Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="?android:attr/colorControlActivated" android:pathData="M4,15.3V19c0,0.55,0.45,1,1,1h3.69l2.6,2.6c0.39,0.39,1.02,0.39,1.41,0l2.6-2.6H19c0.55,0,1-0.45,1-1v-3.69l2.6-2.6 c0.39-0.39,0.39-1.02,0-1.41L20,8.69V5c0-0.55-0.45-1-1-1h-3.69l-2.6-2.6c-0.39-0.39-1.02-0.39-1.41,0L8.69,4H5C4.45,4,4,4.45,4,5 v3.69l-2.6,2.6c-0.39,0.39-0.39,1.02,0,1.41L4,15.3z M12,7c2.76,0,5,2.24,5,5s-2.24,5-5,5s-5-2.24-5-5S9.24,7,12,7z"/>
+  <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 7 C 14.7614237492 7 17 9.23857625085 17 12 C 17 14.7614237492 14.7614237492 17 12 17 C 9.23857625085 17 7 14.7614237492 7 12 C 7 9.23857625085 9.23857625085 7 12 7 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml
new file mode 100644
index 0000000..9bfbe1c
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20,4h-3.17L15,2H9L7.17,4H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.1,4,20,4z M12,17 c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S14.76,17,12,17z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast.xml
new file mode 100644
index 0000000..7b5efbd
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast.xml
@@ -0,0 +1,23 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.11,14.08C1.52,13.99,1.02,14.46,1,15.06c-0.01,0.51,0.32,0.93,0.82,1.02c2.08,0.36,3.74,2,4.1,4.08 C6.01,20.64,6.42,21,6.91,21c0.61,0,1.09-0.54,1-1.14C7.42,16.88,5.09,14.56,2.11,14.08z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M1,18v2c0,0.55,0.45,1,1,1h2C4,19.34,2.66,18,1,18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,3H3C1.9,3,1,3.9,1,5v3h2V5h18v14h-7v2h7c1.1,0,2-0.9,2-2V5C23,3.9,22.1,3,21,3z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.07,10.05C1.5,10,1.02,10.45,1,11.03c-0.01,0.52,0.34,0.96,0.85,1.01c4.26,0.43,7.68,3.82,8.1,8.08 C10,20.62,10.43,21,10.94,21c0.59,0,1.06-0.51,1-1.1C11.42,14.69,7.28,10.56,2.07,10.05z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml
new file mode 100644
index 0000000..03f9cde
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml
@@ -0,0 +1,24 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.07,10.05C1.5,10,1.02,10.45,1,11.03c-0.01,0.52,0.34,0.96,0.85,1.01c4.26,0.43,7.68,3.82,8.1,8.08 C10,20.62,10.43,21,10.94,21c0.59,0,1.06-0.51,1-1.1C11.42,14.69,7.28,10.56,2.07,10.05z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.11,14.08C1.52,13.99,1.02,14.46,1,15.06c-0.01,0.51,0.32,0.93,0.82,1.02c2.08,0.36,3.74,2,4.1,4.08 C6.01,20.64,6.42,21,6.91,21c0.61,0,1.09-0.54,1-1.14C7.42,16.88,5.09,14.56,2.11,14.08z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,3H3C1.9,3,1,3.9,1,5v3h2V5h18v14h-7v2h7c1.1,0,2-0.9,2-2V5C23,3.9,22.1,3,21,3z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19,7H5v1.63c3.96,1.28,7.09,4.41,8.37,8.37H19V7z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M1,18v2c0,0.55,0.45,1,1,1h2C4,19.34,2.66,18,1,18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_close_white.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_close_white.xml
new file mode 100644
index 0000000..2047109
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_close_white.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M5.7,18.3c0.39,0.39,1.02,0.39,1.41,0L12,13.41l4.89,4.89c0.39,0.39,1.02,0.39,1.41,0s0.39-1.02,0-1.41L13.41,12l4.89-4.89 c0.38-0.38,0.38-1.02,0-1.4c-0.39-0.39-1.02-0.39-1.41,0c0,0,0,0,0,0L12,10.59L7.11,5.7c-0.39-0.39-1.02-0.39-1.41,0 s-0.39,1.02,0,1.41L10.59,12L5.7,16.89C5.31,17.28,5.31,17.91,5.7,18.3z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml
new file mode 100644
index 0000000..b01cada
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp " android:viewportHeight="24" android:viewportWidth="24" android:width="18dp " xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11,11H9c-0.55,0-1,0.45-1,1s0.45,1,1,1h2v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2h2c0.55,0,1-0.45,1-1s-0.45-1-1-1h-2V9 c0-0.55-0.45-1-1-1s-1,0.45-1,1V11z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13,2.05v2.52c3.66,0.49,6.5,3.63,6.5,7.43c0,1.01-0.2,1.97-0.56,2.85l2.18,1.26C21.68,14.85,22,13.46,22,12 C22,6.81,18.05,2.55,13,2.05z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,19.5c-4.14,0-7.5-3.36-7.5-7.5c0-3.8,2.84-6.93,6.5-7.43V2.05C5.95,2.55,2,6.81,2,12c0,5.52,4.48,10,10,10 c3.34,0,6.3-1.65,8.11-4.17l-2.18-1.26C16.56,18.35,14.41,19.5,12,19.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver_off.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver_off.xml
index 0949dc9..e6a64ac 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver_off.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver_off.xml
@@ -1,34 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,8a1,1,0,0,0-1,1v2H9a1,1,0,0,0,0,2h2v2a1,1,0,0,0,2,0V13h2a1,1,0,0,0,0-2H13V9A1,1,0,0,0,12,8Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.37,15.5A10.15,10.15,0,0,0,22,12a10,10,0,0,0-8.43-9.88 0.51 0.51,0,0,0-0.57 0.5 V4.15a0.49 0.49 ,0,0,0,0.41 0.48 ,7.5,7.5,0,0,1,5.7,9.75 0.49 0.49,0,0,0,0.21 0.59 l1.33 0.77 A0.51 0.51 ,0,0,0,21.37,15.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10.43,2.12a10,10,0,1,0,9.36,16.13 0.5 0.5,0,0,0-0.15-0.74l-1.32-0.76a0.48 0.48 ,0,0,0-0.62 0.12 ,7.44,7.44,0,0,1-5.93,2.63,7.58,7.58,0,0,1-7.25-7.07,7.5,7.5,0,0,1,6.07-7.79A0.51 0.51 ,0,0,0,11,4.15V2.62A0.5 0.5 ,0,0,0,10.43,2.12Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M13,4.57c3.66,0.49,6.5,3.63,6.5,7.43c0,1.01-0.2,1.97-0.56,2.85l2.18,1.26C21.68,14.85,22,13.46,22,12 c0-5.19-3.95-9.45-9-9.95V4.57z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.93,16.57c-1.37,1.78-3.52,2.93-5.93,2.93c-4.14,0-7.5-3.36-7.5-7.5c0-3.8,2.84-6.93,6.5-7.43V2.05 C5.95,2.55,2,6.81,2,12c0,5.52,4.48,10,10,10c3.34,0,6.3-1.65,8.11-4.17L17.93,16.57z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_dnd.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_dnd.xml
deleted file mode 100644
index e6086f3..0000000
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_dnd.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM8,11h8a1,1,0,0,1,0,2H8a1,1,0,0,1,0-2Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_drag_handle.xml
index 8f6db49..083beaf 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_drag_handle.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_drag_handle.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19,9H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19,13H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M19,13H5c-0.55,0-1,0.45-1,1s0.45,1,1,1h14c0.55,0,1-0.45,1-1S19.55,13,19,13z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19,9H5c-0.55,0-1,0.45-1,1s0.45,1,1,1h14c0.55,0,1-0.45,1-1S19.55,9,19,9z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset.xml
index 428d453..92e0f08 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,18V11a9,9,0,0,0-9.6-9A9.21,9.21,0,0,0,3,11.31V17.2C3,19.66,4.34,21,6,21H8a1,1,0,0,0,1-1V14a1,1,0,0,0-1-1H5V11.29A7.19,7.19,0,0,1,11.79,4,7,7,0,0,1,19,11v2H16a1,1,0,0,0-1,1v6a1,1,0,0,0,1,1h2A3,3,0,0,0,21,18Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,18v-7c0-5.17-4.36-9.32-9.6-8.98C6.62,2.33,3,6.52,3,11.31v5.89C3,19.66,4.34,21,6,21h2c0.55,0,1-0.45,1-1v-6 c0-0.55-0.45-1-1-1H5v-1.71C5,7.45,7.96,4.11,11.79,4C15.76,3.89,19,7.06,19,11v2h-3c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h2 C19.66,21,21,19.66,21,18z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset_mic.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset_mic.xml
new file mode 100644
index 0000000..ef0524a
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_headset_mic.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:pathData="M0,0h24v24H0V0z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M11.4,1.02C6.62,1.33,3,5.52,3,10.31L3,17c0,1.66,1.34,3,3,3h2c0.55,0,1-0.45,1-1v-6c0-0.55-0.45-1-1-1H5l0-1.71 C5,6.45,7.96,3.11,11.79,3C15.76,2.89,19,6.06,19,10v2h-3c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h3v1h-6c-0.55,0-1,0.45-1,1v0 c0,0.55,0.45,1,1,1h5c1.66,0,3-1.34,3-3V10C21,4.83,16.64,0.68,11.4,1.02z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_hotspot.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_hotspot.xml
index 00241f8..602b0f1 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_hotspot.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_hotspot.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15.46,16.46h0A1,1,0,0,0,17,16.35,5.9,5.9,0,0,0,18,13,6,6,0,1,0,7,16.35a1,1,0,0,0,1.51 0.11 h0a1,1,0,0,0,0.11-1.29A3.9,3.9,0,0,1,8,12.44a4,4,0,1,1,7.32,2.73A1,1,0,0,0,15.46,16.46Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10.86,3.06A10,10,0,0,0,4.19,19.25a1,1,0,0,0,1.49 0.07 A1,1,0,0,0,5.75,18a8.05,8.05,0,0,1-1.59-6.61A8,8,0,0,1,20,13a7.89,7.89,0,0,1-1.77,5,1,1,0,0,0,0.08,1.31h0a1,1,0,0,0,1.49-0.07A9.9,9.9,0,0,0,22,13,10,10,0,0,0,10.86,3.06Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10,13a2,2,0,1,0,2-2A2,2,0,0,0,10,13Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M15.46,16.46L15.46,16.46c0.44,0.44,1.17,0.4,1.51-0.1C17.62,15.4,18,14.25,18,13c0-3.75-3.45-6.7-7.34-5.86 c-2.24,0.48-4.04,2.3-4.52,4.54c-0.37,1.75,0.02,3.38,0.89,4.67c0.34,0.51,1.08,0.54,1.51,0.11l0.01-0.01 c0.34-0.34,0.37-0.88,0.1-1.28c-0.5-0.76-0.75-1.71-0.61-2.74c0.23-1.74,1.67-3.17,3.41-3.4C13.9,8.71,16,10.61,16,13 c0,0.8-0.24,1.54-0.64,2.17C15.09,15.58,15.11,16.11,15.46,16.46z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M10.86,3.06c-4.65,0.51-8.39,4.34-8.82,9c-0.25,2.72,0.6,5.25,2.15,7.18c0.37,0.46,1.07,0.49,1.49,0.07 C6.04,18.96,6.07,18.4,5.75,18c-1.4-1.75-2.09-4.1-1.6-6.61c0.61-3.13,3.14-5.65,6.28-6.24C15.54,4.18,20,8.07,20,13 c0,1.9-0.66,3.63-1.77,5c-0.32,0.39-0.28,0.96,0.08,1.31l0,0c0.42,0.42,1.12,0.39,1.49-0.08c1.38-1.7,2.2-3.88,2.2-6.24 C22,7.1,16.89,2.4,10.86,3.06z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 11 C 13.1045694997 11 14 11.8954305003 14 13 C 14 14.1045694997 13.1045694997 15 12 15 C 10.8954305003 15 10 14.1045694997 10 13 C 10 11.8954305003 10.8954305003 11 12 11 Z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info.xml
index e39a2a0..9a17877 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2,12A10,10,0,1,0,12,2,10,10,0,0,0,2,12Zm11,5.42a1,1,0,0,1-2,0V10.68a1,1,0,0,1,2,0ZM12,5.58a1.35,1.35,0,1,1-1.35,1.35A1.34,1.34,0,0,1,12,5.58Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info_outline.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info_outline.xml
new file mode 100644
index 0000000..9a17877
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_info_outline.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_invert_colors.xml
new file mode 100644
index 0000000..653f856
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_invert_colors.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12.7,3.39c-0.1-0.1-0.21-0.17-0.33-0.22C12.25,3.13,12.12,3.1,12,3.1c-0.26,0-0.51,0.1-0.71,0.29L6.56,8.13 c-3,3-3.4,7.89-0.62,11.1C7.54,21.08,9.77,22,12,22c2.23,0,4.45-0.92,6.05-2.76c2.79-3.21,2.39-8.11-0.61-11.11L12.7,3.39z M7.45,17.92c-2.04-2.36-1.81-6.04,0.52-8.38L12,5.51l0,0V20C10.25,20,8.6,19.24,7.45,17.92z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_location.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_location.xml
new file mode 100644
index 0000000..d736b41
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_location.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12.77,21.11C14.58,18.92,19,13.17,19,9c0-3.87-3.13-7-7-7S5,5.13,5,9c0,4.17,4.42,9.92,6.24,12.11 C11.64,21.59,12.37,21.59,12.77,21.11z M9.5,9c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5c0,1.38-1.12,2.5-2.5,2.5S9.5,10.38,9.5,9z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml
index 8b9f562..28ad305 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml
@@ -1,55 +1,29 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,21H21a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2H3A2,2,0,0,0,1,6V19A2,2,0,0,0,3,21ZM3,6H21V19H3Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9 8 H 11 V 10 H 9 V 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5 8 H 7 V 10 H 5 V 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 8 16 H 16 V 17 H 8 V 16 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13 8 H 15 V 10 H 13 V 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9 12 H 11 V 14 H 9 V 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5 12 H 7 V 14 H 5 V 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13 12 H 15 V 14 H 13 V 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17 8 H 19 V 10 H 17 V 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17 12 H 19 V 14 H 17 V 12 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21,19H3V6h18V19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C11,8.22,10.78,8,10.5,8h-1C9.22,8,9,8.22,9,8.5v1C9,9.78,9.22,10,9.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5.5,10h1C6.78,10,7,9.78,7,9.5v-1C7,8.22,6.78,8,6.5,8h-1C5.22,8,5,8.22,5,8.5v1C5,9.78,5.22,10,5.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C15,8.22,14.78,8,14.5,8h-1C13.22,8,13,8.22,13,8.5v1C13,9.78,13.22,10,13.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1C9.22,12,9,12.22,9,12.5v1C9,13.78,9.22,14,9.5,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5.5,14h1C6.78,14,7,13.78,7,13.5v-1C7,12.22,6.78,12,6.5,12h-1C5.22,12,5,12.22,5,12.5v1C5,13.78,5.22,14,5.5,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C13,13.78,13.22,14,13.5,14 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,8.22,18.78,8,18.5,8h-1C17.22,8,17,8.22,17,8.5v1C17,9.78,17.22,10,17.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C17,13.78,17.22,14,17.5,14 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8.5,17h7c0.28,0,0.5-0.22,0.5-0.5S15.78,16,15.5,16h-7C8.22,16,8,16.22,8,16.5S8.22,17,8.5,17z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_alert.xml
index 7858b05..c2e0af3 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_alert.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_alert.xml
@@ -1,37 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M5.4,3.27A10.45,10.45,0,0,0,2.15,9.34a1,1,0,0,0,2,0.33A8.44,8.44,0,0,1,6.77,4.73a1,1,0,0,0,0-1.43A1,1,0,0,0,5.4,3.27Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19.88,9.66a1,1,0,1,0,2-0.32A10.51,10.51,0,0,0,18.6,3.28a1,1,0,0,0-1.4,0,1,1,0,0,0,0,1.42A8.5,8.5,0,0,1,19.88,9.66Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,20H10a2,2,0,0,0,4,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,2.5A1.5,1.5,0,0,0,10.5,4v0.68C7.63,5.36,6,7.92,6,11v5L3.85,18.15a0.5 0.5 ,0,0,0,0,0.71A0.48 0.48 ,0,0,0,4.2,19H19.8a0.49 0.49 ,0,0,0,0.35-0.85L18,16V11c0-3.07-1.64-5.64-4.5-6.32V4A1.5,1.5,0,0,0,12,2.5ZM16,11v6H8V11c0-2.48,1.51-4.5,4-4.5S16,8.52,16,11Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4.12,9.67C4.42,7.73,5.38,6,6.77,4.73C7.19,4.35,7.2,3.7,6.8,3.3c-0.39-0.39-1-0.39-1.4-0.03 C3.7,4.84,2.52,6.96,2.15,9.34c-0.1,0.61,0.37,1.16,0.99,1.16C3.63,10.5,4.04,10.15,4.12,9.67z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.6,3.28c-0.4-0.37-1.02-0.36-1.4,0.02c-0.4,0.4-0.38,1.04,0.03,1.42c1.38,1.27,2.35,3,2.65,4.94 c0.08,0.49,0.5,0.84,0.98,0.84c0.61,0,1.09-0.55,0.99-1.16C21.47,6.96,20.29,4.84,18.6,3.28z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18,16v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5S10.5,3.17,10.5,4v0.68C7.63,5.36,6,7.92,6,11v5 l-2.15,2.15c-0.19,0.2-0.19,0.51,0.01,0.71C3.95,18.95,4.07,19,4.2,19h15.6c0.45,0,0.67-0.54,0.35-0.85L18,16z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_silence.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_silence.xml
index 2cefe4b..c9a600e 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_silence.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_notifications_silence.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20.73,19.46l-0.6-0.6L5.54,4.26A0.9 0.9 ,0,1,0,4.27,5.53l2.4,2.4A7.35,7.35,0,0,0,6,11v5L3.85,18.15a0.5 0.5 ,0,0,0,0,0.71A0.48 0.48 ,0,0,0,4.2,19H17.73l1.73,1.73a0.9 0.9 ,0,0,0,1.27,0A0.88 0.88 ,0,0,0,20.73,19.46Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,2.5A1.5,1.5,0,0,0,10.5,4v0.68a5.62,5.62,0,0,0-1.7 0.72 L18,14.6V11c0-3.07-1.64-5.64-4.5-6.32V4A1.5,1.5,0,0,0,12,2.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,20H10a2,2,0,0,0,4,0Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18,11c0-3.07-1.64-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5S10.5,3.17,10.5,4v0.68C9.72,4.86,9.04,5.2,8.46,5.63 L18,15.17V11z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.49,20.49L3.52,3.52c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41l4.14,4.14C6.09,9.68,6,10.33,6,11v5 l-2.15,2.15c-0.19,0.2-0.19,0.51,0.01,0.71C3.95,18.95,4.07,19,4.2,19h11.97l2.91,2.91c0.39,0.39,1.02,0.39,1.41,0 C20.88,21.52,20.88,20.88,20.49,20.49z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_low.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_low.xml
new file mode 100644
index 0000000..3106029
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_low.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M10,2v2H8.33C7.6,4,7,4.6,7,5.33v15.33C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V5.33C17,4.6,16.4,4,15.67,4 H14V2H10z M11,8.89c0-0.5,0.45-0.9,1-0.9s1,0.4,1,0.9V13c0,0.55-0.45,1-1,1s-1-0.45-1-1V8.89z M12,18.75 c-0.69,0-1.25-0.56-1.25-1.25s0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25S12.69,18.75,12,18.75z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_saver.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_saver.xml
new file mode 100644
index 0000000..e81a7bc
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_power_saver.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M10,2v2H8.33C7.6,4,7,4.6,7,5.33v15.33C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V5.33C17,4.6,16.4,4,15.67,4 H14V2H10z M15,13c0,0.55-0.45,1-1,1h-1v1c0,0.55-0.45,1-1,1s-1-0.45-1-1v-1h-1c-0.55,0-1-0.45-1-1s0.45-1,1-1h1v-1 c0-0.55,0.45-1,1-1s1,0.45,1,1v1h1C14.55,12,15,12.45,15,13z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml
deleted file mode 100644
index f823812..0000000
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.41,11h2.83L11.05,2.78a1.62,1.62,0,0,0-2.29,0L4.27,7.31,2.85,5.89A0.5 0.5 ,0,0,0,2,6.25V10.5a0.5 0.5 ,0,0,0,0.5 0.5 H6.75a0.5 0.5 ,0,0,0,0.36-0.85L5.69,8.73,9.93,4.49Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22,13.51a0.5 0.5 ,0,0,0-0.5-0.5H17.25a0.5 0.5 ,0,0,0-0.36 0.85 l1.35,1.35-4.31,4.31L7.44,13H4.61l8.19,8.18a1.62,1.62,0,0,0,2.29,0l4.57-4.55,1.49,1.49a0.5 0.5 ,0,0,0,0.85-0.36Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
index f64bd30..61b301c 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.67,16.42A0.84 0.84 ,0,0,0,20,16.19a9.83,9.83,0,0,0,1-4.3,10,10,0,0,0-0.91-4.12 0.85 0.85,0,0,0-1.39-0.23 0.87 0.87,0,0,0-0.17,1,8.71,8.71,0,0,1,0,7A0.84 0.84 ,0,0,0,18.67,16.42Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.48,18.56a1,1,0,0,0,1.47,0l4.05-4V21a1,1,0,0,0,1,1,1.07,1.07,0,0,0,0.71-0.27l0.05-0.05,4.46-4.46a1,1,0,0,0,0-1.48L11.51,12l3.75-3.73a1,1,0,0,0,0-1.48L10.79,2.32l0,0A1,1,0,0,0,9,3V9.49L5,5.43A1,1,0,0,0,3.48,6.9L8.57,12,3.48,17.09A1,1,0,0,0,3.48,18.56ZM11,5.38l2.15,2.15L11,9.68Zm0,8.94,2.15,2.15L11,18.62Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15,11.3a1,1,0,0,0,0,1.42l1.61,1.61A6.44,6.44,0,0,0,17,12a6.54,6.54,0,0,0-0.43-2.31Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M14.95,11.3c-0.39,0.39-0.39,1.03,0,1.42l1.61,1.61C16.84,13.61,17,12.82,17,12s-0.16-1.59-0.43-2.31L14.95,11.3z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M11.51,12l3.75-3.73c0.41-0.41,0.41-1.07,0-1.48l-4.47-4.47l-0.03-0.03C10.57,2.11,10.32,2,10.04,2C9.47,2,9,2.47,9,3.04 v6.45L4.95,5.43c-0.41-0.41-1.06-0.41-1.47,0c-0.41,0.41-0.41,1.06,0,1.47L8.57,12l-5.09,5.09c-0.41,0.41-0.41,1.06,0,1.47 c0.41,0.41,1.06,0.41,1.47,0L9,14.51v6.45C9,21.53,9.47,22,10.04,22c0.28,0,0.53-0.11,0.71-0.27l0.05-0.05l4.46-4.46 c0.41-0.41,0.41-1.07,0-1.48L11.51,12z M10.99,5.38l2.15,2.15l-2.15,2.15V5.38z M10.99,18.62v-4.3l2.15,2.15L10.99,18.62z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.08,7.77c-0.24-0.54-0.96-0.66-1.39-0.23c-0.26,0.26-0.32,0.65-0.17,0.98c0.47,1.07,0.72,2.24,0.72,3.47 c0,1.24-0.26,2.43-0.73,3.49c-0.14,0.32-0.09,0.69,0.16,0.94c0.4,0.4,1.09,0.29,1.34-0.23c0.63-1.3,0.98-2.76,0.98-4.3 C20.98,10.43,20.66,9.03,20.08,7.77z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml
index b014083..dbae2e9 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml
@@ -21,8 +21,6 @@
     android:viewportHeight="24">
 
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17.21,6.79l-4.5-4.5A1,1,0,0,0,11,3V9.59L7.2,5.78A1,1,0,0,0,5.79,7.2l4.8,4.8-4.8,4.8A1,1,0,0,0,7.2,18.22L11,14.41V21a1,1,0,0,0,0.62 0.92 A0.84 0.84 ,0,0,0,12,22a1,1,0,0,0,0.71-0.29l4.5-4.5a1,1,0,0,0,0-1.42L13.42,12l3.79-3.79A1,1,0,0,0,17.21,6.79ZM15.09,16.5,13,18.58V14.42ZM13,9.58V5.42L15.09,7.5Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml
deleted file mode 100644
index f3b1c01..0000000
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10,14.61h4L14.85,17H17L13.11,7H10.87L7,17H9.15Zm1.54-4.24 0.38 -1.2h0.11l0.38,1.2 0.91 ,2.51H10.63Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M4,20H8.69L12,23.31,15.31,20H20V15.31L23.31,12,20,8.69V4H15.31L12,0.69,8.69,4H4V8.69L0.69,12,4,15.31Zm-0.48-8L6,9.52V6H9.52L12,3.52,14.48,6H18V9.52L20.48,12,18,14.48V18H14.48L12,20.48,9.52,18H6V14.48Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cancel.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cancel.xml
index 0403d81..fe0130e 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cancel.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cancel.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm4.3,12.89a1,1,0,0,1,0,1.41,1,1,0,0,1-1.41,0h0L12,13.41,9.11,16.3A1,1,0,1,1,7.7,14.89L10.59,12,7.7,9.11A1,1,0,1,1,9.11,7.7L12,10.59,14.89,7.7A1,1,0,1,1,16.3,9.11L13.41,12Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,22c5.53,0,10-4.47,10-10S17.53,2,12,2S2,6.47,2,12S6.47,22,12,22z M7.7,9.11c-0.39-0.39-0.39-1.02,0-1.41 s1.02-0.39,1.41,0L12,10.59l2.89-2.89c0.39-0.39,1.02-0.39,1.41,0c0.39,0.39,0.39,1.02,0,1.41L13.41,12l2.89,2.89 c0.38,0.38,0.38,1.02,0,1.41c-0.39,0.39-1.02,0.39-1.41,0c0,0,0,0,0,0L12,13.41L9.11,16.3c-0.39,0.39-1.02,0.39-1.41,0 s-0.39-1.02,0-1.41L10.59,12L7.7,9.11z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cast_on.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cast_on.xml
deleted file mode 100644
index 0fd763b..0000000
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_cast_on.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M1.82,16.08a5,5,0,0,1,4.1,4.08,1,1,0,0,0,1,0.84,1,1,0,0,0,1-1.14,7,7,0,0,0-5.8-5.78,1,1,0,0,0-0.29,2Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19,7H5V8.63A13,13,0,0,1,13.37,17H19Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,5H21V19H14v2h7a2,2,0,0,0,2-2V5a2,2,0,0,0-2-2H3A2,2,0,0,0,1,5V8H3Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M1.85,12A9.06,9.06,0,0,1,10,20.12a1,1,0,0,0,1,0.88,1,1,0,0,0,1-1.1,11,11,0,0,0-9.87-9.85A1,1,0,0,0,1,11,1,1,0,0,0,1.85,12Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2,21H4a3,3,0,0,0-3-3v2A1,1,0,0,0,2,21Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_no_sim.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_no_sim.xml
index a488ee1..b753c55 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_no_sim.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_no_sim.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17,3H10L7.66,5.34,19,16.68V5A2,2,0,0,0,17,3Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20.73,22.23a0.9 0.9 ,0,0,0,0-1.27L4.28,4.51A0.88 0.88 ,0,0,0,3,4.5H3A0.9 0.9 ,0,0,0,3,5.78l2,2V19a2,2,0,0,0,2,2H17a2,2,0,0,0,1-0.26l1.49,1.49A0.9 0.9 ,0,0,0,20.73,22.23Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M19,5c0-1.1-0.9-2-2-2h-7L7.91,5.09L19,16.17V5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.49,20.49L3.52,3.52c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41l2.98,2.98L5,8v11c0,1.1,0.9,2,2,2h10 c0.34,0,0.65-0.09,0.93-0.24l1.15,1.15c0.39,0.39,1.02,0.39,1.41,0C20.88,21.52,20.88,20.88,20.49,20.49z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_vpn.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_vpn.xml
deleted file mode 100644
index ee2677d..0000000
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_vpn.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,10H12.65a6,6,0,1,0,0,4H16v2a2,2,0,0,0,4,0V14h1a2,2,0,0,0,0-4ZM7,14a2,2,0,1,1,2-2A2,2,0,0,1,7,14Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml
index 395b2e2..16c4fb5 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M23.43,6.57A20.54,20.54,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13V12h6.54l3.12-3.89A1.06,1.06,0,0,0,23.43,6.57Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22.32,14.68a1,1,0,0,0-1.37,0l-1.44,1.44-1.45-1.45a1,1,0,0,0-1.37,0h0a1,1,0,0,0,0,1.37l1.45,1.45L16.68,19h0a1,1,0,0,0,0,1.37h0a1,1,0,0,0,1.37,0l1.45-1.45L21,20.32A1,1,0,0,0,22.32,19L20.87,17.5l1.45-1.45A1,1,0,0,0,22.32,14.68Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M23.43,6.57C21.66,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6 c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12h6.54l3.12-3.89C24.05,7.63,23.94,6.92,23.43,6.57z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22.32,14.68c-0.38-0.38-0.99-0.38-1.37,0l-1.44,1.44l-1.45-1.45c-0.38-0.38-0.99-0.38-1.37,0l-0.01,0.01c0,0,0,0,0,0 c-0.38,0.38-0.37,0.99,0,1.37l1.45,1.45l-1.45,1.45c0,0,0,0,0,0c-0.38,0.38-0.37,0.99,0,1.37l0.01,0.01 c0.38,0.38,0.99,0.38,1.37,0l1.45-1.45l1.44,1.44c0.38,0.38,0.99,0.38,1.37,0s0.38-0.99,0-1.37l-1.45-1.45l1.45-1.45 C22.7,15.67,22.7,15.06,22.32,14.68z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml
index f24bb24..6dae927 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml
@@ -1,34 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M14,12h6.54l3.12-3.89a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22.71,15.67,20.88,17.5l1.83,1.83a1,1,0,0,1,0,1.38h0a1,1,0,0,1-1.38,0L19.5,18.88l-1.83,1.83a1,1,0,0,1-1.38,0h0a1,1,0,0,1,0-1.38l1.83-1.83-1.82-1.82a1,1,0,0,1,0-1.38h0a1,1,0,0,1,1.38,0L19.5,16.1l1.82-1.82a1,1,0,0,1,1.38,0h0A1,1,0,0,1,22.71,15.67Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14,12h6.54l3.12-3.89c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38,0.38,1,0,1.38l0,0c-0.38,0.38-1,0.39-1.38,0l-1.83-1.83l-1.83,1.83 c-0.38,0.38-1,0.38-1.38,0l-0.01-0.01c-0.38-0.38-0.38-1,0-1.38l1.83-1.83l-1.82-1.82c-0.38-0.38-0.38-1,0-1.38l0.01-0.01 c0.38-0.38,1-0.38,1.38,0l1.82,1.82l1.82-1.82c0.38-0.38,1-0.38,1.38,0l0,0C23.09,14.67,23.09,15.29,22.71,15.67z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml
index 4491abb..5f3d85c 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml
@@ -1,34 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M14,12h6.54l3.12-3.89a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,20.13,12.82,21.6a1.07,1.07,0,0,1-1.66,0l-5.1-6.35A9,9,0,0,1,12,13a8.76,8.76,0,0,1,2,0.23Zm8.71-5.84h0a1,1,0,0,0-1.38,0l-1.82,1.82-1.82-1.82a1,1,0,0,0-1.38,0h0a1,1,0,0,0,0,1.38l1.82,1.82-1.83,1.83a1,1,0,0,0,0,1.38h0a1,1,0,0,0,1.38,0l1.83-1.83,1.83,1.83a1,1,0,0,0,1.38,0h0a1,1,0,0,0,0-1.38l-1.83-1.83,1.83-1.83A1,1,0,0,0,22.71,14.29Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14,12h6.54l3.12-3.89c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53-1.23,0.53-1.66,0l-5.1-6.35C7.65,13.85,9.72,13,12,13c0.69,0,1.36,0.08,2,0.23V20.13z M22.71,14.29L22.71,14.29c-0.38-0.38-1-0.39-1.38,0l-1.82,1.82l-1.82-1.82c-0.38-0.38-1-0.38-1.38,0L16.3,14.3 c-0.38,0.38-0.38,1,0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38-0.38,1,0,1.38l0.01,0.01c0.38,0.38,1,0.38,1.38,0l1.83-1.83 l1.83,1.83c0.38,0.38,1,0.38,1.38,0l0,0c0.38-0.38,0.38-1,0-1.38l-1.83-1.83l1.83-1.83C23.09,15.29,23.09,14.67,22.71,14.29z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml
index cd4f78f5..11797cc 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml
@@ -1,34 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M14,12h6.54l3.12-3.89a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,20.13,12.82,21.6a1.07,1.07,0,0,1-1.66,0l-7-8.7A12,12,0,0,1,18.62,12H14Zm8.71-5.84h0a1,1,0,0,0-1.38,0l-1.82,1.82-1.82-1.82a1,1,0,0,0-1.38,0h0a1,1,0,0,0,0,1.38l1.82,1.82-1.83,1.83a1,1,0,0,0,0,1.38h0a1,1,0,0,0,1.38,0l1.83-1.83,1.83,1.83a1,1,0,0,0,1.38,0h0a1,1,0,0,0,0-1.38l-1.83-1.83,1.83-1.83A1,1,0,0,0,22.71,14.29Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14,12h6.54l3.12-3.89c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53-1.23,0.53-1.66,0l-6.98-8.7C6.28,11.1,9.01,10,12,10c2.45,0,4.72,0.74,6.62,2H14 V20.13z M22.71,14.29L22.71,14.29c-0.38-0.38-1-0.39-1.38,0l-1.82,1.82l-1.82-1.82c-0.38-0.38-1-0.38-1.38,0L16.3,14.3 c-0.38,0.38-0.38,1,0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38-0.38,1,0,1.38l0.01,0.01c0.38,0.38,1,0.38,1.38,0l1.83-1.83 l1.83,1.83c0.38,0.38,1,0.38,1.38,0l0,0c0.38-0.38,0.38-1,0-1.38l-1.83-1.83l1.83-1.83C23.09,15.29,23.09,14.67,22.71,14.29z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml
index 47ee832..9996002 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml
@@ -1,34 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M14,12h6.54l3.12-3.89a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0L14,20.13Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,20.13,12.82,21.6a1.07,1.07,0,0,1-1.66,0L2.93,11.35a14,14,0,0,1,18.14,0l-0.53 0.66 H14Zm8.71-5.84h0a1,1,0,0,0-1.38,0l-1.82,1.82-1.82-1.82a1,1,0,0,0-1.38,0h0a1,1,0,0,0,0,1.38l1.82,1.82-1.83,1.83a1,1,0,0,0,0,1.38h0a1,1,0,0,0,1.38,0l1.83-1.83,1.83,1.83a1,1,0,0,0,1.38,0h0a1,1,0,0,0,0-1.38l-1.83-1.83,1.83-1.83A1,1,0,0,0,22.71,14.29Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14,12h6.54l3.12-3.89c0.39-0.48,0.29-1.19-0.22-1.54C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0L14,20.13V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53-1.23,0.53-1.66,0L2.93,11.35C5.37,9.26,8.54,8,12,8s6.62,1.26,9.07,3.34L20.54,12H14 V20.13z M22.71,14.29L22.71,14.29c-0.38-0.38-1-0.39-1.38,0l-1.82,1.82l-1.82-1.82c-0.38-0.38-1-0.38-1.38,0L16.3,14.3 c-0.38,0.38-0.38,1,0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38-0.38,1,0,1.38l0.01,0.01c0.38,0.38,1,0.38,1.38,0l1.83-1.83 l1.83,1.83c0.38,0.38,1,0.38,1.38,0l0,0c0.38-0.38,0.38-1,0-1.38l-1.83-1.83l1.83-1.83C23.09,15.29,23.09,14.67,22.71,14.29z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml
index 8bef29c..906e53a 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14.61,13a5,5,0,0,1,5-5A4.93,4.93,0,0,1,22.8,9.18l0.86-1.07a1.06,1.06,0,0,0-0.22-1.54A20.58,20.58,0,0,0,12,3,20.55,20.55,0,0,0,0.56,6.57,1.07,1.07,0,0,0,0.33,8.11L11.16,21.6a1.07,1.07,0,0,0,1.66,0l3.74-4.66A5,5,0,0,1,14.61,13Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20,22a1.1,1.1,0,1,0-1.1-1.1A1.1,1.1,0,0,0,20,22Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22.69,15.48a2.79,2.79,0,0,0,0.82-2,3.51,3.51,0,0,0-6.82-1.15 0.86 0.86,0,0,0,0.81,1.14 0.89 0.89,0,0,0,0.84-0.55,1.75,1.75,0,0,1,3.41 0.55 ,1.79,1.79,0,0,1-0.51,1.24l-1.09,1.1a3.21,3.21,0,0,0-1,2.12s0,0.05,0,0.08A0.89 0.89 ,0,0,0,20,19a0.87 0.87 ,0,0,0,0.87-0.77,2.85,2.85,0,0,1,1-1.95Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20,8h3.72c0.3-0.47,0.2-1.1-0.28-1.43C21.67,5.36,17.55,3,12,3C6.44,3,2.33,5.36,0.56,6.57 C0.05,6.92-0.05,7.63,0.33,8.11L11.16,21.6c0.42,0.53,1.23,0.53,1.66,0l1.68-2.09V13.5C14.5,10.46,16.96,8,20,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20,10c-1.53,0-2.84,0.99-3.31,2.36c-0.19,0.56,0.23,1.14,0.81,1.14c0.36,0,0.72-0.21,0.84-0.55 c0.23-0.7,0.89-1.2,1.66-1.2c0.97,0,1.75,0.78,1.75,1.75c0,0.48-0.2,0.92-0.51,1.24l-1.09,1.1c-0.69,0.69-0.92,1.38-0.99,2.2 C19.12,18.55,19.52,19,20.04,19c0.44,0,0.83-0.33,0.87-0.77c0.07-0.79,0.31-1.27,1-1.95l0.78-0.8c0.5-0.5,0.82-1.2,0.82-1.97 C23.5,11.57,21.93,10,20,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20,19.86c-0.33,0-0.63,0.15-0.83,0.39c-0.18,0.2-0.29,0.45-0.29,0.74c0,0.62,0.5,1.12,1.12,1.12s1.12-0.5,1.12-1.12 c0-0.29-0.12-0.54-0.29-0.74C20.63,20.02,20.33,19.86,20,19.86z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_screenshot_delete.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_screenshot_delete.xml
index 447d848..c59fb59 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_screenshot_delete.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_screenshot_delete.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18,4H15.5l-0.71-0.71a1,1,0,0,0-0.7-0.29H9.9a1,1,0,0,0-0.7 0.29 L8.49,4H6A1,1,0,0,0,6,6H18a1,1,0,0,0,1-1A1,1,0,0,0,18,4Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18,19V7H6V19a2,2,0,0,0,2,2h8A2,2,0,0,0,18,19Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M18,4h-2.5l-0.71-0.71C14.61,3.11,14.35,3,14.09,3H9.9C9.64,3,9.38,3.11,9.2,3.29L8.49,4h-2.5c-0.55,0-1,0.45-1,1 s0.45,1,1,1h12c0.55,0,1-0.45,1-1C19,4.45,18.55,4,18,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings.xml
new file mode 100644
index 0000000..938b533
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21.64,8.39l-1.6-2.76c-0.28-0.48-0.88-0.7-1.36-0.5l-2.14,0.91c-0.48-0.37-1.01-0.68-1.57-0.92l-0.27-2.2 C14.64,2.4,14.14,2,13.59,2h-3.18C9.86,2,9.36,2.4,9.3,2.92L9.04,5.11c-0.57,0.24-1.1,0.55-1.58,0.92L5.32,5.12 c-0.48-0.2-1.08,0.02-1.36,0.5l-1.6,2.76C2.08,8.86,2.18,9.48,2.6,9.8l1.94,1.45C4.51,11.49,4.5,11.74,4.5,12s0.01,0.51,0.04,0.76 L2.6,14.2c-0.42,0.31-0.52,0.94-0.24,1.41l1.6,2.76c0.28,0.48,0.88,0.7,1.36,0.5l2.14-0.91c0.48,0.37,1.01,0.68,1.57,0.92 l0.27,2.19C9.36,21.6,9.86,22,10.41,22h3.18c0.55,0,1.04-0.4,1.11-0.92l0.27-2.19c0.56-0.24,1.09-0.55,1.57-0.92l2.14,0.91 c0.48,0.2,1.08-0.02,1.36-0.5l1.6-2.76c0.28-0.48,0.18-1.1-0.24-1.42l-1.94-1.45c0.03-0.25,0.04-0.5,0.04-0.76 s-0.01-0.51-0.04-0.76L21.4,9.8C21.82,9.49,21.92,8.86,21.64,8.39z M12,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5 s3.5,1.57,3.5,3.5S13.93,15.5,12,15.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings_16dp.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings_16dp.xml
index d292b13..2a93a69 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings_16dp.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_settings_16dp.xml
@@ -21,8 +21,6 @@
     android:viewportHeight="24">
 
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.64,8.39,20,5.63a1.12,1.12,0,0,0-1.36-0.5L16.54,6A7.26,7.26,0,0,0,15,5.12l-0.27-2.2A1.1,1.1,0,0,0,13.59,2H10.41a1.1,1.1,0,0,0-1.11 0.92 L9,5.11A7.1,7.1,0,0,0,7.46,6L5.32,5.12A1.12,1.12,0,0,0,4,5.62L2.36,8.38A1.1,1.1,0,0,0,2.6,9.8l1.94,1.45a6.06,6.06,0,0,0,0,0.75,6.34,6.34,0,0,0,0,0.76L2.6,14.2a1.09,1.09,0,0,0-0.24,1.41L4,18.37a1.12,1.12,0,0,0,1.36 0.5 L7.46,18A7.26,7.26,0,0,0,9,18.88l0.27,2.19a1.1,1.1,0,0,0,1.11 0.93 h3.18a1.11,1.11,0,0,0,1.11-0.92L15,18.89A7.26,7.26,0,0,0,16.54,18l2.14 0.91 a1.12,1.12,0,0,0,1.36-0.5l1.6-2.76a1.1,1.1,0,0,0-0.24-1.42l-1.94-1.45a7.24,7.24,0,0,0,0-1.52L21.4,9.8A1.09,1.09,0,0,0,21.64,8.39ZM12,15.5A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z" />
-</vector>
+        android:fillColor="#FFFFFF"
+        android:pathData="M21.64,8.39l-1.6-2.76c-0.28-0.48-0.88-0.7-1.36-0.5l-2.14,0.91c-0.48-0.37-1.01-0.68-1.57-0.92l-0.27-2.2 C14.64,2.4,14.14,2,13.59,2h-3.18C9.86,2,9.36,2.4,9.3,2.92L9.04,5.11c-0.57,0.24-1.1,0.55-1.58,0.92L5.32,5.12 c-0.48-0.2-1.08,0.02-1.36,0.5l-1.6,2.76C2.08,8.86,2.18,9.48,2.6,9.8l1.94,1.45C4.51,11.49,4.5,11.74,4.5,12s0.01,0.51,0.04,0.76 L2.6,14.2c-0.42,0.31-0.52,0.94-0.24,1.41l1.6,2.76c0.28,0.48,0.88,0.7,1.36,0.5l2.14-0.91c0.48,0.37,1.01,0.68,1.57,0.92 l0.27,2.19C9.36,21.6,9.86,22,10.41,22h3.18c0.55,0,1.04-0.4,1.11-0.92l0.27-2.19c0.56-0.24,1.09-0.55,1.57-0.92l2.14,0.91 c0.48,0.2,1.08-0.02,1.36-0.5l1.6-2.76c0.28-0.48,0.18-1.1-0.24-1.42l-1.94-1.45c0.03-0.25,0.04-0.5,0.04-0.76 s-0.01-0.51-0.04-0.76L21.4,9.8C21.82,9.49,21.92,8.86,21.64,8.39z M12,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5 s3.5,1.57,3.5,3.5S13.93,15.5,12,15.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_airplane.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_airplane.xml
deleted file mode 100644
index 999a9bf..0000000
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_airplane.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.15,15.8l7.35-2.3V19L8.9,20.2a1,1,0,0,0-0.4 0.8 v0.67a0.24 0.24 ,0,0,0,0.31 0.24 L12,21l3.19 0.91 a0.24 0.24 ,0,0,0,0.31-0.24V21a1,1,0,0,0-0.4-0.8L13.5,19V13.5l7.35,2.3a0.5 0.5 ,0,0,0,0.65-0.48v-0.49a1.5,1.5,0,0,0-0.7-1.27L13.5,9V3.5a1.5,1.5,0,0,0-3,0V9L3.2,13.56a1.5,1.5,0,0,0-0.7,1.27v0.49A0.5 0.5 ,0,0,0,3.15,15.8Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_flashlight.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_flashlight.xml
deleted file mode 100644
index 1ffb32b..0000000
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_signal_flashlight.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10,22h4a1,1,0,0,0,1-1V10a2,2,0,0,0,2-2V5.5H7V8a2,2,0,0,0,2,2V21A1,1,0,0,0,10,22Zm2-10a1.5,1.5,0,1,1-1.5,1.5A1.5,1.5,0,0,1,12,12Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17,3a1,1,0,0,0-1-1H8A1,1,0,0,0,7,3V4H17Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_swap_vert.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_swap_vert.xml
index 43a01c6..d1a4023 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_swap_vert.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_swap_vert.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18,17H16V11a1,1,0,0,0-2,0v6H12a0.53 0.53 ,0,0,0-0.37 0.9 l2.95,2.94a0.53 0.53 ,0,0,0,0.75,0l3-2.94A0.52 0.52 ,0,0,0,18,17Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.32,6.09l-3-2.95a0.52 0.52 ,0,0,0-0.74,0h0L5.68,6.09a0.53 0.53 ,0,0,0,0.37 0.9 H8v6a1,1,0,0,0,2,0V7H12A0.52 0.52 ,0,0,0,12.32,6.09Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.95,17.01H16V11c0-0.55-0.45-1-1-1s-1,0.45-1,1v6.01h-1.96c-0.47,0-0.7,0.57-0.37,0.9l2.95,2.94 c0.21,0.21,0.54,0.21,0.75,0l2.95-2.94C18.66,17.58,18.42,17.01,17.95,17.01z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.32,6.09L9.37,3.14c-0.2-0.21-0.54-0.21-0.74-0.01c0,0-0.01,0.01-0.01,0.01L5.68,6.09c-0.33,0.33-0.1,0.9,0.37,0.9H8 V13c0,0.55,0.45,1,1,1s1-0.45,1-1V6.99h1.95C12.42,6.99,12.66,6.42,12.32,6.09z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml
new file mode 100644
index 0000000..cd4e7f4
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml
@@ -0,0 +1,25 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="16dp" android:viewportHeight="24" android:viewportWidth="24" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M8,9c-0.55,0-1,0.45-1,1v1H4c-0.55,0-1,0.45-1,1c0,0.55,0.45,1,1,1h3v1c0,0.55,0.45,1,1,1s1-0.45,1-1v-4 C9,9.45,8.55,9,8,9z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20,5h-3V4c0-0.55-0.45-1-1-1s-1,0.45-1,1v4c0,0.55,0.45,1,1,1s1-0.45,1-1V7h3c0.55,0,1-0.45,1-1C21,5.45,20.55,5,20,5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20,11h-9v2h9c0.55,0,1-0.45,1-1C21,11.45,20.55,11,20,11z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20,17h-7v-1c0-0.55-0.45-1-1-1s-1,0.45-1,1v4c0,0.55,0.45,1,1,1s1-0.45,1-1v-1h7c0.55,0,1-0.45,1-1S20.55,17,20,17z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M4,7h9V5H4C3.45,5,3,5.45,3,6C3,6.55,3.45,7,4,7z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3,18c0,0.55,0.45,1,1,1h5v-2H4C3.45,17,3,17.45,3,18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm.xml
index c300bed..f282ddc 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm.xml
@@ -21,14 +21,12 @@
     android:viewportHeight="24">
 
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M4.1,6.6l3-2.6c0.4-0.3,0.5-1,0.1-1.4c-0.4-0.4-1-0.5-1.4-0.1l-3,2.6c-0.4,0.4-0.5,1-0.1,1.4C3,6.9,3.6,7,4.1,6.6z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M16.8,2.6A1,1,0,0,0,16.9,4L20,6.6a1,1,0,0,0,1.4-0.1,1,1,0,0,0-0.1-1.4L18.2,2.5A1,1,0,0,0,16.8,2.6Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M12,4c-5,0-9,4-9,9s4,9,9,9s9-4,9-9S17,4,12,4z M16.12,16.24c-0.21,0.34-0.64,0.45-0.98,0.24L11,14V8.75 C11,8.34,11.34,8,11.75,8s0.75,0.34,0.75,0.75v4.5l3.37,2C16.21,15.45,16.33,15.9,16.12,16.24z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M4.1,6.6,7.1,4A1,1,0,1,0,5.8,2.5l-3,2.6a1,1,0,0,0-0.1,1.4A1,1,0,0,0,4.1,6.6Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,13a9,9,0,1,0,9-9A9,9,0,0,0,3,13Zm8-4.25a0.75 0.75 ,0,0,1,1.5,0v4.5l3.37,2a0.72 0.72 ,0,0,1,0.25,1,0.71 0.71 ,0,0,1-1,0.24L11,14Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M21.3,5.1l-3.1-2.6c-0.4-0.4-0.99-0.31-1.4,0.1c-0.4,0.4-0.3,1,0.1,1.4L20,6.6c0.41,0.37,1,0.3,1.4-0.1 C21.73,6.12,21.7,5.4,21.3,5.1z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
new file mode 100644
index 0000000..1a98350
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
@@ -0,0 +1,23 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,4c-1.5,0-2.91,0.37-4.15,1.02l12.13,12.13C20.63,15.91,21,14.5,21,13C21,8.03,16.97,4,12,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M7.1,4c0.4-0.3,0.5-1,0.1-1.4c-0.4-0.4-1-0.5-1.4-0.1L5.55,2.72l1.41,1.41L7.1,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.3,5.1l-3.1-2.6c-0.4-0.4-0.99-0.31-1.4,0.1c-0.4,0.4-0.3,1,0.1,1.4L20,6.6c0.41,0.37,1,0.3,1.4-0.1 C21.73,6.12,21.7,5.4,21.3,5.1z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.52,3.52c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41l0.47,0.47C2.38,5.77,2.39,6.19,2.7,6.5 c0.26,0.34,0.74,0.44,1.19,0.22l0.91,0.91C3.67,9.13,3,10.98,3,13c0,4.97,4.03,9,9,9c2.02,0,3.87-0.67,5.38-1.79l1.7,1.7 c0.39,0.39,1.02,0.39,1.41,0c0.39-0.39,0.39-1.02,0-1.41L3.52,3.52z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml
new file mode 100644
index 0000000..1f925d5
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml
@@ -0,0 +1,24 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="19dp" android:viewportHeight="24" android:viewportWidth="24" android:width="19dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M19,7c-0.55,0-1,0.45-1,1v8c0,0.55,0.45,1,1,1s1-0.45,1-1V8C20,7.45,19.55,7,19,7z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5,7C4.45,7,4,7.45,4,8v8c0,0.55,0.45,1,1,1s1-0.45,1-1V8C6,7.45,5.55,7,5,7z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22,9c-0.55,0-1,0.45-1,1v4c0,0.55,0.45,1,1,1s1-0.45,1-1v-4C23,9.45,22.55,9,22,9z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16,4H8C7.45,4,7,4.45,7,5v14c0,0.55,0.45,1,1,1h8c0.55,0,1-0.45,1-1V5C17,4.45,16.55,4,16,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2,9c-0.55,0-1,0.45-1,1v4c0,0.55,0.45,1,1,1s1-0.45,1-1v-4C3,9.45,2.55,9,2,9z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_camera.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_camera.xml
new file mode 100644
index 0000000..9bfbe1c
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_camera.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20,4h-3.17L15,2H9L7.17,4H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.1,4,20,4z M12,17 c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S14.76,17,12,17z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_mic_none.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_mic_none.xml
new file mode 100644
index 0000000..d7f7811
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_mic_none.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,14c1.66,0,3-1.34,3-3V5c0-1.66-1.34-3-3-3S9,3.34,9,5v6C9,12.66,10.34,14,12,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.09,11L6.09,11c-0.61,0-1.09,0.54-1,1.14c0.49,3,2.89,5.34,5.91,5.78V20c0,0.55,0.45,1,1,1s1-0.45,1-1v-2.08 c3.02-0.44,5.42-2.78,5.91-5.78c0.1-0.6-0.39-1.14-1-1.14h0c-0.49,0-0.9,0.36-0.98,0.85C16.52,14.21,14.47,16,12,16 s-4.52-1.79-4.93-4.15C6.99,11.36,6.58,11,6.09,11z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml
new file mode 100644
index 0000000..90ef490
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,10h-8.35C11.7,7.31,8.9,5.5,5.78,6.12C3.49,6.58,1.62,8.41,1.14,10.7C0.32,14.57,3.26,18,7,18c2.61,0,4.83-1.67,5.65-4 H16v2c0,1.1,0.9,2,2,2s2-0.9,2-2v-2h1c1.1,0,2-0.9,2-2C23,10.9,22.1,10,21,10z M7,14c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2s2,0.9,2,2 C9,13.1,8.1,14,7,14z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
new file mode 100644
index 0000000..53cbd3c
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="@*android:color/accent_device_default" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.53,6.72l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C11.68,1.92,11.5,2.2,11.5,2.5v7.69L7.53,6.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L11.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l3.97-3.97v7.69 c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.2,0,0.39-0.08,0.53-0.22l4.75-4.75c0.29-0.29,0.29-0.77,0-1.06 L13.31,12l4.22-4.22C17.82,7.49,17.82,7.01,17.53,6.72z M15.94,16.75L13,19.69v-5.88L15.94,16.75z M13,10.19V4.31l2.94,2.94 L13,10.19z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml
index 264e212..0e80234 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_bt_headphones_a2dp.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.5,18V11.5C21.5,5.82,17.68,2,12,2S2.5,5.82,2.5,11.5V18a3,3,0,0,0,3,3H7a1.5,1.5,0,0,0,1.5-1.5V14A1.5,1.5,0,0,0,7,12.5H4v-1c0-4.86,3.14-8,8-8s8,3.14,8,8v1H17A1.5,1.5,0,0,0,15.5,14v5.5A1.5,1.5,0,0,0,17,21h1.5A3,3,0,0,0,21.5,18ZM7,19.5H5.5A1.5,1.5,0,0,1,4,18V14H7ZM20,18a1.5,1.5,0,0,1-1.5,1.5H17V14h3Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M14.75,2.01h-5.5c-3.72,0-6.75,3.03-6.75,6.75v3.74v1V18c0,1.66,1.34,3,3,3H7c0.83,0,1.5-0.67,1.5-1.5V14 c0-0.83-0.67-1.5-1.5-1.5H4V8.76c0-2.9,2.36-5.25,5.25-5.25h5.5c2.89,0,5.25,2.35,5.25,5.25v3.74h-3c-0.83,0-1.5,0.67-1.5,1.5v5.5 c0,0.83,0.67,1.5,1.5,1.5h1.5c1.66,0,3-1.34,3-3v-4.5v-1V8.76C21.5,5.04,18.47,2.01,14.75,2.01z M7,19.5H5.5 C4.67,19.5,4,18.83,4,18v-4h3V19.5z M20,18c0,0.83-0.67,1.5-1.5,1.5H17V14h3V18z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_expand_more.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_expand_more.xml
index 407adac..ba7a9fd 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_expand_more.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_expand_more.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.54,8.48a0.75 0.75 ,0,0,0-1.06,0L12,13.82,6.52,8.46a0.75 0.75 ,0,0,0-1.06,0,0.75 0.75 ,0,0,0,0,1.06l5.74,5.62a1.11,1.11,0,0,0,0.78 0.36 ,1.09,1.09,0,0,0,0.77-0.36l5.75-5.62A0.75 0.75 ,0,0,0,18.54,8.48Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M18.79,8.23c-0.29-0.3-0.76-0.3-1.06-0.01L12,13.82L6.27,8.21C5.98,7.92,5.5,7.93,5.21,8.23C4.92,8.52,4.93,9,5.23,9.29 l6,5.87c0.24,0.24,0.51,0.37,0.78,0.37c0.27,0,0.53-0.12,0.77-0.36l6-5.88C19.07,9,19.08,8.52,18.79,8.23z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_faster_emergency.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_faster_emergency.xml
new file mode 100644
index 0000000..713fda8
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_faster_emergency.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorError" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M19.5,4.5v15h-15v-15H19.5 M19.5,3h-15C3.67,3,3,3.67,3,4.5v15C3,20.33,3.67,21,4.5,21h15c0.83,0,1.5-0.67,1.5-1.5v-15 C21,3.67,20.33,3,19.5,3L19.5,3z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.6,10.75h-3.35V7.4c0-0.22-0.18-0.4-0.4-0.4h-1.7c-0.22,0-0.4,0.18-0.4,0.4v3.35H7.4c-0.22,0-0.4,0.18-0.4,0.4v1.7 c0,0.22,0.18,0.4,0.4,0.4h3.35v3.35c0,0.22,0.18,0.4,0.4,0.4h1.7c0.22,0,0.4-0.18,0.4-0.4v-3.35h3.35c0.22,0,0.4-0.18,0.4-0.4v-1.7 C17,10.93,16.82,10.75,16.6,10.75z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_info_outline_24.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_info_outline_24.xml
index 642ac42..00a9523 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_info_outline_24.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_info_outline_24.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19.07,4.93A10,10,0,1,0,22,12,10,10,0,0,0,19.07,4.93ZM18,18a8.5,8.5,0,1,1,2.5-6A8.53,8.53,0,0,1,18,18Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,10a0.76 0.76 ,0,0,0-0.75 0.75 v5.5a0.75 0.75 ,0,0,0,1.5,0v-5.5A0.76 0.76 ,0,0,0,12,10Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_invert_colors.xml
deleted file mode 100644
index 173824b..0000000
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_invert_colors.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.62,2.23A1,1,0,0,0,12,2a1.07,1.07,0,0,0-0.63 0.22 C9.48,3.75,4,8.5,4,14a7.89,7.89,0,0,0,8,8,8,8,0,0,0,8-8C20,8.5,14.5,3.73,12.62,2.23ZM5.5,14c0-4.4,4.32-8.53,6.5-10.33V20.49A6.43,6.43,0,0,1,5.5,14Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml
new file mode 100644
index 0000000..2161d88
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M18.5,8.5H16V5.12c-0.04-2.05-1.82-3.73-3.99-3.67C9.82,1.4,8.04,3.07,8,5.14V8.5H5.5C4.67,8.5,4,9.17,4,10v10 c0,0.83,0.67,1.5,1.5,1.5h13c0.83,0,1.5-0.67,1.5-1.5V10C20,9.17,19.33,8.5,18.5,8.5z M9.5,5.15c0.02-1.23,1.13-2.23,2.51-2.19 c1.36-0.04,2.47,0.96,2.49,2.18V8.5h-5V5.15z M18.5,20h-13V10h13V20z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_bugreport.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_bugreport.xml
new file mode 100644
index 0000000..919046e
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_bugreport.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M18,13.5h1.26c0.41,0,0.75-0.34,0.75-0.75S19.67,12,19.26,12H18v-1c0-0.52-0.07-1.02-0.2-1.5h1.46 c0.41,0,0.75-0.34,0.75-0.75S19.67,8,19.26,8h-2.07c-0.5-0.86-1.2-1.58-2.03-2.1l1.37-1.37c0.29-0.29,0.29-0.77,0-1.06 c-0.29-0.29-0.77-0.29-1.06,0l-1.78,1.78C13.16,5.09,12.59,5,12,5s-1.16,0.09-1.69,0.25L8.53,3.47c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06L8.84,5.9C8,6.42,7.3,7.14,6.81,8H4.74C4.33,8,3.99,8.34,3.99,8.75S4.33,9.5,4.74,9.5H6.2 C6.07,9.98,6,10.48,6,11v1H4.74c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75H6V15c0,0.34,0.04,0.67,0.09,1H4.74 c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1.81C7.5,19.56,9.58,21,12,21s4.5-1.44,5.45-3.5h1.81 c0.41,0,0.75-0.34,0.75-0.75S19.67,16,19.26,16h-1.35c0.05-0.33,0.09-0.66,0.09-1V13.5z M16.5,15c0,2.48-2.02,4.5-4.5,4.5 S7.5,17.48,7.5,15v-4c0-2.48,2.02-4.5,4.5-4.5s4.5,2.02,4.5,4.5V15z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.25,14h-2.5C10.34,14,10,14.34,10,14.75s0.34,0.75,0.75,0.75h2.5c0.41,0,0.75-0.34,0.75-0.75S13.66,14,13.25,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.25,10.5h-2.5c-0.41,0-0.75,0.34-0.75,0.75S10.34,12,10.75,12h2.5c0.41,0,0.75-0.34,0.75-0.75S13.66,10.5,13.25,10.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml
new file mode 100644
index 0000000..719e63f
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="32dp" android:tint="?android:attr/textColor" android:viewportHeight="24" android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.51,1.46c-2.19-0.06-3.98,1.61-4.01,3.68V8.5h-9C4.67,8.5,4,9.17,4,10v10c0,0.83,0.67,1.5,1.5,1.5h13 c0.83,0,1.5-0.67,1.5-1.5V10c0-0.83-0.67-1.5-1.5-1.5H16V5.15c0.02-1.23,1.14-2.23,2.51-2.19C19.9,2.93,20.98,3.92,21,5.15 c0.01,0.41,0.36,0.71,0.76,0.74c0.41-0.01,0.74-0.35,0.74-0.76C22.46,3.07,20.7,1.39,18.51,1.46z M18.5,10v10h-13V10H18.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_power_off.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_power_off.xml
new file mode 100644
index 0000000..d0e21a1
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_power_off.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,13c-0.41,0-0.75-0.34-0.75-0.75v-9.5C11.25,2.33,11.59,2,12,2s0.75,0.34,0.75,0.75v9.5C12.75,12.66,12.41,13,12,13z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,21c-4.96,0-9-4.02-9-8.96c0-2.5,1.06-4.9,2.91-6.6c0.31-0.28,0.78-0.26,1.06,0.05C7.25,5.8,7.23,6.27,6.92,6.55 C5.38,7.96,4.5,9.96,4.5,12.04c0,4.11,3.36,7.46,7.5,7.46s7.5-3.34,7.5-7.46c0-2.08-0.88-4.08-2.42-5.49 c-0.3-0.28-0.33-0.75-0.05-1.06c0.28-0.3,0.75-0.33,1.06-0.05c1.85,1.69,2.91,4.1,2.91,6.6C21,16.98,16.96,21,12,21z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
index 7897fa3a..6b91dcd 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
@@ -1,55 +1,29 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,21H21a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2H3A2,2,0,0,0,1,6V19A2,2,0,0,0,3,21ZM2.5,6A0.51 0.51 ,0,0,1,3,5.5H21a0.51 0.51 ,0,0,1,0.5 0.5 V19a0.51 0.51 ,0,0,1-0.5 0.5 H3a0.51 0.51 ,0,0,1-0.5-0.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9.5 8 L 10.5 8 Q 11 8 11 8.5 L 11 9.5 Q 11 10 10.5 10 L 9.5 10 Q 9 10 9 9.5 L 9 8.5 Q 9 8 9.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5.5 8 L 6.5 8 Q 7 8 7 8.5 L 7 9.5 Q 7 10 6.5 10 L 5.5 10 Q 5 10 5 9.5 L 5 8.5 Q 5 8 5.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M8.75,17.5h6.5a0.75 0.75 ,0,0,0,0-1.5H8.75a0.75 0.75 ,0,0,0,0,1.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13.5 8 L 14.5 8 Q 15 8 15 8.5 L 15 9.5 Q 15 10 14.5 10 L 13.5 10 Q 13 10 13 9.5 L 13 8.5 Q 13 8 13.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9.5 12 L 10.5 12 Q 11 12 11 12.5 L 11 13.5 Q 11 14 10.5 14 L 9.5 14 Q 9 14 9 13.5 L 9 12.5 Q 9 12 9.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5.5 12 L 6.5 12 Q 7 12 7 12.5 L 7 13.5 Q 7 14 6.5 14 L 5.5 14 Q 5 14 5 13.5 L 5 12.5 Q 5 12 5.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13.5 12 L 14.5 12 Q 15 12 15 12.5 L 15 13.5 Q 15 14 14.5 14 L 13.5 14 Q 13 14 13 13.5 L 13 12.5 Q 13 12 13.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17.5 8 L 18.5 8 Q 19 8 19 8.5 L 19 9.5 Q 19 10 18.5 10 L 17.5 10 Q 17 10 17 9.5 L 17 8.5 Q 17 8 17.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17.5 12 L 18.5 12 Q 19 12 19 12.5 L 19 13.5 Q 19 14 18.5 14 L 17.5 14 Q 17 14 17 13.5 L 17 12.5 Q 17 12 17.5 12 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21.5,19c0,0.27-0.23,0.5-0.5,0.5 H3c-0.27,0-0.5-0.23-0.5-0.5V6c0-0.27,0.23-0.5,0.5-0.5h18c0.27,0,0.5,0.23,0.5,0.5V19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C11,8.22,10.78,8,10.5,8h-1C9.22,8,9,8.22,9,8.5v1C9,9.78,9.22,10,9.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.5,8h-1C5.22,8,5,8.22,5,8.5v1C5,9.78,5.22,10,5.5,10h1C6.78,10,7,9.78,7,9.5v-1C7,8.22,6.78,8,6.5,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15.25,16h-6.5C8.34,16,8,16.34,8,16.75c0,0.41,0.34,0.75,0.75,0.75h6.5c0.41,0,0.75-0.34,0.75-0.75 C16,16.34,15.66,16,15.25,16z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C15,8.22,14.78,8,14.5,8h-1C13.22,8,13,8.22,13,8.5v1C13,9.78,13.22,10,13.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1C9.22,12,9,12.22,9,12.5v1C9,13.78,9.22,14,9.5,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.5,12h-1C5.22,12,5,12.22,5,12.5v1C5,13.78,5.22,14,5.5,14h1C6.78,14,7,13.78,7,13.5v-1C7,12.22,6.78,12,6.5,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C13,13.78,13.22,14,13.5,14 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.5,8h-1C17.22,8,17,8.22,17,8.5v1c0,0.28,0.22,0.5,0.5,0.5h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,8.22,18.78,8,18.5,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.5,12h-1c-0.28,0-0.5,0.22-0.5,0.5v1c0,0.28,0.22,0.5,0.5,0.5h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,12.22,18.78,12,18.5,12 z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml
index 8532bdd..a341880 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.35,21.15h0.07l3.88-0.6a1,1,0,0,0,0.56-0.28L21,7.07h0A0.75 0.75 ,0,0,0,21,6L18,3h0a0.73 0.73 ,0,0,0-0.52-0.21A0.74 0.74 ,0,0,0,17,3L15.51,4.45h0L14.44,5.5h0L3.73,16.14a1,1,0,0,0-0.28 0.56 l-0.6,3.88A0.51 0.51 ,0,0,0,3.35,21.15ZM17.5,4.59l1.95,1.94-0.93 0.93 L16.57,5.51ZM4.91,17.09,15.51,6.56l2,2L6.91,19.09l-2.37 0.37 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.08,5.08l-1.17-1.17c-0.39-0.39-0.9-0.58-1.41-0.58c-0.51,0-1.02,0.2-1.41,0.59L3.29,16.71C3.11,16.89,3,17.15,3,17.41 l0,2.59c0,0.55,0.45,1,1,1c0,0,0,0,0,0L6.59,21c0.26,0,0.52-0.11,0.71-0.29l10.68-10.68l0,0l1.06-1.06l0,0l1.05-1.06 C20.87,7.13,20.87,5.86,20.08,5.08z M6.38,19.5l-1.88,0l0-1.88L15.03,7.09l1.88,1.88L6.38,19.5z M19.02,6.85l-1.06,1.06l-1.88-1.88 l1.05-1.05c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.35,0.15l1.17,1.17c0.13,0.13,0.15,0.28,0.15,0.35 C19.17,6.57,19.15,6.72,19.02,6.85z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml
index c62203d..b57d509 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,16.35A1.41,1.41,0,0,0,20,15l-2.42-0.73a1.43,1.43,0,0,0-1.41 0.34 l-2.95,2.87a16.48,16.48,0,0,1-3.74-2.7,17.33,17.33,0,0,1-3-4L9.36,7.94a1.42,1.42,0,0,0,0.37-1.36L9.07,4.12a1.43,1.43,0,0,0-1.37-1h-4a0.56 0.56 ,0,0,0-0.12,0,0.58 0.58 ,0,0,0-0.14,0,0.54 0.54 ,0,0,0-0.12 0.09 l-0.11 0.08 a0.94 0.94 ,0,0,0-0.09 0.12 l-0.07 0.12 ,0,0.15s0,0.08,0,0.12v0a18.53,18.53,0,0,0,5.42,12,18.25,18.25,0,0,0,11.79,5.07h0a0.72 0.72 ,0,0,0,0.29-0.06l0.08-0.05a0.53 0.53 ,0,0,0,0.15-0.11 0.31 0.31,0,0,0,0.07-0.09 0.67 0.67,0,0,0,0.09-0.14 0.53 0.53,0,0,0,0-0.12 0.37 0.37,0,0,0,0-0.15h0V16.35ZM8.3,6.88,5.81,9.33A17.23,17.23,0,0,1,4.58,4.58H7.64Zm8.83,8.82,2.37 0.72 v2.93a17.06,17.06,0,0,1-4.85-1.19Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,16.35c0-0.62-0.4-1.17-1.01-1.35l-2.42-0.73c-0.5-0.15-1.04-0.02-1.41,0.34l-2.96,2.87c-1.36-0.72-2.62-1.62-3.74-2.7 c-1.2-1.2-2.19-2.56-2.97-4.02l2.87-2.82c0.36-0.36,0.5-0.88,0.37-1.37L9.07,4.12C8.9,3.51,8.34,3.08,7.7,3.08H3.75 c-0.01,0-0.01,0-0.02,0c-0.01,0-0.02,0-0.02,0c-0.05,0-0.08,0.02-0.13,0.03C3.53,3.13,3.48,3.13,3.44,3.15 C3.39,3.17,3.36,3.21,3.32,3.24C3.28,3.26,3.24,3.29,3.21,3.32C3.17,3.36,3.15,3.4,3.12,3.44C3.1,3.48,3.07,3.52,3.05,3.56 c-0.02,0.05-0.02,0.1-0.03,0.15C3.02,3.75,3,3.79,3,3.83c0,0.01,0,0.01,0,0.02c0,0.01,0,0.02,0,0.02c0.28,4.51,2.2,8.76,5.42,11.98 c3.18,3.06,7.37,4.86,11.8,5.07c0.01,0,0.02,0,0.04,0c0,0,0,0,0,0s0,0,0,0c0,0,0,0,0,0c0.1,0,0.2-0.02,0.29-0.06 c0.03-0.01,0.05-0.04,0.08-0.05c0.05-0.03,0.11-0.06,0.15-0.1c0.03-0.03,0.04-0.06,0.07-0.09c0.03-0.04,0.07-0.09,0.09-0.14 c0.02-0.04,0.02-0.08,0.03-0.12C20.98,20.3,21,20.26,21,20.2c0-0.01,0-0.01,0-0.02c0-0.01,0-0.01,0-0.02V16.35z M8.3,6.88 L5.81,9.33c-0.63-1.51-1.05-3.1-1.23-4.74h3.05L8.3,6.88z M17.13,15.7l2.37,0.71v2.93c-1.68-0.16-3.31-0.56-4.85-1.19L17.13,15.7z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_airplane.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_airplane.xml
new file mode 100644
index 0000000..01accfb
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_airplane.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.52,16.17c0.32,0.23,0.74,0.31,1.11,0.19l5.87-1.84v3.87L8,19.52c-0.31,0.24-0.5,0.61-0.5,1v0.75 c0,0.69,0.56,1.25,1.25,1.25h6.5c0.69,0,1.25-0.56,1.25-1.25v-0.75c0-0.39-0.19-0.76-0.5-1l-1.5-1.12v-3.87l5.88,1.84 c0.38,0.12,0.79,0.05,1.11-0.19c0.32-0.23,0.51-0.61,0.51-1.01l0-1.84c0-0.63-0.34-1.21-0.89-1.52L14.5,8.06V4 c0-1.38-1.12-2.5-2.5-2.5S9.5,2.62,9.5,4v4.07L2.89,11.8C2.35,12.11,2,12.7,2,13.33l0,1.83C2.01,15.56,2.2,15.94,2.52,16.17z M3.63,13.11L11,8.94V4c0-0.55,0.45-1,1-1s1,0.45,1,1v4.94l7.37,4.17c0.08,0.04,0.13,0.13,0.13,0.22l0,1.5L13,12.48v6.66l2,1.5 v0.38H9v-0.38l2-1.5v-6.66l-7.5,2.34l0-1.49C3.5,13.24,3.55,13.15,3.63,13.11z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml
new file mode 100644
index 0000000..1593810
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_auto_rotate.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M3.5,7C3.09,7,2.75,7.34,2.75,7.75v2.73c0,0.41,0.34,0.75,0.75,0.75h2.75c0.41,0,0.75-0.34,0.75-0.75S6.66,9.73,6.25,9.73 H5.33l5.42-5.42l6.47,6.47c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06l-7-7 c-0.29-0.29-0.77-0.29-1.06,0L4.25,8.69V7.75C4.25,7.34,3.91,7,3.5,7z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.5,17c0.41,0,0.75-0.34,0.75-0.75V13.5c0-0.41-0.34-0.75-0.75-0.75h-2.75c-0.41,0-0.75,0.34-0.75,0.75 s0.34,0.75,0.75,0.75h0.94l-5.44,5.44l-6.47-6.47c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l7,7 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22l5.97-5.97v0.94C19.75,16.66,20.09,17,20.5,17z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
new file mode 100644
index 0000000..d49b81e
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.53,6.72l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C11.68,1.92,11.5,2.2,11.5,2.5v7.69L7.53,6.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L11.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l3.97-3.97v7.69 c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.2,0,0.39-0.08,0.53-0.22l4.75-4.75c0.29-0.29,0.29-0.77,0-1.06 L13.31,12l4.22-4.22C17.82,7.49,17.82,7.01,17.53,6.72z M15.94,16.75L13,19.69v-5.88L15.94,16.75z M13,10.19V4.31l2.94,2.94 L13,10.19z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_dnd.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_dnd.xml
new file mode 100644
index 0000000..8b5f98e
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_dnd.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M16.25,11.25h-8.5C7.34,11.25,7,11.59,7,12s0.34,0.75,0.75,0.75h8.5c0.41,0,0.75-0.34,0.75-0.75S16.66,11.25,16.25,11.25z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C6.49,2,2,6.49,2,12s4.49,10,10,10c0,0,0.01,0,0.01,0c5.5,0,9.98-4.47,9.99-9.98V12C22,6.49,17.51,2,12,2z M20.5,12.02c0,4.68-3.81,8.48-8.49,8.48c0,0-0.01,0-0.01,0c-4.69,0-8.5-3.81-8.5-8.5S7.31,3.5,12,3.5s8.5,3.81,8.5,8.5V12.02z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_flashlight.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_flashlight.xml
new file mode 100644
index 0000000..2481763
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_flashlight.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17,2H7C6.59,2,6.25,2.34,6.25,2.75v5c0,0.14,0.04,0.27,0.11,0.39l1.89,3.07v10.04C8.25,21.66,8.59,22,9,22h6 c0.41,0,0.75-0.34,0.75-0.75v-9.79l1.89-3.07c0.07-0.12,0.11-0.25,0.11-0.39V2.75C17.75,2.34,17.41,2,17,2z M16.25,7.79 l-1.89,3.07c-0.07,0.12-0.11,0.25-0.11,0.39v9.25h-4.5V11c0-0.14-0.04-0.27-0.11-0.39L7.75,7.54V6.5h8.5V7.79z M16.25,5h-8.5V3.5 h8.5V5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 12.75 C 12.6903559373 12.75 13.25 13.3096440627 13.25 14 C 13.25 14.6903559373 12.6903559373 15.25 12 15.25 C 11.3096440627 15.25 10.75 14.6903559373 10.75 14 C 10.75 13.3096440627 11.3096440627 12.75 12 12.75 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_night_display_on.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_night_display_on.xml
index 96ce11c..e26d647 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_night_display_on.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_night_display_on.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22.63,16.12a0.75 0.75 ,0,0,0-0.76-0.32,12.23,12.23,0,0,1-2.12 0.2 A11.76,11.76,0,0,1,8,4.25a12.23,12.23,0,0,1,0.2-2.12 0.73 0.73,0,0,0-0.32-0.76 0.74 0.74,0,0,0-0.83,0A11.25,11.25,0,1,0,22.63,17,0.74 0.74 ,0,0,0,22.63,16.12ZM13.25,20.5A9.75,9.75,0,0,1,6.51,3.71c0,0.18,0,0.36,0,0.54A13.27,13.27,0,0,0,20.29,17.49,9.71,9.71,0,0,1,13.25,20.5Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M22.63,16.12c-0.17-0.25-0.47-0.38-0.76-0.33c-0.74,0.14-1.44,0.2-2.12,0.2C13.27,16,8,10.73,8,4.25 c0-0.68,0.07-1.38,0.2-2.12c0.05-0.3-0.07-0.59-0.33-0.76C7.63,1.2,7.3,1.2,7.05,1.37C3.89,3.46,2,6.97,2,10.75 C2,16.95,7.05,22,13.25,22c3.78,0,7.29-1.89,9.38-5.05C22.8,16.7,22.8,16.37,22.63,16.12z M13.25,20.5c-5.38,0-9.75-4.37-9.75-9.75 c0-2.69,1.1-5.22,3.01-7.04C6.5,3.89,6.5,4.07,6.5,4.25c0,7.49,6.28,13.57,13.79,13.24C18.47,19.4,15.94,20.5,13.25,20.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_restart.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_restart.xml
new file mode 100644
index 0000000..425fd81
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_restart.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12.03,2.96c-0.29-0.29-0.77-0.29-1.06,0l-2.51,2.5C8.33,5.61,8.25,5.8,8.25,6s0.08,0.39,0.22,0.53l2.51,2.5 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06l-1.34-1.34C11.12,6.55,11.56,6.5,12,6.5 c3.58,0,6.5,2.92,6.5,6.5c0,3.05-2.07,5.66-5.04,6.34c-0.4,0.09-0.66,0.5-0.56,0.9c0.08,0.35,0.39,0.58,0.73,0.58 c0.06,0,0.11-0.01,0.17-0.02C17.45,19.96,20,16.75,20,13c0-4.41-3.59-8-8-8c-0.34,0-0.68,0.03-1.01,0.07l1.05-1.05 C12.33,3.73,12.33,3.26,12.03,2.96z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M7,7.69C6.69,7.42,6.22,7.46,5.95,7.77C4.69,9.22,4,11.08,4,13c0,3.75,2.55,6.96,6.21,7.8c0.06,0.01,0.11,0.02,0.17,0.02 c0.34,0,0.65-0.24,0.73-0.58c0.09-0.4-0.16-0.81-0.56-0.9C7.57,18.66,5.5,16.05,5.5,13c0-1.56,0.56-3.07,1.58-4.25 C7.35,8.44,7.32,7.96,7,7.69z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_screenshot.xml
new file mode 100644
index 0000000..ef033e6
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_screenshot.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M15.25,12c-0.41,0-0.75,0.34-0.75,0.75v2.75h-2.75c-0.41,0-0.75,0.34-0.75,0.75S11.34,17,11.75,17h3.5 c0.41,0,0.75-0.34,0.75-0.75v-3.5C16,12.34,15.66,12,15.25,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13,7.75C13,7.34,12.66,7,12.25,7h-3.5C8.34,7,8,7.34,8,7.75v3.5C8,11.66,8.34,12,8.75,12s0.75-0.34,0.75-0.75V8.5h2.75 C12.66,8.5,13,8.16,13,7.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16,23c1.66,0,3-1.34,3-3V4c0-1.66-1.34-3-3-3H8C6.34,1,5,2.34,5,4v16c0,1.66,1.34,3,3,3H16z M8,2.5h8 c0.83,0,1.5,0.67,1.5,1.5h-11C6.5,3.17,7.17,2.5,8,2.5z M6.5,5.5h11v13h-11V5.5z M6.5,20h11c0,0.83-0.67,1.5-1.5,1.5H8 C7.17,21.5,6.5,20.83,6.5,20z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_settings_bluetooth.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
new file mode 100644
index 0000000..d49b81e
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.53,6.72l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C11.68,1.92,11.5,2.2,11.5,2.5v7.69L7.53,6.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L11.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l3.97-3.97v7.69 c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.2,0,0.39-0.08,0.53-0.22l4.75-4.75c0.29-0.29,0.29-0.77,0-1.06 L13.31,12l4.22-4.22C17.82,7.49,17.82,7.01,17.53,6.72z M15.94,16.75L13,19.69v-5.88L15.94,16.75z M13,10.19V4.31l2.94,2.94 L13,10.19z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_signal_location.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_signal_location.xml
index eb94952..133ccea 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_signal_location.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_signal_location.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-4.5,0A1.5,1.5,0,1,1,12,11.5,1.5,1.5,0,0,1,10.5,10Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M11.37,21.76A1,1,0,0,0,12,22a1,1,0,0,0,0.62-0.22C14.5,20.26,20,15.5,20,10a8,8,0,0,0-8-8,7.89,7.89,0,0,0-8,8C4,15.5,9.48,20.25,11.37,21.76ZM12,3.51A6.5,6.5,0,0,1,18.5,10c0,4.4-4.31,8.53-6.5,10.34C9.82,18.54,5.5,14.4,5.5,10A6.43,6.43,0,0,1,12,3.51Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,7c-1.66,0-3,1.34-3,3s1.34,3,3,3s3-1.34,3-3S13.66,7,12,7z M12,11.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S12.83,11.5,12,11.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,2.01c-4.5,0-8,3.49-8,8c0,5.49,5.48,10.24,7.37,11.76c0.19,0.15,0.41,0.22,0.63,0.22c0.22,0,0.44-0.07,0.62-0.22 C14.5,20.26,20,15.5,20,10C20,5.72,16.5,2.01,12,2.01z M12,20.34c-2.18-1.8-6.5-5.94-6.5-10.34c0-3.64,2.86-6.5,6.5-6.5 c3.58,0,6.5,2.91,6.5,6.49C18.5,14.4,14.19,18.53,12,20.34z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_0.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_0.xml
index 96d04c3..8aeb60a 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_0.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_0.xml
@@ -1,49 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M22.8,7.25a0.73 0.73 ,0,0,1,0,1l0,0a0.83 0.83 ,0,0,1-1.05,0,13.16,13.16,0,0,0-9.7-4,13.34,13.34,0,0,0-9.7,4,0.72 0.72 ,0,0,1-1,0l0,0a0.76 0.76 ,0,0,1,0-1.05A14.77,14.77,0,0,1,12,2.8,14.51,14.51,0,0,1,22.8,7.25Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M8.3,14.8a0.73 0.73 ,0,0,1-1,0l0,0a0.76 0.76 ,0,0,1,0-1,6.73,6.73,0,0,1,9.52,0l0,0h0a0.75 0.75 ,0,0,1,0.12,1.05 0.75 0.75,0,0,1-1.05 0.12 l-0.07-0.07a0,0,0,0,1-0.05,0h0A5.28,5.28,0,0,0,8.3,14.8Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M20.05,10.75A0.74 0.74 ,0,0,1,19,11.8h0a10.15,10.15,0,0,0-6.95-3,9.93,9.93,0,0,0-7,3,0.74 0.74 ,0,0,1-1-1.05,11.36,11.36,0,0,1,8.05-3.5A11.43,11.43,0,0,1,20.05,10.75Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.2,0.24,0.49,0.37,0.77,0.37 s0.57-0.12,0.77-0.37L23.14,8.43c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2z M12,19.64L2.01,7.48 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L12,19.64z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_1.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_1.xml
index b887320..01155ea 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_1.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_1.xml
@@ -1,46 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M16.77,13.71a6.74,6.74,0,0,0-9.54,0,0.75 0.75 ,0,0,0,1.06,1.06h0a5.25,5.25,0,0,1,7.42,0h0a0.08 0.08 ,0,0,1,0,0,0.75 0.75 ,0,0,0,1.17-1,0.8 0.8 ,0,0,0-0.17-0.15Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M20,10.73a11.51,11.51,0,0,0-8-3.5,11.55,11.55,0,0,0-8,3.5 0.75 0.75,0,0,0,0.95,1.15A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3,10.1,10.1,0,0,1,7,3,0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M22.79,7.23A14.76,14.76,0,0,0,12,2.75,14.72,14.72,0,0,0,1.23,7.2a0.75 0.75 ,0,0,0,1.07,1,13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.75 0.75 ,0,0,0,1.07-1Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l6.72,8.19c0,0,0,0,0,0l0.52,0.64l3.12,3.8 c0.2,0.24,0.49,0.37,0.77,0.37s0.57-0.12,0.77-0.37l3.12-3.8l0.52-0.64c0,0,0,0,0,0l6.72-8.19c0.5-0.61,0.45-1.51-0.13-2.05 C20.12,3.66,16.25,2,12,2z M15.77,15.04c-0.09-0.14-0.19-0.28-0.3-0.41c-0.82-1-2.07-1.64-3.47-1.64s-2.65,0.64-3.47,1.64 c-0.11,0.13-0.21,0.27-0.3,0.41L2.01,7.48C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L15.77,15.04z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_2.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_2.xml
index af41245..bf5a358 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_2.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_2.xml
@@ -1,43 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.77,13.71a6.74,6.74,0,0,0-9.54,0,0.75 0.75 ,0,0,0,1.06,1.06h0a5.25,5.25,0,0,1,7.42,0h0a0.08 0.08 ,0,0,1,0,0,0.75 0.75 ,0,0,0,1.17-1,0.8 0.8 ,0,0,0-0.17-0.15Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M20,10.73a11.51,11.51,0,0,0-8-3.5,11.55,11.55,0,0,0-8,3.5 0.75 0.75,0,0,0,0.95,1.15A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3,10.1,10.1,0,0,1,7,3,0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M22.79,7.23A14.76,14.76,0,0,0,12,2.75,14.72,14.72,0,0,0,1.23,7.2a0.75 0.75 ,0,0,0,1.07,1,13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.75 0.75 ,0,0,0,1.07-1Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.2,0.24,0.49,0.37,0.77,0.37 s0.57-0.12,0.77-0.37L23.14,8.43c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2z M17.72,12.68 c-0.11-0.13-0.21-0.27-0.33-0.39c-1.36-1.42-3.27-2.3-5.39-2.3s-4.03,0.88-5.39,2.3c-0.12,0.12-0.22,0.26-0.33,0.39l-4.27-5.2 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L17.72,12.68z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_3.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_3.xml
index c137643..ff8c305 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_3.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_3.xml
@@ -1,40 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.77,13.71a6.74,6.74,0,0,0-9.54,0,0.75 0.75 ,0,0,0,1.06,1.06h0a5.25,5.25,0,0,1,7.42,0h0a0.08 0.08 ,0,0,1,0,0,0.75 0.75 ,0,0,0,1.17-1,0.8 0.8 ,0,0,0-0.17-0.15Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20,10.73a11.51,11.51,0,0,0-8-3.5,11.55,11.55,0,0,0-8,3.5 0.75 0.75,0,0,0,0.95,1.15A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3,10.1,10.1,0,0,1,7,3,0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M22.79,7.23A14.76,14.76,0,0,0,12,2.75,14.72,14.72,0,0,0,1.23,7.2a0.75 0.75 ,0,0,0,1.07,1,13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.75 0.75 ,0,0,0,1.07-1Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l2.44,2.98c0,0,0,0,0,0l7.93,9.65 c0.4,0.49,1.15,0.49,1.55,0l7.93-9.65c0,0,0,0,0,0l2.44-2.98c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2z M19.71,10.25 c-0.09-0.09-0.17-0.19-0.27-0.27C17.51,8.12,14.9,6.99,12,6.99S6.49,8.13,4.56,9.98c-0.09,0.09-0.18,0.18-0.26,0.27L2.01,7.48 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L19.71,10.25z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_4.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_4.xml
index b8f2d78..e31a550 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_4.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_wifi_signal_4.xml
@@ -1,37 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20,11.79a0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.77 0.77,0,0,0,0,1.07 0.76 0.76,0,0,0,1.07,0,10.12,10.12,0,0,1,7-3,10.12,10.12,0,0,1,7,3A0.75 0.75 ,0,0,0,20,11.79Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15.78,14.82a0.57 0.57 ,0,0,0,0.16 0.15 0.75 0.75 ,0,0,0,1-0.2 0.76 0.76,0,0,0-0.2-1,6.77,6.77,0,0,0-9.55,0,0.76 0.76 ,0,0,0,0,1,0.75 0.75 ,0,0,0,1.06,0h0a5.24,5.24,0,0,1,7.42,0A0.08 0.08 ,0,0,0,15.78,14.82Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.3,8.25a13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.73 0.73 ,0,0,0,1,0,0.75 0.75 ,0,0,0,0.05-1.06A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.77 0.77 ,0,0,0,0,1A0.75 0.75 ,0,0,0,2.3,8.25Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.4,0.49,1.15,0.49,1.55,0L23.14,8.43 c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_empty_recents.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_empty_recents.xml
deleted file mode 100644
index 76f8831..0000000
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_empty_recents.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,6h2c0.55,0,1,0.45,1,1v9c0,0.55-0.45,1-1,1H3c-0.55,0-1-0.45-1-1V7C2,6.45,2.45,6,3,6z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M8,19h8c0.55,0,1-0.45,1-1V5c0-0.55-0.45-1-1-1H8C7.45,4,7,4.45,7,5v13C7,18.55,7.45,19,8,19z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19,6h2c0.55,0,1,0.45,1,1v9c0,0.55-0.45,1-1,1h-2c-0.55,0-1-0.45-1-1V7C18,6.45,18.45,6,19,6z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_airplanemode_active.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_airplanemode_active.xml
new file mode 100644
index 0000000..ed64277
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_airplanemode_active.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.52,16.17c0.32,0.23,0.74,0.31,1.11,0.19l5.87-1.84v3.87L8,19.52c-0.31,0.24-0.5,0.61-0.5,1v0.75 c0,0.69,0.56,1.25,1.25,1.25h6.5c0.69,0,1.25-0.56,1.25-1.25v-0.75c0-0.39-0.19-0.76-0.5-1l-1.5-1.12v-3.87l5.88,1.84 c0.38,0.12,0.79,0.05,1.11-0.19c0.32-0.23,0.51-0.61,0.51-1.01l0-1.84c0-0.63-0.34-1.21-0.89-1.52L14.5,8.06V4 c0-1.38-1.12-2.5-2.5-2.5S9.5,2.62,9.5,4v4.07L2.89,11.8C2.35,12.11,2,12.7,2,13.33l0,1.83C2.01,15.56,2.2,15.94,2.52,16.17z M3.63,13.11L11,8.94V4c0-0.55,0.45-1,1-1s1,0.45,1,1v4.94l7.37,4.17c0.08,0.04,0.13,0.13,0.13,0.22l0,1.5L13,12.48v6.66l2,1.5 v0.38H9v-0.38l2-1.5v-6.66l-7.5,2.34l0-1.49C3.5,13.24,3.55,13.15,3.63,13.11z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml
index 62acfc6..1dca653 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml
@@ -1,52 +1,28 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 5.5 4 L 6.5 4 Q 8 4 8 5.5 L 8 6.5 Q 8 8 6.5 8 L 5.5 8 Q 4 8 4 6.5 L 4 5.5 Q 4 4 5.5 4 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 11.5 4 L 12.5 4 Q 14 4 14 5.5 L 14 6.5 Q 14 8 12.5 8 L 11.5 8 Q 10 8 10 6.5 L 10 5.5 Q 10 4 11.5 4 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 17.5 4 L 18.5 4 Q 20 4 20 5.5 L 20 6.5 Q 20 8 18.5 8 L 17.5 8 Q 16 8 16 6.5 L 16 5.5 Q 16 4 17.5 4 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 5.5 10 L 6.5 10 Q 8 10 8 11.5 L 8 12.5 Q 8 14 6.5 14 L 5.5 14 Q 4 14 4 12.5 L 4 11.5 Q 4 10 5.5 10 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 11.5 10 L 12.5 10 Q 14 10 14 11.5 L 14 12.5 Q 14 14 12.5 14 L 11.5 14 Q 10 14 10 12.5 L 10 11.5 Q 10 10 11.5 10 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 17.5 10 L 18.5 10 Q 20 10 20 11.5 L 20 12.5 Q 20 14 18.5 14 L 17.5 14 Q 16 14 16 12.5 L 16 11.5 Q 16 10 17.5 10 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 5.5 16 L 6.5 16 Q 8 16 8 17.5 L 8 18.5 Q 8 20 6.5 20 L 5.5 20 Q 4 20 4 18.5 L 4 17.5 Q 4 16 5.5 16 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 11.5 16 L 12.5 16 Q 14 16 14 17.5 L 14 18.5 Q 14 20 12.5 20 L 11.5 20 Q 10 20 10 18.5 L 10 17.5 Q 10 16 11.5 16 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 17.5 16 L 18.5 16 Q 20 16 20 17.5 L 20 18.5 Q 20 20 18.5 20 L 17.5 20 Q 16 20 16 18.5 L 16 17.5 Q 16 16 17.5 16 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M6.5,4h-1C4.67,4,4,4.67,4,5.5v1C4,7.33,4.67,8,5.5,8h1C7.33,8,8,7.33,8,6.5v-1C8,4.67,7.33,4,6.5,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.5,4h-1C10.67,4,10,4.67,10,5.5v1C10,7.33,10.67,8,11.5,8h1C13.33,8,14,7.33,14,6.5v-1C14,4.67,13.33,4,12.5,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.5,4h-1C16.67,4,16,4.67,16,5.5v1C16,7.33,16.67,8,17.5,8h1C19.33,8,20,7.33,20,6.5v-1C20,4.67,19.33,4,18.5,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.5,10h-1C4.67,10,4,10.67,4,11.5v1C4,13.33,4.67,14,5.5,14h1C7.33,14,8,13.33,8,12.5v-1C8,10.67,7.33,10,6.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.5,10h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C14,10.67,13.33,10,12.5,10 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.5,10h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C20,10.67,19.33,10,18.5,10 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.5,16h-1C4.67,16,4,16.67,4,17.5v1C4,19.33,4.67,20,5.5,20h1C7.33,20,8,19.33,8,18.5v-1C8,16.67,7.33,16,6.5,16z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12.5,16h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C14,16.67,13.33,16,12.5,16 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.5,16h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C20,16.67,19.33,16,18.5,16 z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml
new file mode 100644
index 0000000..5fa15f4
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8,12a0.76 0.76 ,0,0,0,0.75 0.75 h2.5v2.5a0.75 0.75 ,0,0,0,1.5,0v-2.5h2.5a0.75 0.75 ,0,0,0,0-1.5h-2.5V8.75a0.75 0.75 ,0,0,0-1.5,0v2.5H8.75A0.76 0.76 ,0,0,0,8,12Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
index be7f297..1317fa9 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M22,18V10a1.5,1.5,0,0,0-1.5-1.5h-4A1.5,1.5,0,0,0,15,10v8a1.5,1.5,0,0,0,1.5,1.5h4A1.5,1.5,0,0,0,22,18Zm-5.5-8h4v8h-4Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M13,17a2.5,2.5,0,1,0-2.5,2.5A2.5,2.5,0,0,0,13,17ZM9.5,17a1,1,0,1,1,1,1A1,1,0,0,1,9.5,17Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M21.25,4H3.5A1.5,1.5,0,0,0,2,5.5V18a1.5,1.5,0,0,0,1.5,1.5H5.25a0.75 0.75 ,0,0,0,0-1.5H3.5V5.5H21.25a0.75 0.75 ,0,0,0,0-1.5Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M5.25,18H3.5V5.5h17.75C21.66,5.5,22,5.16,22,4.75S21.66,4,21.25,4H3.5C2.67,4,2,4.67,2,5.5V18c0,0.83,0.67,1.5,1.5,1.5 h1.75C5.66,19.5,6,19.16,6,18.75S5.66,18,5.25,18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M10.5,14.5C9.12,14.5,8,15.62,8,17s1.12,2.5,2.5,2.5S13,18.38,13,17S11.88,14.5,10.5,14.5z M10.5,18c-0.55,0-1-0.45-1-1 s0.45-1,1-1s1,0.45,1,1S11.05,18,10.5,18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.5,8.5h-4C15.67,8.5,15,9.17,15,10v8c0,0.83,0.67,1.5,1.5,1.5h4c0.83,0,1.5-0.67,1.5-1.5v-8 C22,9.17,21.33,8.5,20.5,8.5z M20.5,18h-4v-8h4V18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml
index e8c3e47..36f2965 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,22h0A10,10,0,0,0,22,12v0A10,10,0,1,0,12,22ZM12,3.5A8.51,8.51,0,0,1,20.5,12h0.75l-0.75,0A8.49,8.49,0,0,1,12,20.5h0a8.5,8.5,0,0,1,0-17Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M8.67,10a0.77 0.77 ,0,0,0,0.91-0.56,2.48,2.48,0,0,1,0.65-1.19,2.57,2.57,0,0,1,3.54,0A2.2,2.2,0,0,1,14.43,10a1.81,1.81,0,0,1-0.84,1.37c-0.13 0.09 -0.26 0.16 -0.4 0.24 a3.3,3.3,0,0,0-1.93,2.51 0.76 0.76,0,0,0,0.62 0.87 H12a0.75 0.75 ,0,0,0,0.74-0.62,1.84,1.84,0,0,1,1.19-1.46l0.49-0.29a3.32,3.32,0,0,0,1.5-2.48,3.71,3.71,0,0,0-1.09-3,4.1,4.1,0,0,0-5.66,0,4,4,0,0,0-1.05,1.9A0.75 0.75 ,0,0,0,8.67,10Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,22c0,0,0.01,0,0.01,0c5.5,0,9.98-4.47,9.99-9.98V12c0-5.51-4.49-10-10-10S2,6.49,2,12S6.49,22,12,22z M12,3.5 c4.69,0,8.5,3.81,8.5,8.5v0.02c0,4.68-3.81,8.48-8.49,8.48c0,0-0.01,0-0.01,0c-4.69,0-8.5-3.81-8.5-8.5S7.31,3.5,12,3.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8.67,9.98c0.4,0.1,0.81-0.15,0.9-0.56c0.11-0.47,0.33-0.86,0.65-1.19c0.94-0.94,2.59-0.94,3.54,0 c0.49,0.49,0.73,1.13,0.67,1.76c-0.06,0.57-0.36,1.06-0.84,1.38c-0.13,0.08-0.26,0.16-0.4,0.24c-0.7,0.4-1.67,0.94-1.93,2.51 c-0.07,0.41,0.21,0.8,0.61,0.86C11.92,15,11.96,15,12,15c0.36,0,0.68-0.26,0.74-0.62c0.15-0.87,0.58-1.12,1.19-1.46 c0.17-0.09,0.33-0.19,0.49-0.29c0.87-0.58,1.41-1.46,1.51-2.48c0.11-1.08-0.29-2.17-1.1-2.97c-1.51-1.51-4.15-1.51-5.66,0 c-0.52,0.51-0.88,1.17-1.05,1.9C8.02,9.48,8.27,9.88,8.67,9.98z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml
index e5e57d4..35422fc 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M8,1A3,3,0,0,0,5,4V20a3,3,0,0,0,3,3h8a3,3,0,0,0,3-3V4a3,3,0,0,0-3-3Zm8,20.5H8A1.5,1.5,0,0,1,6.5,20h11A1.5,1.5,0,0,1,16,21.5Zm1.5-3H6.5V5.5h11ZM17.5,4H6.5A1.5,1.5,0,0,1,8,2.5h8A1.5,1.5,0,0,1,17.5,4Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,11.25a0.76 0.76 ,0,0,0-0.75 0.75 v4a0.75 0.75 ,0,0,0,1.5,0V12A0.76 0.76 ,0,0,0,12,11.25Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M8,1C6.34,1,5,2.34,5,4v16c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V4c0-1.66-1.34-3-3-3H8z M16,21.5H8 c-0.83,0-1.5-0.67-1.5-1.5h11C17.5,20.83,16.83,21.5,16,21.5z M17.5,18.5h-11v-13h11V18.5z M17.5,4h-11c0-0.83,0.67-1.5,1.5-1.5h8 C16.83,2.5,17.5,3.17,17.5,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml
index 1ac58b5..2d24cd1 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -1,40 +1,24 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M14.25,2.5A2.25,2.25,0,1,0,12,4.75,2.25,2.25,0,0,0,14.25,2.5Zm-3,0a0.75 0.75 ,0,1,1,0.75 0.75 A0.76 0.76 ,0,0,1,11.25,2.5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M20.72,5.28a0.77 0.77 ,0,0,0-0.94-0.5,29.53,29.53,0,0,1-7.78,1,29.72,29.72,0,0,1-7.78-1,0.75 0.75 ,0,0,0-0.44,1.44A28.14,28.14,0,0,0,9,7.12V19a0.75 0.75 ,0,0,0,1.5,0V14h3v5A0.75 0.75 ,0,0,0,15,19V7.12a28.14,28.14,0,0,0,5.22-0.9A0.76 0.76 ,0,0,0,20.72,5.28Zm-7.22,2V12.5h-3V7.25Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 0.5 C 13.1045694997 0.5 14 1.39543050034 14 2.5 C 14 3.60456949966 13.1045694997 4.5 12 4.5 C 10.8954305003 4.5 10 3.60456949966 10 2.5 C 10 1.39543050034 10.8954305003 0.5 12 0.5 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.72,5.28c-0.12-0.4-0.54-0.62-0.94-0.5C19.75,4.79,16.55,5.75,12,5.75c-4.53,0-7.75-0.96-7.78-0.97 c-0.39-0.12-0.81,0.1-0.94,0.5c-0.12,0.4,0.1,0.81,0.5,0.94C3.89,6.25,5.89,6.85,9,7.12v12.13C9,19.66,9.34,20,9.75,20 s0.75-0.34,0.75-0.75V14h3v5.25c0,0.41,0.34,0.75,0.75,0.75S15,19.66,15,19.25V7.12c3.11-0.27,5.11-0.87,5.22-0.9 C20.61,6.1,20.84,5.68,20.72,5.28z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml
index 90da97f..710ed5e 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M6.21,20.14l0.08 0.06 A10,10,0,0,0,12,22h0a10,10,0,0,0,5.76-1.84h0A10,10,0,0,0,22,12v0A10,10,0,1,0,6.21,20.14Zm5.8 0.36 h0a8.45,8.45,0,0,1-4.5-1.3V15.75A0.76 0.76 ,0,0,1,8.25,15h7.5a0.76 0.76 ,0,0,1,0.75 0.75 V19.2A8.39,8.39,0,0,1,12,20.5Zm0-17A8.51,8.51,0,0,1,20.5,12h0.75l-0.75,0A8.47,8.47,0,0,1,18,18V15.75a2.25,2.25,0,0,0-2.25-2.25H8.25A2.25,2.25,0,0,0,6,15.75V18A8.49,8.49,0,0,1,12,3.5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,12h0A3,3,0,1,0,9,9H9A3,3,0,0,0,12,12ZM10.5,9A1.5,1.5,0,1,1,12,10.5h0A1.5,1.5,0,0,1,10.5,9Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C6.49,2,2,6.49,2,12c0,3.36,1.67,6.33,4.21,8.14c0.02,0.02,0.05,0.04,0.07,0.06C7.91,21.33,9.88,22,12,22 c0,0,0.01,0,0.01,0c2.15,0,4.13-0.69,5.76-1.84c0,0,0.01,0,0.01-0.01c2.55-1.81,4.22-4.77,4.22-8.13V12C22,6.49,17.51,2,12,2z M16.5,19.2c-1.3,0.82-2.84,1.3-4.49,1.3c0,0-0.01,0-0.01,0c-1.65,0-3.19-0.48-4.5-1.3v-3.45C7.5,15.34,7.84,15,8.25,15h7.5 c0.41,0,0.75,0.34,0.75,0.75V19.2z M20.5,12.02c0,2.34-0.96,4.47-2.5,6v-2.27c0-1.24-1.01-2.25-2.25-2.25h-7.5 C7.01,13.5,6,14.51,6,15.75v2.26C4.46,16.47,3.5,14.35,3.5,12c0-4.69,3.81-8.5,8.5-8.5s8.5,3.81,8.5,8.5V12.02z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,6c-1.65,0-3,1.35-3,3v0.01C9,10.66,10.35,12,11.99,12c0,0,0,0,0.01,0c1.65,0,3-1.35,3-3S13.65,6,12,6z M12,10.5 C12,10.5,12,10.5,12,10.5c-0.83,0-1.5-0.67-1.5-1.49V9c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5S12.83,10.5,12,10.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml
index 3f3b95a..bdeb9fc 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M13,2.49H11a1,1,0,0,0-1,1V4H7A1,1,0,0,0,6,5V21a1,1,0,0,0,1,1H17a1,1,0,0,0,1-1V5a1,1,0,0,0-1-1H14V3.49A1,1,0,0,0,13,2.49Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M13,2.49h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1V5c0-0.55-0.45-1-1-1h-3 V3.49C14,2.94,13.55,2.49,13,2.49z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_delete.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_delete.xml
new file mode 100644
index 0000000..7297658
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_delete.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20,4h-1h-4c0-0.55-0.45-1-1-1h-4C9.45,3,9,3.45,9,4H5H4C3.59,4,3.25,4.34,3.25,4.75S3.59,5.5,4,5.5h1V18 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V5.5h1c0.41,0,0.75-0.34,0.75-0.75S20.41,4,20,4z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V5.5h11V18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14.25,8c-0.41,0-0.75,0.34-0.75,0.75v7.5c0,0.41,0.34,0.75,0.75,0.75S15,16.66,15,16.25v-7.5C15,8.34,14.66,8,14.25,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.75,8C9.34,8,9,8.34,9,8.75v7.5C9,16.66,9.34,17,9.75,17s0.75-0.34,0.75-0.75v-7.5C10.5,8.34,10.16,8,9.75,8z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
index 54993e2..41d9e5d 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -1,52 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19.5,12h0A7.5,7.5,0,1,0,12,19.5h0A7.49,7.49,0,0,0,19.5,12ZM12,18h0a6,6,0,1,1,6-6h0a6,6,0,0,1-6,6Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 1.5 C 12.4142135624 1.5 12.75 1.83578643763 12.75 2.25 C 12.75 2.66421356237 12.4142135624 3 12 3 C 11.5857864376 3 11.25 2.66421356237 11.25 2.25 C 11.25 1.83578643763 11.5857864376 1.5 12 1.5 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 5.1 4.35 C 5.51421356237 4.35 5.85 4.68578643763 5.85 5.1 C 5.85 5.51421356237 5.51421356237 5.85 5.1 5.85 C 4.68578643763 5.85 4.35 5.51421356237 4.35 5.1 C 4.35 4.68578643763 4.68578643763 4.35 5.1 4.35 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 2.25 11.25 C 2.66421356237 11.25 3 11.5857864376 3 12 C 3 12.4142135624 2.66421356237 12.75 2.25 12.75 C 1.83578643763 12.75 1.5 12.4142135624 1.5 12 C 1.5 11.5857864376 1.83578643763 11.25 2.25 11.25 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 5.1 18.15 C 5.51421356237 18.15 5.85 18.4857864376 5.85 18.9 C 5.85 19.3142135624 5.51421356237 19.65 5.1 19.65 C 4.68578643763 19.65 4.35 19.3142135624 4.35 18.9 C 4.35 18.4857864376 4.68578643763 18.15 5.1 18.15 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 21 C 12.4142135624 21 12.75 21.3357864376 12.75 21.75 C 12.75 22.1642135624 12.4142135624 22.5 12 22.5 C 11.5857864376 22.5 11.25 22.1642135624 11.25 21.75 C 11.25 21.3357864376 11.5857864376 21 12 21 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 18.9 18.15 C 19.3142135624 18.15 19.65 18.4857864376 19.65 18.9 C 19.65 19.3142135624 19.3142135624 19.65 18.9 19.65 C 18.4857864376 19.65 18.15 19.3142135624 18.15 18.9 C 18.15 18.4857864376 18.4857864376 18.15 18.9 18.15 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 21.75 11.25 C 22.1642135624 11.25 22.5 11.5857864376 22.5 12 C 22.5 12.4142135624 22.1642135624 12.75 21.75 12.75 C 21.3357864376 12.75 21 12.4142135624 21 12 C 21 11.5857864376 21.3357864376 11.25 21.75 11.25 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 18.9 4.35 C 19.3142135624 4.35 19.65 4.68578643763 19.65 5.1 C 19.65 5.51421356237 19.3142135624 5.85 18.9 5.85 C 18.4857864376 5.85 18.15 5.51421356237 18.15 5.1 C 18.15 4.68578643763 18.4857864376 4.35 18.9 4.35 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.49,11.26h-1.03c-0.15-1.51-0.74-2.88-1.65-3.99l0.73-0.73c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L16.75,6.2 c-1.11-0.91-2.49-1.51-4-1.66V3.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.04c-1.5,0.15-2.88,0.75-3.99,1.65L6.53,5.46 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L6.2,7.25c-0.91,1.11-1.51,2.49-1.66,3.99H3.51c-0.41,0-0.75,0.34-0.75,0.75 s0.34,0.75,0.75,0.75h1.03c0.15,1.51,0.74,2.88,1.65,3.99l-0.73,0.73c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22l0.73-0.73c1.11,0.91,2.48,1.51,3.98,1.66v1.02c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.02 c1.48-0.14,2.86-0.71,4.01-1.65l0.73,0.73c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 l-0.72-0.72c0.94-1.14,1.51-2.52,1.66-4h1.03c0.41,0,0.75-0.34,0.75-0.75S20.9,11.26,20.49,11.26z M12,18c-3.31,0-6-2.69-6-6 s2.69-6,6-6s6,2.69,6,6S15.31,18,12,18z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml
index 26aa308..133ccea 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M15,10a3,3,0,1,0-3,3A3,3,0,0,0,15,10Zm-4.5,0A1.5,1.5,0,1,1,12,11.5,1.5,1.5,0,0,1,10.5,10Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M11.37,21.76A1,1,0,0,0,12,22a1,1,0,0,0,0.62-0.22C14.5,20.26,20,15.5,20,10a8,8,0,0,0-8-8,7.89,7.89,0,0,0-8,8C4,15.5,9.48,20.25,11.37,21.76ZM12,3.51A6.5,6.5,0,0,1,18.5,10c0,4.4-4.31,8.53-6.5,10.34C9.82,18.54,5.5,14.4,5.5,10A6.43,6.43,0,0,1,12,3.51Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,7c-1.66,0-3,1.34-3,3s1.34,3,3,3s3-1.34,3-3S13.66,7,12,7z M12,11.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S12.83,11.5,12,11.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,2.01c-4.5,0-8,3.49-8,8c0,5.49,5.48,10.24,7.37,11.76c0.19,0.15,0.41,0.22,0.63,0.22c0.22,0,0.44-0.07,0.62-0.22 C14.5,20.26,20,15.5,20,10C20,5.72,16.5,2.01,12,2.01z M12,20.34c-2.18-1.8-6.5-5.94-6.5-10.34c0-3.64,2.86-6.5,6.5-6.5 c3.58,0,6.5,2.91,6.5,6.49C18.5,14.4,14.19,18.53,12,20.34z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml
index a6619bd..df9be5d 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,8a4,4,0,0,0,0,8,3.94,3.94,0,0,0,2.23-0.68,5.06,5.06,0,0,1,1.67-2.47A4,4,0,0,0,16,12,4,4,0,0,0,12,8Zm0,6.5A2.5,2.5,0,1,1,14.5,12,2.5,2.5,0,0,1,12,14.5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M1.55,12.27C1.67,12.58,4.58,20,12,20a10.57,10.57,0,0,0,2-0.21V18.27a8.44,8.44,0,0,1-2,0.23c-5.72,0-8.37-5.22-8.94-6.5C3.63,10.75,6.33,5.5,12,5.5s8.38,5.22,9,6.5l-0.06 0.12 a4.84,4.84,0,0,1,1.28 0.8 c0.17-0.36 0.27 -0.6 0.29 -0.65a0.72 0.72 ,0,0,0,0-0.54C22.34,11.42,19.43,4,12,4S1.67,11.42,1.55,11.73A0.72 0.72 ,0,0,0,1.55,12.27Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M21.25,16.5v-0.66a2.26,2.26,0,0,0-4.5,0v0.66H16V22h6V16.5Zm-3,0v-0.66c0-0.29 0.38 -0.59 0.75 -0.59s0.75 0.3 0.75 0.59 v0.66Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,8c-2.21,0-4,1.79-4,4s1.79,4,4,4c0.76,0,1.46-0.22,2.06-0.59c0.16-1.38,0.88-2.59,1.94-3.39c0-0.01,0-0.02,0-0.02 C16,9.79,14.21,8,12,8z M12,14.5c-1.38,0-2.5-1.12-2.5-2.5s1.12-2.5,2.5-2.5c1.38,0,2.5,1.12,2.5,2.5S13.38,14.5,12,14.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.09,12C3.73,10.81,6.43,6.5,12,6.5c4.53,0,7.14,2.79,8.31,4.5h1.77C21.1,9.28,18.05,5,12,5c-7.4,0-10.32,6.42-10.44,6.7 c-0.09,0.19-0.09,0.41,0,0.61C1.68,12.58,4.61,19,12,19c0.71,0,1.37-0.07,2-0.18V17.3c-0.62,0.13-1.28,0.2-2,0.2 C6.39,17.5,3.73,13.21,3.09,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,16c0-0.35,0-0.72,0-1c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,0.37,0,0.7,0,1c-0.55,0-1,0.45-1,1v3c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-3C22,16.45,21.55,16,21,16z M20,16h-2v-1c0-0.55,0.45-1,1-1s1,0.45,1,1V16z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml
index d769f4f..a45e416 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M18.51,3A2.32,2.32,0,0,1,21,5.15a0.79 0.79 ,0,0,0,0.76 0.74 0.75 0.75 ,0,0,0,0.74-0.77,3.8,3.8,0,0,0-4-3.66,3.83,3.83,0,0,0-4,3.68V8.5h-9A1.5,1.5,0,0,0,4,10V20a1.5,1.5,0,0,0,1.5,1.5h13A1.5,1.5,0,0,0,20,20V10a1.5,1.5,0,0,0-1.5-1.5H16V5.15A2.35,2.35,0,0,1,18.51,3Zm0,17H5.5V10h13Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.51,1.46c-2.19-0.06-3.98,1.61-4.01,3.68V8.5h-9C4.67,8.5,4,9.17,4,10v10c0,0.83,0.67,1.5,1.5,1.5h13 c0.83,0,1.5-0.67,1.5-1.5V10c0-0.83-0.67-1.5-1.5-1.5H16V5.15c0.02-1.23,1.14-2.23,2.51-2.19C19.9,2.93,20.98,3.92,21,5.15 c0.01,0.41,0.36,0.71,0.76,0.74c0.41-0.01,0.74-0.35,0.74-0.76C22.46,3.07,20.7,1.39,18.51,1.46z M18.5,10v10h-13V10H18.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
index ee990f9..00a9523 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M19.07,4.93A10,10,0,1,0,22,12,10,10,0,0,0,19.07,4.93ZM18,18a8.5,8.5,0,1,1,2.5-6A8.53,8.53,0,0,1,18,18Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,10a0.76 0.76 ,0,0,0-0.75 0.75 v5.5a0.75 0.75 ,0,0,0,1.5,0v-5.5A0.76 0.76 ,0,0,0,12,10Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
index ffd2c64..2e80328 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
@@ -1,37 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M15.78,14.82a0.57 0.57 ,0,0,0,0.16 0.15 0.75 0.75 ,0,0,0,1-0.2 0.76 0.76,0,0,0-0.2-1,6.77,6.77,0,0,0-9.55,0,0.76 0.76 ,0,0,0,0,1,0.75 0.75 ,0,0,0,1.06,0h0a5.24,5.24,0,0,1,7.42,0A0.08 0.08 ,0,0,0,15.78,14.82Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M20,11.79a0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.77 0.77,0,0,0,0,1.07 0.76 0.76,0,0,0,1.07,0,10.12,10.12,0,0,1,7-3,10.12,10.12,0,0,1,7,3A0.75 0.75 ,0,0,0,20,11.79Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M12,2.75A14.76,14.76,0,0,0,1.22,7.2a0.77 0.77 ,0,0,0,0,1,0.75 0.75 ,0,0,0,1.06,0,13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.73 0.73 ,0,0,0,1,0,0.75 0.75 ,0,0,0,0.05-1.06A14.76,14.76,0,0,0,12,2.75Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2.75C7.95,2.69,4.05,4.3,1.22,7.2C0.96,7.5,0.97,7.95,1.24,8.23C1.53,8.53,2,8.54,2.3,8.25c2.55-2.61,6.05-4.06,9.7-4 c3.65-0.06,7.17,1.4,9.72,4.02c0.28,0.27,0.73,0.28,1.03,0.01c0.31-0.28,0.33-0.75,0.05-1.06C19.96,4.32,16.06,2.69,12,2.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15.78,14.82c0.05,0.06,0.1,0.11,0.17,0.15c0.34,0.23,0.81,0.14,1.04-0.21s0.14-0.81-0.21-1.04 c-2.64-2.64-6.91-2.64-9.55,0c-0.27,0.29-0.27,0.73,0,1.02c0.28,0.3,0.76,0.32,1.06,0.04h0.03c0,0,0,0,0.01-0.01 c2.05-2.05,5.37-2.04,7.42,0.01C15.75,14.8,15.76,14.81,15.78,14.82z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.03,11.79c0.3-0.29,0.3-0.77,0.01-1.06h-0.01c-2.12-2.18-5.01-3.44-8.04-3.5c-3.04,0.06-5.93,1.32-8.05,3.5 c-0.29,0.3-0.28,0.77,0.01,1.06c0.3,0.29,0.77,0.28,1.06-0.01c1.85-1.88,4.36-2.96,7-3c2.62,0.05,5.11,1.13,6.95,3 C19.25,12.07,19.73,12.08,20.03,11.79z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml
index e6125db..a2e429d 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -1,43 +1,25 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M21,2.75A0.76 0.76 ,0,0,0,20.25,2H3.75A0.76 0.76 ,0,0,0,3,2.75v4.5A0.76 0.76 ,0,0,0,3.75,8h16.5A0.76 0.76 ,0,0,0,21,7.25ZM19.5,6.5H4.5v-3h15Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 5.25 4.25 H 6.75 V 5.75 H 5.25 V 4.25 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M21,9.75A0.76 0.76 ,0,0,0,20.25,9H3.75A0.76 0.76 ,0,0,0,3,9.75v4.5a0.76 0.76 ,0,0,0,0.75 0.75 h16.5a0.76 0.76 ,0,0,0,0.75-0.75ZM19.5,13.5H4.5v-3h15Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 5.25 11.25 H 6.75 V 12.75 H 5.25 V 11.25 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M21,21.25v-4.5a0.76 0.76 ,0,0,0-0.75-0.75H3.75a0.76 0.76 ,0,0,0-0.75 0.75 v4.5a0.76 0.76 ,0,0,0,0.75 0.75 h16.5A0.76 0.76 ,0,0,0,21,21.25Zm-1.5-0.75H4.5v-3h15Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 5.25 18.25 H 6.75 V 19.75 H 5.25 V 18.25 Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.25,2H3.75C3.34,2,3,2.34,3,2.75v4.5C3,7.66,3.34,8,3.75,8h16.5C20.66,8,21,7.66,21,7.25v-4.5C21,2.34,20.66,2,20.25,2 z M19.5,6.5h-15v-3h15V6.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 5.25 4.25 H 6.75 V 5.75 H 5.25 V 4.25 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.25,9H3.75C3.34,9,3,9.34,3,9.75v4.5C3,14.66,3.34,15,3.75,15h16.5c0.41,0,0.75-0.34,0.75-0.75v-4.5 C21,9.34,20.66,9,20.25,9z M19.5,13.5h-15v-3h15V13.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 5.25 11.25 H 6.75 V 12.75 H 5.25 V 11.25 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.25,16H3.75C3.34,16,3,16.34,3,16.75v4.5C3,21.66,3.34,22,3.75,22h16.5c0.41,0,0.75-0.34,0.75-0.75v-4.5 C21,16.34,20.66,16,20.25,16z M19.5,20.5h-15v-3h15V20.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 5.25 18.25 H 6.75 V 19.75 H 5.25 V 18.25 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
index 76d3e5f..ca73792 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M5.69,16l5,5a0.77 0.77 ,0,0,0,0.53 0.22 0.75 0.75 ,0,0,0,0.29-0.06A0.74 0.74 ,0,0,0,12,20.5V3.5A0.75 0.75 ,0,0,0,10.72,3l-5,5H3.49A1.52,1.52,0,0,0,2,9.5v5A1.5,1.5,0,0,0,3.5,16ZM3.5,9.5H6a0.75 0.75 ,0,0,0,0.53-0.22l4-4V18.69l-4-4A0.75 0.75 ,0,0,0,6,14.5H3.5Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M13.52,20.64a0.77 0.77 ,0,0,0,0.73 0.56 0.63 0.63 ,0,0,0,0.19,0,9.48,9.48,0,0,0,0-18.34 0.75 0.75,0,0,0-0.92 0.53 0.76 0.76 ,0,0,0,0.54 0.92 ,8,8,0,0,1,0,15.44A0.76 0.76 ,0,0,0,13.52,20.64Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M13.85,15a0.76 0.76 ,0,0,0-0.24,1,0.78 0.78 ,0,0,0,0.64 0.35 0.83 0.83 ,0,0,0,0.4-0.11,5,5,0,0,0,1.6-6.88,5.2,5.2,0,0,0-1.6-1.6A0.75 0.75 ,0,1,0,13.85,9,3.33,3.33,0,0,1,15,10.16,3.47,3.47,0,0,1,13.85,15Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M5.69,16l5.03,5.03c0.14,0.14,0.34,0.22,0.53,0.22c0.1,0,0.19-0.02,0.29-0.06C11.82,21.08,12,20.8,12,20.5v-17 c0-0.3-0.18-0.58-0.46-0.69c-0.28-0.11-0.6-0.05-0.82,0.16L5.69,8H3.49C2.68,8.01,2.01,8.68,2,9.5v5C2,15.33,2.67,16,3.5,16H5.69z M3.5,9.5H6c0.2,0,0.39-0.08,0.53-0.22l3.97-3.97v13.38l-3.97-3.97C6.39,14.58,6.2,14.5,6,14.5H3.5V9.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.52,20.64c0.09,0.34,0.39,0.56,0.72,0.56c0.06,0,0.13-0.01,0.19-0.02c3.29-0.87,5.88-3.46,6.75-6.75 c1.34-5.06-1.69-10.26-6.75-11.59c-0.4-0.11-0.81,0.13-0.92,0.53c-0.11,0.4,0.13,0.81,0.53,0.92c4.26,1.13,6.8,5.5,5.68,9.76 c-0.73,2.77-2.91,4.95-5.68,5.68C13.66,19.83,13.42,20.24,13.52,20.64z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.85,14.96c-0.35,0.22-0.46,0.68-0.24,1.03c0.14,0.23,0.39,0.35,0.64,0.35c0.14,0,0.27-0.04,0.4-0.11 c1.13-0.7,1.92-1.81,2.22-3.1c0.3-1.3,0.08-2.64-0.62-3.77c-0.4-0.65-0.96-1.2-1.6-1.6C14.29,7.54,13.83,7.65,13.61,8 c-0.22,0.35-0.11,0.81,0.24,1.03c0.45,0.28,0.84,0.67,1.12,1.12c0.49,0.79,0.65,1.73,0.44,2.64C15.2,13.7,14.65,14.47,13.85,14.96z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml
index eadd300..419710d 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_wifi_tethering.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M15,16.57a0.75 0.75 ,0,0,0,1.06,0,5.75,5.75,0,1,0-8.14,0,0.79 0.79 ,0,0,0,0.53 0.22 A0.75 0.75 ,0,0,0,9,16.57a0.74 0.74 ,0,0,0,0-1.06,4.25,4.25,0,1,1,6,0A0.75 0.75 ,0,0,0,15,16.57Z" />
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M18.36,19.61a0.71 0.71 ,0,0,0,0.53-0.22A9.74,9.74,0,0,0,5.11,5.61a9.73,9.73,0,0,0,0,13.78 0.74 0.74,0,0,0,1.06,0,0.75 0.75 ,0,0,0,0-1.06A8.24,8.24,0,0,1,17.83,6.67a8.23,8.23,0,0,1,0,11.66 0.75 0.75,0,0,0,0,1.06A0.74 0.74 ,0,0,0,18.36,19.61Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15.01,16.57c0.29,0.29,0.77,0.29,1.06,0c1.09-1.09,1.68-2.53,1.68-4.07s-0.6-2.98-1.68-4.07c-2.24-2.24-5.89-2.24-8.13,0 c-1.09,1.09-1.68,2.53-1.68,4.07s0.6,2.98,1.68,4.07c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0.29-0.29,0.29-0.77,0-1.06c-0.8-0.8-1.24-1.87-1.24-3.01c0-1.13,0.44-2.2,1.24-3c1.66-1.66,4.35-1.66,6.01,0 c0.8,0.8,1.24,1.87,1.24,3.01c0,1.13-0.44,2.2-1.24,3C14.71,15.8,14.71,16.27,15.01,16.57z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.36,19.61c0.19,0,0.38-0.07,0.53-0.22c1.84-1.84,2.86-4.29,2.86-6.89s-1.01-5.05-2.86-6.89c-3.8-3.8-9.99-3.8-13.79,0 C3.26,7.45,2.25,9.9,2.25,12.5s1.01,5.05,2.86,6.89c0.29,0.29,0.77,0.29,1.06,0s0.29-0.77,0-1.06c-1.56-1.56-2.42-3.63-2.42-5.83 s0.86-4.28,2.42-5.83c3.22-3.22,8.45-3.22,11.67,0c1.56,1.56,2.42,3.63,2.42,5.83s-0.86,4.28-2.42,5.83 c-0.29,0.29-0.29,0.77,0,1.06C17.98,19.54,18.17,19.61,18.36,19.61z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm.xml
new file mode 100644
index 0000000..e9590bf
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm.xml
@@ -0,0 +1,23 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M13.93,16.02c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.3-0.77,0.01-1.06l-2.25-2.28V7.75 C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75V13c0,0.2,0.08,0.39,0.22,0.53L13.93,16.02z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.4,2.55c-0.25,0.33-0.18,0.8,0.15,1.05l4.02,3c0.13,0.1,0.29,0.15,0.45,0.15c0.23,0,0.45-0.1,0.6-0.3 c0.25-0.33,0.18-0.8-0.15-1.05l-4.02-3C17.12,2.15,16.65,2.22,16.4,2.55z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.98,6.75c0.16,0,0.31-0.05,0.45-0.15l4.02-3c0.33-0.25,0.4-0.72,0.15-1.05C7.35,2.22,6.88,2.15,6.55,2.4l-4.02,3 C2.2,5.65,2.13,6.12,2.38,6.45C2.52,6.65,2.75,6.75,2.98,6.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.08,13c0,4.96,4,9,8.92,9c0,0,0.01,0,0.01,0c2.38,0,4.61-0.93,6.3-2.63c1.68-1.7,2.61-3.95,2.61-6.35V13 c0-4.96-4-9-8.92-9S3.08,8.04,3.08,13z M12,5.5c4.09,0,7.42,3.36,7.42,7.5v0.02c0,2-0.78,3.88-2.18,5.3 c-1.4,1.41-3.26,2.19-5.23,2.19c0,0-0.01,0-0.01,0c-4.09,0-7.42-3.36-7.42-7.5S7.91,5.5,12,5.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm_dim.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm_dim.xml
new file mode 100644
index 0000000..e9590bf
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_alarm_dim.xml
@@ -0,0 +1,23 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M13.93,16.02c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.3-0.77,0.01-1.06l-2.25-2.28V7.75 C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75V13c0,0.2,0.08,0.39,0.22,0.53L13.93,16.02z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M16.4,2.55c-0.25,0.33-0.18,0.8,0.15,1.05l4.02,3c0.13,0.1,0.29,0.15,0.45,0.15c0.23,0,0.45-0.1,0.6-0.3 c0.25-0.33,0.18-0.8-0.15-1.05l-4.02-3C17.12,2.15,16.65,2.22,16.4,2.55z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.98,6.75c0.16,0,0.31-0.05,0.45-0.15l4.02-3c0.33-0.25,0.4-0.72,0.15-1.05C7.35,2.22,6.88,2.15,6.55,2.4l-4.02,3 C2.2,5.65,2.13,6.12,2.38,6.45C2.52,6.65,2.75,6.75,2.98,6.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.08,13c0,4.96,4,9,8.92,9c0,0,0.01,0,0.01,0c2.38,0,4.61-0.93,6.3-2.63c1.68-1.7,2.61-3.95,2.61-6.35V13 c0-4.96-4-9-8.92-9S3.08,8.04,3.08,13z M12,5.5c4.09,0,7.42,3.36,7.42,7.5v0.02c0,2-0.78,3.88-2.18,5.3 c-1.4,1.41-3.26,2.19-5.23,2.19c0,0-0.01,0-0.01,0c-4.09,0-7.42-3.36-7.42-7.5S7.91,5.5,12,5.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml
new file mode 100644
index 0000000..dcaba7c
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_bluetooth_connected.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M17.53,6.72l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C11.68,1.92,11.5,2.2,11.5,2.5v7.69L7.53,6.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L11.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l3.97-3.97 v7.69c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.2,0,0.39-0.08,0.53-0.22l4.75-4.75c0.29-0.29,0.29-0.77,0-1.06 L13.31,12l4.22-4.22C17.82,7.49,17.82,7.01,17.53,6.72z M15.94,16.75L13,19.69v-5.88L15.94,16.75z M13,10.19V4.31l2.94,2.94 L13,10.19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 5 11 C 5.55228474983 11 6 11.4477152502 6 12 C 6 12.5522847498 5.55228474983 13 5 13 C 4.44771525017 13 4 12.5522847498 4 12 C 4 11.4477152502 4.44771525017 11 5 11 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 19 11 C 19.5522847498 11 20 11.4477152502 20 12 C 20 12.5522847498 19.5522847498 13 19 13 C 18.4477152502 13 18 12.5522847498 18 12 C 18 11.4477152502 18.4477152502 11 19 11 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
index abfcfce..27a15c6 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
@@ -1,52 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M12,19.5h0A7.49,7.49,0,0,0,19.5,12h0A7.5,7.5,0,1,0,12,19.5ZM12,6a6,6,0,0,1,6,6h0a6,6,0,0,1-6,6h0A6,6,0,0,1,12,6Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M11.25 0.75 v1.5a0.75 0.75 ,0,0,0,1.5,0V0.75a0.75 0.75 ,0,0,0-1.5,0Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M4.58,3.51A0.76 0.76 ,0,0,0,3.51,4.58L4.57,5.64a0.79 0.79 ,0,0,0,1.07,0,0.77 0.77 ,0,0,0,0-1.07Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M3,12a0.76 0.76 ,0,0,0-0.75-0.75H0.75a0.75 0.75 ,0,0,0,0,1.5h1.5A0.76 0.76 ,0,0,0,3,12Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M3.51,20.49a0.76 0.76 ,0,0,0,1.07,0l1.06-1.06a0.76 0.76 ,0,1,0-1.07-1.07L3.51,19.42A0.77 0.77 ,0,0,0,3.51,20.49Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M11.25,21.75v1.5a0.75 0.75 ,0,0,0,1.5,0v-1.5a0.75 0.75 ,0,0,0-1.5,0Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M18.36,18.36a0.77 0.77 ,0,0,0,0,1.07l1.06,1.06a0.76 0.76 ,0,0,0,1.07,0,0.77 0.77 ,0,0,0,0-1.07l-1.06-1.06A0.77 0.77 ,0,0,0,18.36,18.36Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M23.25,11.25h-1.5a0.75 0.75 ,0,0,0,0,1.5h1.5a0.75 0.75 ,0,0,0,0-1.5Z" />
-    <path
-        android:fillColor="?android:attr/colorControlActivated"
-        android:pathData="M19.42,3.51,18.36,4.57a0.77 0.77 ,0,0,0,0,1.07 0.79 0.79,0,0,0,1.07,0l1.06-1.06a0.76 0.76 ,0,0,0-1.07-1.07Z" />
-</vector>
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="?android:attr/colorControlActivated" android:pathData="M22.46,11.25h-3.02c-0.15-1.51-0.75-2.88-1.66-4l2.17-2.17c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.18,2.18 c-1.11-0.91-2.49-1.51-3.99-1.66V1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v3.04c-1.5,0.15-2.88,0.75-3.99,1.65 L5.06,4.01C4.77,3.71,4.29,3.71,4,4.01S3.71,4.77,4,5.07l2.18,2.18c-0.91,1.11-1.51,2.48-1.66,3.98H1.48 c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h3.04c0.15,1.51,0.74,2.88,1.65,3.99L3.99,18.9c-0.29,0.29-0.29,0.77,0,1.06 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22l2.17-2.17c1.11,0.91,2.49,1.52,3.99,1.67v3.02c0,0.41,0.34,0.75,0.75,0.75 s0.75-0.34,0.75-0.75v-3.02c1.48-0.14,2.86-0.71,4.01-1.65l2.16,2.16c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0.29-0.29,0.29-0.77,0-1.06l-2.16-2.16c0.94-1.15,1.52-2.53,1.66-4.01h3.02c0.41,0,0.75-0.34,0.75-0.75S22.88,11.25,22.46,11.25z M12,18c-3.31,0-6-2.69-6-6s2.69-6,6-6s6,2.69,6,6S15.31,18,12,18z"/>
+  <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 6 C 15.313708499 6 18 8.68629150102 18 12 C 18 15.313708499 15.313708499 18 12 18 C 8.68629150102 18 6 15.313708499 6 12 C 6 8.68629150102 8.68629150102 6 12 6 Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml
new file mode 100644
index 0000000..ab73718
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M22,7c0-1.1-0.9-2-2-2h-3l-1.41-1.41C15.21,3.21,14.7,3,14.17,3H9.83C9.3,3,8.79,3.21,8.41,3.59L7,5H4C2.9,5,2,5.9,2,7v12 c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V7z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4c-0.28,0-0.5-0.22-0.5-0.5V7c0-0.28,0.22-0.5,0.5-0.5 h3.62l1.85-1.85C9.57,4.55,9.69,4.5,9.83,4.5h4.34c0.13,0,0.26,0.05,0.35,0.15l1.85,1.85H20c0.28,0,0.5,0.22,0.5,0.5V19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,9c-2.21,0-4,1.79-4,4c0,2.21,1.79,4,4,4c2.21,0,4-1.79,4-4C16,10.79,14.21,9,12,9z M12,15.5c-1.38,0-2.5-1.12-2.5-2.5 c0-1.38,1.12-2.5,2.5-2.5c1.38,0,2.5,1.12,2.5,2.5C14.5,14.38,13.38,15.5,12,15.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast.xml
new file mode 100644
index 0000000..b1107af
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast.xml
@@ -0,0 +1,23 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.75,14.25C2.34,14.25,2,14.59,2,15s0.34,0.75,0.75,0.75c1.93,0,3.5,1.57,3.5,3.5C6.25,19.66,6.59,20,7,20 s0.75-0.34,0.75-0.75C7.75,16.49,5.51,14.25,2.75,14.25z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.25,17.5h0.03C3.27,17.5,3.26,17.5,3.25,17.5C2.56,17.5,2,18.06,2,18.75C2,19.44,2.56,20,3.25,20s1.25-0.56,1.25-1.25 S3.94,17.5,3.25,17.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.5,4h-17C3.49,4,3.48,4,3.47,4C2.64,4.02,1.98,4.7,2,5.53v3.18c0,0.41,0.34,0.75,0.75,0.75S3.5,9.12,3.5,8.71 c0-1.96,0-3.21,0-3.21l17,0.03V18.5h-7.35c-0.41,0-0.75,0.34-0.75,0.75S12.74,20,13.15,20h7.35c0.01,0,0.02,0,0.03,0 c0.83-0.02,1.49-0.7,1.47-1.53V5.53c0-0.01,0-0.02,0-0.03C22,4.67,21.33,4,20.5,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.75,11C2.34,11,2,11.34,2,11.75s0.34,0.75,0.75,0.75c3.73,0,6.75,3.02,6.75,6.75c0,0.41,0.34,0.75,0.75,0.75 S11,19.66,11,19.25C11,14.69,7.31,11,2.75,11z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml
new file mode 100644
index 0000000..548a65a
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml
@@ -0,0 +1,24 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20.5,4h-17C3.49,4,3.48,4,3.47,4C2.64,4.02,1.98,4.7,2,5.53v3.18c0,0.41,0.34,0.75,0.75,0.75S3.5,9.12,3.5,8.71 c0-1.96,0-3.21,0-3.21l17,0.03V18.5h-7.35c-0.41,0-0.75,0.34-0.75,0.75S12.74,20,13.15,20h7.35c0.01,0,0.02,0,0.03,0 c0.83-0.02,1.49-0.7,1.47-1.53V5.53c0-0.01,0-0.02,0-0.03C22,4.67,21.33,4,20.5,4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.25,17.5h0.03C3.27,17.5,3.26,17.5,3.25,17.5C2.56,17.5,2,18.06,2,18.75C2,19.44,2.56,20,3.25,20s1.25-0.56,1.25-1.25 S3.94,17.5,3.25,17.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.75,11C2.34,11,2,11.34,2,11.75s0.34,0.75,0.75,0.75c3.73,0,6.75,3.02,6.75,6.75c0,0.41,0.34,0.75,0.75,0.75 S11,19.66,11,19.25C11,14.69,7.31,11,2.75,11z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.75,14.25C2.34,14.25,2,14.59,2,15s0.34,0.75,0.75,0.75c1.93,0,3.5,1.57,3.5,3.5C6.25,19.66,6.59,20,7,20 s0.75-0.34,0.75-0.75C7.75,16.49,5.51,14.25,2.75,14.25z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.25,15.5c-0.41,0-0.75,0.34-0.75,0.75S12.84,17,13.25,17h5c0.41,0,0.75-0.34,0.75-0.75v-8.5C19,7.34,18.66,7,18.25,7 H5.75C5.34,7,5,7.34,5,7.75v1C5,9.16,5.34,9.5,5.75,9.5S6.5,9.16,6.5,8.75V8.5h11v7H13.25z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_close_white.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_close_white.xml
new file mode 100644
index 0000000..2243cab
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_close_white.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M18.78,5.22c-0.29-0.29-0.77-0.29-1.06,0L12,10.94L6.28,5.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12 l-5.72,5.72c-0.29,0.29-0.29,0.77,0,1.06C5.37,18.93,5.56,19,5.75,19s0.38-0.07,0.53-0.22L12,13.06l5.72,5.72 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l5.72-5.72 C19.07,5.99,19.07,5.51,18.78,5.22z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml
new file mode 100644
index 0000000..bbb4df0
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp " android:viewportHeight="24" android:viewportWidth="24" android:width="18dp " xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8,12a0.76 0.76 ,0,0,0,0.75 0.75 h2.5v2.5a0.75 0.75 ,0,0,0,1.5,0v-2.5h2.5a0.75 0.75 ,0,0,0,0-1.5h-2.5V8.75a0.75 0.75 ,0,0,0-1.5,0v2.5H8.75A0.76 0.76 ,0,0,0,8,12Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml
index 1158b27..2921dd8 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml
@@ -1,34 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22,12a10,10,0,0,0-9-9.95v3A7,7,0,0,1,19,12a7.12,7.12,0,0,1-0.48,2.54h0l2.6,1.53A9.88,9.88,0,0,0,22,12Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.09,13.39a10,10,0,0,0,18,4.52l-2.6-1.53h0A7,7,0,1,1,11,5.08v-3A10,10,0,0,0,2.09,13.39Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M11.25,8v3.25H8a0.75 0.75 ,0,0,0,0,1.5h3.25V16a0.75 0.75 ,0,0,0,1.5,0V12.75H16a0.75 0.75 ,0,0,0,0-1.5H12.75V8a0.75 0.75 ,0,0,0-1.5,0Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_dnd.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_dnd.xml
deleted file mode 100644
index a9a32ee..0000000
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_dnd.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M7.25,12.75h9.5a0.75 0.75 ,0,0,0,0-1.5H7.25a0.75 0.75 ,0,0,0,0,1.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,22h0A10,10,0,0,0,22,12v0A10,10,0,1,0,12,22ZM12,3.5A8.51,8.51,0,0,1,20.5,12h0.75l-0.75,0A8.49,8.49,0,0,1,12,20.5h0a8.5,8.5,0,0,1,0-17Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_drag_handle.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_drag_handle.xml
index 915597e..31c1c4e 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_drag_handle.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_drag_handle.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M4,10.5H20A0.75 0.75 ,0,0,0,20,9H4a0.75 0.75 ,0,0,0,0,1.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M4,15H20a0.75 0.75 ,0,0,0,0-1.5H4A0.75 0.75 ,0,0,0,4,15Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M5.75,10.5h12.5c0.41,0,0.75-0.34,0.75-0.75S18.66,9,18.25,9H5.75C5.34,9,5,9.34,5,9.75S5.34,10.5,5.75,10.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.25,13.5H5.75C5.34,13.5,5,13.84,5,14.25S5.34,15,5.75,15h12.5c0.41,0,0.75-0.34,0.75-0.75S18.66,13.5,18.25,13.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset.xml
index 264e212..409fac3 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset.xml
@@ -1,28 +1,20 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.5,18V11.5C21.5,5.82,17.68,2,12,2S2.5,5.82,2.5,11.5V18a3,3,0,0,0,3,3H7a1.5,1.5,0,0,0,1.5-1.5V14A1.5,1.5,0,0,0,7,12.5H4v-1c0-4.86,3.14-8,8-8s8,3.14,8,8v1H17A1.5,1.5,0,0,0,15.5,14v5.5A1.5,1.5,0,0,0,17,21h1.5A3,3,0,0,0,21.5,18ZM7,19.5H5.5A1.5,1.5,0,0,1,4,18V14H7ZM20,18a1.5,1.5,0,0,1-1.5,1.5H17V14h3Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M14.75,2.01h-5.5c-3.72,0-6.75,3.03-6.75,6.75v3.74v1V18c0,1.66,1.34,3,3,3H7c0.83,0,1.5-0.67,1.5-1.5V14 c0-0.83-0.67-1.5-1.5-1.5H4V8.76c0-2.9,2.36-5.25,5.25-5.25h5.5c2.89,0,5.25,2.35,5.25,5.25v3.74h-3c-0.83,0-1.5,0.67-1.5,1.5v5.5 c0,0.83,0.67,1.5,1.5,1.5h1.5c1.66,0,3-1.34,3-3v-4.5v-1V8.76C21.5,5.04,18.47,2.01,14.75,2.01z M7,19.5H5.5 C4.67,19.5,4,18.83,4,18v-4h3V19.5z M20,18c0,0.83-0.67,1.5-1.5,1.5H17V14h3V18z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset_mic.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset_mic.xml
new file mode 100644
index 0000000..74318ae
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_headset_mic.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M14.75,1.01h-5.5c-3.72,0-6.75,3.03-6.75,6.75V17c0,1.66,1.34,3,3,3H7c0.83,0,1.5-0.67,1.5-1.5V13c0-0.83-0.67-1.5-1.5-1.5 H4V7.76c0-2.89,2.35-5.25,5.25-5.25h5.5c2.9,0,5.25,2.36,5.25,5.25v3.74h-3c-0.83,0-1.5,0.67-1.5,1.5v5.5c0,0.83,0.67,1.5,1.5,1.5 h1.5c0.53,0,1.03-0.15,1.46-0.4c-0.17,1.07-1.09,1.9-2.21,1.9h-5c-0.41,0-0.75,0.34-0.75,0.75S12.34,23,12.75,23h5 c2.07,0,3.75-1.68,3.75-3.75V7.76C21.5,4.04,18.47,1.01,14.75,1.01z M7,18.5H5.5C4.67,18.5,4,17.83,4,17v-4h3V18.5z M18.5,18.5H17 V13h3v4C20,17.83,19.33,18.5,18.5,18.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_hotspot.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_hotspot.xml
index ae78a14..7aca4d7 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_hotspot.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_hotspot.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M15,16.57a0.75 0.75 ,0,0,0,1.06,0,5.75,5.75,0,1,0-8.14,0,0.79 0.79 ,0,0,0,0.53 0.22 A0.75 0.75 ,0,0,0,9,16.57a0.74 0.74 ,0,0,0,0-1.06,4.25,4.25,0,1,1,6,0A0.75 0.75 ,0,0,0,15,16.57Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.36,19.61a0.71 0.71 ,0,0,0,0.53-0.22A9.74,9.74,0,0,0,5.11,5.61a9.73,9.73,0,0,0,0,13.78 0.74 0.74,0,0,0,1.06,0,0.75 0.75 ,0,0,0,0-1.06A8.24,8.24,0,0,1,17.83,6.67a8.23,8.23,0,0,1,0,11.66 0.75 0.75,0,0,0,0,1.06A0.74 0.74 ,0,0,0,18.36,19.61Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 12 11 C 12.8284271247 11 13.5 11.6715728753 13.5 12.5 C 13.5 13.3284271247 12.8284271247 14 12 14 C 11.1715728753 14 10.5 13.3284271247 10.5 12.5 C 10.5 11.6715728753 11.1715728753 11 12 11 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15.01,16.57c0.29,0.29,0.77,0.29,1.06,0c1.09-1.09,1.68-2.53,1.68-4.07s-0.6-2.98-1.68-4.07c-2.24-2.24-5.89-2.24-8.13,0 c-1.09,1.09-1.68,2.53-1.68,4.07s0.6,2.98,1.68,4.07c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 c0.29-0.29,0.29-0.77,0-1.06c-0.8-0.8-1.24-1.87-1.24-3.01c0-1.13,0.44-2.2,1.24-3c1.66-1.66,4.35-1.66,6.01,0 c0.8,0.8,1.24,1.87,1.24,3.01c0,1.13-0.44,2.2-1.24,3C14.71,15.8,14.71,16.27,15.01,16.57z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.36,19.61c0.19,0,0.38-0.07,0.53-0.22c1.84-1.84,2.86-4.29,2.86-6.89s-1.01-5.05-2.86-6.89c-3.8-3.8-9.99-3.8-13.79,0 C3.26,7.45,2.25,9.9,2.25,12.5s1.01,5.05,2.86,6.89c0.29,0.29,0.77,0.29,1.06,0s0.29-0.77,0-1.06c-1.56-1.56-2.42-3.63-2.42-5.83 s0.86-4.28,2.42-5.83c3.22-3.22,8.45-3.22,11.67,0c1.56,1.56,2.42,3.63,2.42,5.83s-0.86,4.28-2.42,5.83 c-0.29,0.29-0.29,0.77,0,1.06C17.98,19.54,18.17,19.61,18.36,19.61z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info.xml
index 642ac42..00a9523 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19.07,4.93A10,10,0,1,0,22,12,10,10,0,0,0,19.07,4.93ZM18,18a8.5,8.5,0,1,1,2.5-6A8.53,8.53,0,0,1,18,18Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,10a0.76 0.76 ,0,0,0-0.75 0.75 v5.5a0.75 0.75 ,0,0,0,1.5,0v-5.5A0.76 0.76 ,0,0,0,12,10Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info_outline.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info_outline.xml
new file mode 100644
index 0000000..00a9523
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_info_outline.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_invert_colors.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_invert_colors.xml
new file mode 100644
index 0000000..347c2bd
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_invert_colors.xml
@@ -0,0 +1,20 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12.62,2.23c-0.18-0.15-0.4-0.22-0.62-0.22c-0.22,0-0.45,0.08-0.63,0.22C9.48,3.75,4,8.5,4,13.99c0,4.51,3.5,8,8,8 s8-3.71,8-7.99C20,8.5,14.5,3.73,12.62,2.23z M5.5,13.99c0-4.4,4.32-8.53,6.5-10.34v16.83C8.36,20.49,5.5,17.64,5.5,13.99z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_location.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_location.xml
new file mode 100644
index 0000000..b4ea6b4
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_location.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,7c-1.66,0-3,1.34-3,3s1.34,3,3,3s3-1.34,3-3S13.66,7,12,7z M12,11.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S12.83,11.5,12,11.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,2.01c-4.5,0-8,3.49-8,8c0,5.49,5.48,10.24,7.37,11.76c0.19,0.15,0.41,0.22,0.63,0.22c0.22,0,0.44-0.07,0.62-0.22 C14.5,20.26,20,15.5,20,10C20,5.72,16.5,2.01,12,2.01z M12,20.34c-2.18-1.8-6.5-5.94-6.5-10.34c0-3.64,2.86-6.5,6.5-6.5 c3.58,0,6.5,2.91,6.5,6.49C18.5,14.4,14.19,18.53,12,20.34z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml
index 7897fa3a..6b91dcd 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_lockscreen_ime.xml
@@ -1,55 +1,29 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,21H21a2,2,0,0,0,2-2V6a2,2,0,0,0-2-2H3A2,2,0,0,0,1,6V19A2,2,0,0,0,3,21ZM2.5,6A0.51 0.51 ,0,0,1,3,5.5H21a0.51 0.51 ,0,0,1,0.5 0.5 V19a0.51 0.51 ,0,0,1-0.5 0.5 H3a0.51 0.51 ,0,0,1-0.5-0.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9.5 8 L 10.5 8 Q 11 8 11 8.5 L 11 9.5 Q 11 10 10.5 10 L 9.5 10 Q 9 10 9 9.5 L 9 8.5 Q 9 8 9.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5.5 8 L 6.5 8 Q 7 8 7 8.5 L 7 9.5 Q 7 10 6.5 10 L 5.5 10 Q 5 10 5 9.5 L 5 8.5 Q 5 8 5.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M8.75,17.5h6.5a0.75 0.75 ,0,0,0,0-1.5H8.75a0.75 0.75 ,0,0,0,0,1.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13.5 8 L 14.5 8 Q 15 8 15 8.5 L 15 9.5 Q 15 10 14.5 10 L 13.5 10 Q 13 10 13 9.5 L 13 8.5 Q 13 8 13.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9.5 12 L 10.5 12 Q 11 12 11 12.5 L 11 13.5 Q 11 14 10.5 14 L 9.5 14 Q 9 14 9 13.5 L 9 12.5 Q 9 12 9.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 5.5 12 L 6.5 12 Q 7 12 7 12.5 L 7 13.5 Q 7 14 6.5 14 L 5.5 14 Q 5 14 5 13.5 L 5 12.5 Q 5 12 5.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13.5 12 L 14.5 12 Q 15 12 15 12.5 L 15 13.5 Q 15 14 14.5 14 L 13.5 14 Q 13 14 13 13.5 L 13 12.5 Q 13 12 13.5 12 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17.5 8 L 18.5 8 Q 19 8 19 8.5 L 19 9.5 Q 19 10 18.5 10 L 17.5 10 Q 17 10 17 9.5 L 17 8.5 Q 17 8 17.5 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 17.5 12 L 18.5 12 Q 19 12 19 12.5 L 19 13.5 Q 19 14 18.5 14 L 17.5 14 Q 17 14 17 13.5 L 17 12.5 Q 17 12 17.5 12 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M21,4H3C1.9,4,1,4.9,1,6v13c0,1.1,0.9,2,2,2h18c1.1,0,2-0.9,2-2V6C23,4.9,22.1,4,21,4z M21.5,19c0,0.27-0.23,0.5-0.5,0.5 H3c-0.27,0-0.5-0.23-0.5-0.5V6c0-0.27,0.23-0.5,0.5-0.5h18c0.27,0,0.5,0.23,0.5,0.5V19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C11,8.22,10.78,8,10.5,8h-1C9.22,8,9,8.22,9,8.5v1C9,9.78,9.22,10,9.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.5,8h-1C5.22,8,5,8.22,5,8.5v1C5,9.78,5.22,10,5.5,10h1C6.78,10,7,9.78,7,9.5v-1C7,8.22,6.78,8,6.5,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M15.25,16h-6.5C8.34,16,8,16.34,8,16.75c0,0.41,0.34,0.75,0.75,0.75h6.5c0.41,0,0.75-0.34,0.75-0.75 C16,16.34,15.66,16,15.25,16z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,10h1c0.28,0,0.5-0.22,0.5-0.5v-1C15,8.22,14.78,8,14.5,8h-1C13.22,8,13,8.22,13,8.5v1C13,9.78,13.22,10,13.5,10z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1C9.22,12,9,12.22,9,12.5v1C9,13.78,9.22,14,9.5,14z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M6.5,12h-1C5.22,12,5,12.22,5,12.5v1C5,13.78,5.22,14,5.5,14h1C6.78,14,7,13.78,7,13.5v-1C7,12.22,6.78,12,6.5,12z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.5,14h1c0.28,0,0.5-0.22,0.5-0.5v-1c0-0.28-0.22-0.5-0.5-0.5h-1c-0.28,0-0.5,0.22-0.5,0.5v1C13,13.78,13.22,14,13.5,14 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.5,8h-1C17.22,8,17,8.22,17,8.5v1c0,0.28,0.22,0.5,0.5,0.5h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,8.22,18.78,8,18.5,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.5,12h-1c-0.28,0-0.5,0.22-0.5,0.5v1c0,0.28,0.22,0.5,0.5,0.5h1c0.28,0,0.5-0.22,0.5-0.5v-1C19,12.22,18.78,12,18.5,12 z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_alert.xml
index 74311e7..bfd820f 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_alert.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_alert.xml
@@ -1,37 +1,23 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,20H10a2,2,0,0,0,4,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,2.5a1.25,1.25,0,0,0-1.25,1.25v0.78A6,6,0,0,0,6,10.4V17H4.75a0.75 0.75 ,0,0,0,0,1.5h14.5a0.75 0.75 ,0,0,0,0-1.5H18V10.4a6,6,0,0,0-4.75-5.87V3.75A1.25,1.25,0,0,0,12,2.5Zm4.5,7.9V17h-9V10.4a4.5,4.5,0,1,1,9,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M5.85,3A9.49,9.49,0,0,0,2.5,10.25a0.75 0.75 ,0,0,0,1.5,0,8,8,0,0,1,2.82-6.1A0.75 0.75 ,0,1,0,5.85,3Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.15,3a0.75 0.75 ,0,1,0-1,1.14A8,8,0,0,1,20,10.25a0.75 0.75 ,0,0,0,1.5,0A9.49,9.49,0,0,0,18.15,3Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,2.5c-0.69,0-1.25,0.56-1.25,1.25v0.77C8.04,5.11,6,7.51,6,10.4V17H4.75C4.34,17,4,17.34,4,17.75s0.34,0.75,0.75,0.75 h14.5c0.41,0,0.75-0.34,0.75-0.75S19.66,17,19.25,17H18v-6.6c0-2.88-2.04-5.29-4.75-5.87V3.75C13.25,3.06,12.69,2.5,12,2.5z M16.5,10.4V17h-9v-6.6c0-2.48,2.02-4.5,4.5-4.5S16.5,7.91,16.5,10.4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.15,3.01c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06C18.97,5.68,20,7.9,20,10.25 c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75C21.5,7.46,20.28,4.82,18.15,3.01z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_silence.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_silence.xml
index a93c45b..b70f9ed 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_silence.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_notifications_silence.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14,20H10a2,2,0,0,0,4,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,5.9a4.5,4.5,0,0,1,4.5,4.5v3.92l1.5,1.5V10.4a6,6,0,0,0-4.75-5.87V3.75a1.25,1.25,0,0,0-2.5,0v0.78A5.92,5.92,0,0,0,8.06,5.88L9.14,7A4.45,4.45,0,0,1,12,5.9Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,22A0.75 0.75 ,0,0,0,21,21L3,3A0.75 0.75 ,0,0,0,2,3H2A0.75 0.75 ,0,0,0,2,4L6.35,8.41a6,6,0,0,0-0.35,2V17H4.75a0.75 0.75 ,0,0,0,0,1.5H16.44L20,22A0.75 0.75 ,0,0,0,21,22ZM7.5,17V10.4a3.84,3.84,0,0,1,0.08-0.76L14.94,17Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,5.9c2.48,0,4.5,2.02,4.5,4.5v3.92l1.5,1.5V10.4c0-2.88-2.04-5.29-4.75-5.87V3.75c0-0.69-0.56-1.25-1.25-1.25 s-1.25,0.56-1.25,1.25v0.77C9.73,4.74,8.82,5.22,8.06,5.88l1.08,1.08C9.92,6.3,10.91,5.9,12,5.9z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.03,22.03c0.29-0.29,0.29-0.77,0-1.06l-18-18c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06 l4.38,4.37C6.13,9.03,6,9.7,6,10.4V17H4.75C4.34,17,4,17.34,4,17.75s0.34,0.75,0.75,0.75h11.69l3.53,3.53 c0.15,0.15,0.34,0.22,0.53,0.22S20.88,22.18,21.03,22.03C21.03,22.03,21.03,22.03,21.03,22.03z M7.5,17v-6.6 c0-0.26,0.03-0.51,0.08-0.76L14.94,17H7.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_low.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_low.xml
new file mode 100644
index 0000000..c6c713f
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_low.xml
@@ -0,0 +1,22 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,14.5c0.41,0,0.75-0.34,0.75-0.75v-5C12.75,8.34,12.41,8,12,8s-0.75,0.34-0.75,0.75v5C11.25,14.16,11.59,14.5,12,14.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 12.01 16 C 12.5622847498 16 13.01 16.4477152502 13.01 17 C 13.01 17.5522847498 12.5622847498 18 12.01 18 C 11.4577152502 18 11.01 17.5522847498 11.01 17 C 11.01 16.4477152502 11.4577152502 16 12.01 16 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17,4h-3V3.49c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1 V5C18,4.45,17.55,4,17,4z M16.5,20.5h-9v-15h9V20.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_saver.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_saver.xml
new file mode 100644
index 0000000..e2669d9
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_power_saver.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M9.74,13.75h1.5v1.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.5h1.5c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.5v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.5h-1.5c-0.41,0-0.75,0.34-0.75,0.75 S9.33,13.75,9.74,13.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17,4h-3V3.49c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1 V5C18,4.45,17.55,4,17,4z M16.5,20.5h-9v-15h9V20.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml
deleted file mode 100644
index fe7ecfd..0000000
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_auto_rotate.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3,6.81a0.75 0.75 ,0,0,0-0.75 0.75 v2.83a0.74 0.74 ,0,0,0,0.75 0.75 H5.8a0.75 0.75 ,0,1,0,0-1.5h-1l5.6-5.59,7.07,7.06a0.75 0.75 ,0,0,0,1.06-1.06l-7.6-7.6a0.75 0.75 ,0,0,0-1.06,0L3.72,8.62V7.56A0.76 0.76 ,0,0,0,3,6.81Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,12.85H18.21a0.75 0.75 ,0,0,0,0,1.5h1L13.59,20,6.52,12.89a0.75 0.75 ,0,0,0-1.06,0,0.74 0.74 ,0,0,0,0,1.06l7.6,7.6a0.75 0.75 ,0,0,0,1.06,0l6.17-6.17v1.06a0.75 0.75 ,0,1,0,1.5,0V13.6A0.76 0.76 ,0,0,0,21,12.85Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
index 70282d4..739c110 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M4.47,17.78a0.75 0.75 ,0,0,0,1.06,0l4-4V21.5a0.74 0.74 ,0,0,0,0.46 0.69 0.75 0.75 ,0,0,0,0.29 0.06 0.77 0.77 ,0,0,0,0.53-0.22l4.75-4.75a0.75 0.75 ,0,0,0,0-1.06L11.31,12l4.22-4.22a0.75 0.75 ,0,0,0,0-1.06L10.78,2A0.75 0.75 ,0,0,0,10,1.81a0.74 0.74 ,0,0,0-0.46 0.69 v7.69l-4-4A0.75 0.75 ,0,0,0,4.47,7.28L9.19,12,4.47,16.72A0.75 0.75 ,0,0,0,4.47,17.78ZM11,4.31l2.94,2.94L11,10.19Zm0,9.5,2.94,2.94L11,19.69Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 16 11 C 16.5522847498 11 17 11.4477152502 17 12 C 17 12.5522847498 16.5522847498 13 16 13 C 15.4477152502 13 15 12.5522847498 15 12 C 15 11.4477152502 15.4477152502 11 16 11 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M18.55,16.37a0.74 0.74 ,0,0,0,0.45 0.15 0.77 0.77 ,0,0,0,0.6-0.3,7,7,0,0,0,0-8.42 0.76 0.76,0,0,0-1.05-0.15 0.75 0.75,0,0,0-0.15,1,5.53,5.53,0,0,1,0,6.62A0.75 0.75 ,0,0,0,18.55,16.37Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.31,12l4.22-4.22c0.29-0.29,0.29-0.77,0-1.06l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C9.68,1.92,9.5,2.2,9.5,2.5 v7.69L5.53,6.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L9.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0 l3.97-3.97v7.69c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.19,0,0.39-0.08,0.53-0.22l4.75-4.75 c0.29-0.29,0.29-0.77,0-1.06L11.31,12z M11,4.31l2.94,2.94L11,10.19V4.31z M11,19.69v-5.88l2.94,2.94L11,19.69z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 16 11 C 16.5522847498 11 17 11.4477152502 17 12 C 17 12.5522847498 16.5522847498 13 16 13 C 15.4477152502 13 15 12.5522847498 15 12 C 15 11.4477152502 15.4477152502 11 16 11 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.6,7.8c-0.25-0.33-0.72-0.4-1.05-0.15c-0.33,0.25-0.4,0.72-0.15,1.05c0.72,0.96,1.1,2.1,1.1,3.31 c0,1.2-0.38,2.35-1.1,3.31c-0.25,0.33-0.18,0.8,0.15,1.05c0.13,0.1,0.29,0.15,0.45,0.15c0.23,0,0.45-0.1,0.6-0.3 C20.52,15,21,13.54,21,12.01S20.52,9.02,19.6,7.8z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml
index dfef14b..f2e6050 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_on.xml
@@ -21,8 +21,6 @@
     android:viewportHeight="24">
 
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M17.53,6.72,12.78,2a0.75 0.75 ,0,0,0-1.28 0.53 v7.69l-4-4A0.75 0.75 ,0,0,0,6.47,7.28L11.19,12,6.47,16.72a0.75 0.75 ,0,0,0,1.06,1.06l4-4V21.5a0.74 0.74 ,0,0,0,0.46 0.69 0.74 0.74 ,0,0,0,0.82-0.16l4.75-4.75a0.75 0.75 ,0,0,0,0-1.06L13.31,12l4.22-4.22A0.75 0.75 ,0,0,0,17.53,6.72Zm-1.59,10L13,19.69V13.81ZM13,10.19V4.31l2.94,2.94Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M17.53,6.72l-4.75-4.75c-0.21-0.21-0.54-0.28-0.82-0.16C11.68,1.92,11.5,2.2,11.5,2.5v7.69L7.53,6.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L11.19,12l-4.72,4.72c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l3.97-3.97v7.69 c0,0.3,0.18,0.58,0.46,0.69c0.09,0.04,0.19,0.06,0.29,0.06c0.2,0,0.39-0.08,0.53-0.22l4.75-4.75c0.29-0.29,0.29-0.77,0-1.06 L13.31,12l4.22-4.22C17.82,7.49,17.82,7.01,17.53,6.72z M15.94,16.75L13,19.69v-5.88L15.94,16.75z M13,10.19V4.31l2.94,2.94 L13,10.19z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml
deleted file mode 100644
index 9bf1274..0000000
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_brightness_auto_on.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.75,2.25V0.75a0.75 0.75 ,0,0,0-1.5,0v1.5a0.75 0.75 ,0,0,0,1.5,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M4.57,5.64a0.79 0.79 ,0,0,0,1.07,0,0.77 0.77 ,0,0,0,0-1.07L4.58,3.51A0.76 0.76 ,0,0,0,3.51,4.58Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M0.75,12.75h1.5a0.75 0.75 ,0,0,0,0-1.5H0.75a0.75 0.75 ,0,0,0,0,1.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.51,20.49a0.76 0.76 ,0,0,0,1.07,0l1.06-1.06a0.76 0.76 ,0,1,0-1.07-1.07L3.51,19.42A0.77 0.77 ,0,0,0,3.51,20.49Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M11.25,21.75v1.5a0.75 0.75 ,0,0,0,1.5,0v-1.5a0.75 0.75 ,0,0,0-1.5,0Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M20,20.71a0.79 0.79 ,0,0,0,0.53-0.22 0.77 0.77,0,0,0,0-1.07l-1.06-1.06a0.76 0.76 ,0,0,0-1.07,1.07l1.06,1.06A0.79 0.79 ,0,0,0,20,20.71Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M23.25,11.25h-1.5a0.75 0.75 ,0,0,0,0,1.5h1.5a0.75 0.75 ,0,0,0,0-1.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19.42,3.51,18.36,4.57a0.77 0.77 ,0,0,0,0,1.07 0.79 0.79,0,0,0,1.07,0l1.06-1.06a0.76 0.76 ,0,0,0-1.07-1.07Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M14.85,17H17L13.11,7H10.87L7,17H9.15L10,14.61h4Zm-4.22-4.12,1.31-3.71h0.11l1.29,3.71Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cancel.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cancel.xml
index cc819a0..9ee53c2 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cancel.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cancel.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm0,18.5A8.5,8.5,0,1,1,20.5,12,8.51,8.51,0,0,1,12,20.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.6,7.4a0.75 0.75 ,0,0,0-1.06,0L12,10.94,8.46,7.4A0.75 0.75 ,0,0,0,7.4,8.46L10.94,12,7.4,15.54a0.75 0.75 ,0,0,0,0,1.06 0.79 0.79,0,0,0,0.53 0.22 0.75 0.75 ,0,0,0,0.53-0.22L12,13.06l3.54,3.54a0.75 0.75 ,0,0,0,0.53 0.22 0.79 0.79 ,0,0,0,0.53-0.22 0.75 0.75,0,0,0,0-1.06L13.06,12,16.6,8.46A0.75 0.75 ,0,0,0,16.6,7.4Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10c5.52,0,10-4.48,10-10S17.52,2,12,2z M12,20.5c-4.69,0-8.5-3.81-8.5-8.5 c0-4.69,3.81-8.5,8.5-8.5c4.69,0,8.5,3.81,8.5,8.5C20.5,16.69,16.69,20.5,12,20.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M13.01,11.95l2.76-2.66c0.3-0.29,0.31-0.76,0.02-1.06c-0.29-0.3-0.76-0.31-1.06-0.02l-2.78,2.68L9.28,8.22 c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l2.65,2.65l-2.89,2.78c-0.3,0.29-0.31,0.76-0.02,1.06C8.11,15.92,8.3,16,8.5,16 c0.19,0,0.37-0.07,0.52-0.21l2.91-2.8l2.79,2.79c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06 L13.01,11.95z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cast_on.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cast_on.xml
deleted file mode 100644
index 34ca21a..0000000
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_cast_on.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M22,18V5.5A1.5,1.5,0,0,0,20.5,4h-17A1.5,1.5,0,0,0,2,5.53V8.46a0.75 0.75 ,0,0,0,1.5,0v-3l17,0V18H13.15a0.75 0.75 ,0,1,0,0,1.5h7.38A1.5,1.5,0,0,0,22,18Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.25,19.5a1.25,1.25,0,0,0,0-2.5h0a1.25,1.25,0,0,0,0,2.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2,11.25a0.76 0.76 ,0,0,0,0.75 0.75 A6.75,6.75,0,0,1,9.5,18.75a0.75 0.75 ,0,0,0,1.5,0A8.25,8.25,0,0,0,2.75,10.5 0.76 0.76,0,0,0,2,11.25Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.75,15.25a3.5,3.5,0,0,1,3.5,3.5 0.75 0.75,0,0,0,1.5,0,5,5,0,0,0-5-5,0.75 0.75 ,0,0,0,0,1.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M13.25,15a0.75 0.75 ,0,0,0,0,1.5h5a0.76 0.76 ,0,0,0,0.75-0.75v-8A0.76 0.76 ,0,0,0,18.25,7H5.75A0.76 0.76 ,0,0,0,5,7.75V8.5a0.75 0.75 ,0,0,0,1.5,0h11V15Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_no_sim.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_no_sim.xml
index 7020463..f39c2c0 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_no_sim.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_no_sim.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M10.62,4.5H17a0.5 0.5 ,0,0,1,0.5 0.5 V15.32l1.5,1.5V5a2,2,0,0,0-2-2H10L7.59,5.41,8.65,6.47Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,21,3,3A0.75 0.75 ,0,0,0,2,3H2A0.75 0.75 ,0,0,0,2,4l3.5,3.5L5,8V19a2,2,0,0,0,2,2H17a2,2,0,0,0,1.38-0.56L20,22A0.75 0.75 ,0,0,0,21,22h0A0.75 0.75 ,0,0,0,21,21ZM17,19.5H7a0.5 0.5 ,0,0,1-0.5-0.5V8.62l0,0L17.32,19.38A0.53 0.53 ,0,0,1,17,19.5Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M10.62,4.5H17c0.28,0,0.5,0.22,0.5,0.5v10.32l1.5,1.5V5c0-1.1-0.9-2-2-2h-7L7.59,5.41l1.06,1.06L10.62,4.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.03,20.97l-18-18c-0.29-0.29-0.77-0.29-1.06,0c0,0,0,0,0,0c-0.29,0.29-0.29,0.77,0,1.06l3.5,3.5L5,8v11c0,1.1,0.9,2,2,2 h10c0.54,0,1.02-0.21,1.38-0.56l1.59,1.59c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0,0,0,0,0,0 C21.32,21.74,21.32,21.26,21.03,20.97z M17,19.5H7c-0.28,0-0.5-0.22-0.5-0.5V8.62l0.03-0.03l10.79,10.79 C17.23,19.45,17.12,19.5,17,19.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_vpn.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_vpn.xml
deleted file mode 100644
index 65c56f8..0000000
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_vpn.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21,9.5H11.37a5.25,5.25,0,1,0,0,5H14.5v1A1.5,1.5,0,0,0,16,17h2.5A1.5,1.5,0,0,0,20,15.5v-1h1A1.5,1.5,0,0,0,22.5,13V11A1.5,1.5,0,0,0,21,9.5ZM21,13H18.5v2.5H16V13H10.4l-0.19 0.46 A3.75,3.75,0,1,1,6.09,8.31a3.57,3.57,0,0,1,0.65-0.06,3.76,3.76,0,0,1,3.47,2.29l0.19 0.46 H21Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M6.75,9.75A2.25,2.25,0,1,0,9,12,2.25,2.25,0,0,0,6.75,9.75Zm0,3A0.75 0.75 ,0,1,1,7.5,12,0.76 0.76 ,0,0,1,6.75,12.75Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml
index ff02c59..793bae5 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_0.xml
@@ -1,52 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.7,8.3a0.83 0.83 ,0,0,0,1.05,0l0,0a0.73 0.73 ,0,0,0,0-1A14.51,14.51,0,0,0,12,2.8,14.77,14.77,0,0,0,1.25,7.25a0.76 0.76 ,0,0,0,0,1.05l0,0a0.72 0.72 ,0,0,0,1,0,13.34,13.34,0,0,1,9.7-4A13.16,13.16,0,0,1,21.7,8.3Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M19,11.8a0.74 0.74 ,0,0,0,1.05-1.05,11.43,11.43,0,0,0-8-3.5,11.36,11.36,0,0,0-8,3.5 0.74 0.74,0,0,0,1,1.05,9.93,9.93,0,0,1,7-3A10.15,10.15,0,0,1,19,11.8Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M7.25,13.75a0.76 0.76 ,0,0,0,0,1l0,0a0.73 0.73 ,0,0,0,1,0,5.28,5.28,0,0,1,6.2-0.9,3.87,3.87,0,0,1,1.57-0.78A6.73,6.73,0,0,0,7.25,13.75Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.92,16.08a0.74 0.74 ,0,0,0-1.06,0L19,17.94l-1.86-1.86a0.75 0.75 ,0,0,0-1.06,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86A0.74 0.74 ,0,0,0,21.92,16.08Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,18.42l-1,1.22L2.01,7.48C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L18.27,12h1.94l2.93-3.57 c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63 c0.2,0.24,0.49,0.37,0.77,0.37s0.57-0.12,0.77-0.37L13,20.78V18.42z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.56,17.5l2.22-2.22c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06l2.22,2.22l-2.22,2.22c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 l2.22-2.22l2.22,2.22c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L19.56,17.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml
index 6a645a3..4893b48 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_1.xml
@@ -1,49 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M7.23,13.71a0.75 0.75 ,0,0,0,1.06,1.06,5.23,5.23,0,0,1,6.22-0.88,4,4,0,0,1,1.57-0.78A6.75,6.75,0,0,0,7.23,13.71Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M19,11.77a0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.75 0.75,0,0,0-0.1,1.06 0.74 0.74,0,0,0,1,0.1A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3A10.1,10.1,0,0,1,19,11.77Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.72,8.27a0.75 0.75 ,0,0,0,1.07-1A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.76 0.76 ,0,0,0,0.05,1.06 0.76 0.76,0,0,0,1,0,13.25,13.25,0,0,1,9.7-4A13.27,13.27,0,0,1,21.72,8.27Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.92,16.08a0.74 0.74 ,0,0,0-1.06,0L19,17.94l-1.86-1.86a0.75 0.75 ,0,0,0-1.06,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86A0.74 0.74 ,0,0,0,21.92,16.08Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,13.11c-0.32-0.08-0.66-0.12-1-0.12c-1.4,0-2.65,0.64-3.47,1.64c-0.11,0.13-0.21,0.27-0.3,0.41L2.01,7.48 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L18.27,12h1.94l2.93-3.57c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2 C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l6.72,8.19c0,0,0,0,0,0l4.41,5.37H12l1-1.21V13.11z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.56,17.5l2.22-2.22c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06l2.22,2.22l-2.22,2.22c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 l2.22-2.22l2.22,2.22c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L19.56,17.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml
index b2207f9..4757f0f 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_2.xml
@@ -1,46 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M7.23,13.71a0.75 0.75 ,0,0,0,1.06,1.06,5.23,5.23,0,0,1,6.22-0.88,4,4,0,0,1,1.57-0.78A6.75,6.75,0,0,0,7.23,13.71Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.72,8.27a0.75 0.75 ,0,0,0,1.07-1A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.76 0.76 ,0,0,0,0.05,1.06 0.76 0.76,0,0,0,1,0,13.25,13.25,0,0,1,9.7-4A13.27,13.27,0,0,1,21.72,8.27Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M19,11.77a0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.75 0.75,0,0,0-0.1,1.06 0.74 0.74,0,0,0,1,0.1A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3A10.1,10.1,0,0,1,19,11.77Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.92,16.08a0.74 0.74 ,0,0,0-1.06,0L19,17.94l-1.86-1.86a0.75 0.75 ,0,0,0-1.06,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86A0.74 0.74 ,0,0,0,21.92,16.08Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,12h4.08c-1.33-1.24-3.12-2.01-5.08-2.01c-2.12,0-4.03,0.88-5.39,2.3c-0.12,0.12-0.22,0.26-0.33,0.39 l-4.27-5.2C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98L18.27,12h1.94l2.93-3.57c0.5-0.61,0.45-1.51-0.13-2.05 C20.12,3.66,16.25,2,12,2C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.2,0.24,0.49,0.37,0.77,0.37 s0.57-0.12,0.77-0.37L13,20.78v0V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.78,14.22c-0.29-0.29-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l2.22,2.22 l-2.22,2.22c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22l2.22-2.22l2.22,2.22 c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06l-2.22-2.22l2.22-2.22 C22.07,14.99,22.07,14.51,21.78,14.22z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml
index 6dd92a0..6d9059d 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_3.xml
@@ -1,43 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M7.23,13.71a0.75 0.75 ,0,0,0,1.06,1.06,5.23,5.23,0,0,1,6.22-0.88,4,4,0,0,1,1.57-0.78A6.75,6.75,0,0,0,7.23,13.71Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.72,8.27a0.75 0.75 ,0,0,0,1.07-1A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.76 0.76 ,0,0,0,0.05,1.06 0.76 0.76,0,0,0,1,0,13.25,13.25,0,0,1,9.7-4A13.27,13.27,0,0,1,21.72,8.27Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19,11.77a0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.75 0.75,0,0,0-0.1,1.06 0.74 0.74,0,0,0,1,0.1A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3A10.1,10.1,0,0,1,19,11.77Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M21.92,16.08a0.74 0.74 ,0,0,0-1.06,0L19,17.94l-1.86-1.86a0.75 0.75 ,0,0,0-1.06,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86A0.74 0.74 ,0,0,0,21.92,16.08Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,12h7.21c0,0,0.49-0.59,0.49-0.59l2.44-2.98c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2 C7.75,2,3.88,3.66,0.99,6.38C0.41,6.92,0.36,7.82,0.86,8.43l2.44,2.98c0,0,0,0,0,0l7.93,9.65c0,0,0,0,0,0l0,0 c0.2,0.24,0.49,0.37,0.77,0.37s0.57-0.12,0.77-0.37L13,20.78V12z M4.65,9.9c-0.03,0.02-0.36,0.35-0.36,0.35L2.01,7.48 C4.74,4.91,8.29,3.5,12,3.5s7.26,1.41,9.98,3.98l-2.28,2.77c-0.09-0.09-0.33-0.33-0.36-0.35C17.43,8.1,14.86,6.99,12,6.99 S6.57,8.1,4.65,9.9z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.56,17.5l2.22-2.22c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06l2.22,2.22l-2.22,2.22c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 l2.22-2.22l2.22,2.22c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L19.56,17.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml
index 13b0069..a7d5048 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_4.xml
@@ -1,40 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M7.23,13.71a0.75 0.75 ,0,0,0,1.06,1.06,5.23,5.23,0,0,1,6.22-0.88,4,4,0,0,1,1.57-0.78A6.75,6.75,0,0,0,7.23,13.71Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.3,8.25a13.25,13.25,0,0,1,9.7-4,13.27,13.27,0,0,1,9.72,4,0.75 0.75 ,0,0,0,1.07-1A14.76,14.76,0,0,0,12,2.75,14.76,14.76,0,0,0,1.22,7.2a0.76 0.76 ,0,0,0,0.05,1.06A0.76 0.76 ,0,0,0,2.3,8.25Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19,11.77a0.75 0.75 ,0,0,0,1.06,0,0.77 0.77 ,0,0,0,0-1.07h0a11.59,11.59,0,0,0-8-3.5,11.63,11.63,0,0,0-8,3.5 0.75 0.75,0,0,0-0.1,1.06 0.74 0.74,0,0,0,1,0.1A0.38 0.38 ,0,0,0,5,11.77a10.12,10.12,0,0,1,7-3A10.1,10.1,0,0,1,19,11.77Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.08,16.08a0.74 0.74 ,0,0,0,0,1.06L17.94,19l-1.86,1.86a0.74 0.74 ,0,0,0,0,1.06 0.73 0.73,0,0,0,0.53 0.22 0.74 0.74 ,0,0,0,0.53-0.22L19,20.06l1.86,1.86a0.74 0.74 ,0,0,0,0.53 0.22 0.73 0.73 ,0,0,0,0.53-0.22 0.74 0.74,0,0,0,0-1.06L20.06,19l1.86-1.86a0.75 0.75 ,0,0,0-1.06-1.06L19,17.94l-1.86-1.86A0.74 0.74 ,0,0,0,16.08,16.08Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M13.5,18.5a1.5,1.5,0,0,0-0.5-1.11,1.5,1.5,0,1,0,0,2.22A1.5,1.5,0,0,0,13.5,18.5Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M13,12h7.21l2.93-3.57c0.5-0.61,0.45-1.51-0.13-2.05C20.12,3.66,16.25,2,12,2S3.88,3.66,0.99,6.38 C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.4,0.49,1.15,0.49,1.55,0L13,20.78V12z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.56,17.5l2.22-2.22c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0l-2.22,2.22l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0 s-0.29,0.77,0,1.06l2.22,2.22l-2.22,2.22c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22 l2.22-2.22l2.22,2.22c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L19.56,17.5z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml
index c6607a7..bed6c8c 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_wifi_disconnected.xml
@@ -1,55 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M21.7,8.3a0.83 0.83 ,0,0,0,1.05,0l0,0a0.73 0.73 ,0,0,0,0-1A14.51,14.51,0,0,0,12,2.8,14.77,14.77,0,0,0,1.25,7.25a0.76 0.76 ,0,0,0,0,1.05l0,0a0.72 0.72 ,0,0,0,1,0,13.34,13.34,0,0,1,9.7-4A13.16,13.16,0,0,1,21.7,8.3Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M12.05,7.25a11.36,11.36,0,0,0-8,3.5 0.74 0.74,0,0,0,1,1.05,9.93,9.93,0,0,1,7-3,9.94,9.94,0,0,1,3.25 0.64 ,5.58,5.58,0,0,1,1.56-1A11.38,11.38,0,0,0,12.05,7.25Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M7.25,13.75a0.76 0.76 ,0,0,0,0,1l0,0a0.73 0.73 ,0,0,0,1,0,5.26,5.26,0,0,1,5.2-1.3A5.48,5.48,0,0,1,13.72,12,6.73,6.73,0,0,0,7.25,13.75Z" />
-    <path
-        android:fillColor="#000000"
-        android:fillAlpha="0.3"
-        android:strokeAlpha="0.3"
-        android:strokeWidth="1"
-        android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.42,11.09a3.66,3.66,0,0,0-1,1.76 0.73 0.73,0,0,0,0.56 0.9 0.74 0.74 ,0,0,0,0.9-0.56,2.23,2.23,0,0,1,0.56-1,2.14,2.14,0,0,1,3,0,2,2,0,0,1,0.57,1.57,1.61,1.61,0,0,1-0.72,1.2,3.13,3.13,0,0,1-0.34 0.21 ,3.07,3.07,0,0,0-1.76,2.34 0.75 0.75,0,0,0,0.62 0.86 H19a0.75 0.75 ,0,0,0,0.74-0.62,1.62,1.62,0,0,1,1-1.29c0.15-0.09 0.3 -0.17 0.44 -0.27a3.14,3.14,0,0,0,1.37-2.29,3.46,3.46,0,0,0-1-2.77A3.68,3.68,0,0,0,16.42,11.09Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 19 20 C 19.5522847498 20 20 20.4477152502 20 21 C 20 21.5522847498 19.5522847498 22 19 22 C 18.4477152502 22 18 21.5522847498 18 21 C 18 20.4477152502 18.4477152502 20 19 20 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillAlpha="0.3" android:fillColor="@android:color/white" android:pathData="M14.48,16.62L12,19.64L2.01,7.48C4.74,4.91,8.29,3.5,12,3.5c3.71,0,7.26,1.41,9.98,3.98L21.56,8 c0.66,0,1.3,0,1.82,0c0.21-0.55,0.09-1.19-0.36-1.62C20.12,3.66,16.25,2,12,2C7.75,2,3.88,3.66,0.99,6.38 C0.41,6.92,0.36,7.82,0.86,8.43l10.37,12.63c0.2,0.24,0.49,0.37,0.77,0.37s0.57-0.12,0.77-0.37l2.73-3.32 C15.11,17.42,14.76,17.04,14.48,16.62z" android:strokeAlpha="0.3" android:strokeWidth="1"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.58,11.09c-1.38-1.41-3.79-1.41-5.16,0c-0.47,0.48-0.8,1.09-0.95,1.76c-0.09,0.4,0.16,0.81,0.56,0.9 c0.4,0.1,0.81-0.16,0.9-0.56c0.09-0.41,0.29-0.77,0.56-1.05c0.81-0.83,2.21-0.83,3.02,0c0.42,0.43,0.63,1,0.57,1.57 c-0.05,0.5-0.31,0.92-0.72,1.2c-0.11,0.08-0.23,0.14-0.35,0.21c-0.64,0.37-1.51,0.88-1.75,2.34c-0.07,0.41,0.21,0.79,0.62,0.86 c0.04,0.01,0.08,0.01,0.12,0.01c0.36,0,0.68-0.26,0.74-0.63c0.13-0.76,0.48-0.97,1.03-1.28c0.15-0.09,0.3-0.17,0.44-0.27 c0.79-0.53,1.28-1.35,1.37-2.3C22.68,12.85,22.32,11.84,21.58,11.09z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M 19 20 C 19.5522847498 20 20 20.4477152502 20 21 C 20 21.5522847498 19.5522847498 22 19 22 C 18.4477152502 22 18 21.5522847498 18 21 C 18 20.4477152502 18.4477152502 20 19 20 Z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_screenshot_delete.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_screenshot_delete.xml
index 9b42490..7297658 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_screenshot_delete.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_screenshot_delete.xml
@@ -1,34 +1,22 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M8,21h8a3,3,0,0,0,3-3V5.5h1A0.75 0.75 ,0,0,0,20,4H15a1,1,0,0,0-1-1H10A1,1,0,0,0,9,4H4A0.75 0.75 ,0,0,0,4,5.5H5V18A3,3,0,0,0,8,21ZM9,5.5h8.5V18A1.5,1.5,0,0,1,16,19.5H8A1.5,1.5,0,0,1,6.5,18V5.5Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 13.5 8 H 15 V 17 H 13.5 V 8 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 9 8 H 10.5 V 17 H 9 V 8 Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M20,4h-1h-4c0-0.55-0.45-1-1-1h-4C9.45,3,9,3.45,9,4H5H4C3.59,4,3.25,4.34,3.25,4.75S3.59,5.5,4,5.5h1V18 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V5.5h1c0.41,0,0.75-0.34,0.75-0.75S20.41,4,20,4z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V5.5h11V18z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M14.25,8c-0.41,0-0.75,0.34-0.75,0.75v7.5c0,0.41,0.34,0.75,0.75,0.75S15,16.66,15,16.25v-7.5C15,8.34,14.66,8,14.25,8z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M9.75,8C9.34,8,9,8.34,9,8.75v7.5C9,16.66,9.34,17,9.75,17s0.75-0.34,0.75-0.75v-7.5C10.5,8.34,10.16,8,9.75,8z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings.xml
new file mode 100644
index 0000000..0fc673b
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M2.43,15.45l1.79,3.09c0.25,0.45,0.74,0.73,1.25,0.73c0.17,0,0.35-0.03,0.52-0.09l1.76-0.7c0.25,0.17,0.51,0.31,0.77,0.45 l0.26,1.84c0.09,0.71,0.69,1.24,1.42,1.24h3.61c0.72,0,1.33-0.53,1.43-1.19l0.26-1.86c0.25-0.14,0.51-0.28,0.76-0.45l1.76,0.7 c0.17,0.07,0.35,0.1,0.53,0.1c0.5,0,0.98-0.27,1.23-0.72l1.82-3.14c0.34-0.61,0.19-1.38-0.36-1.82l-1.48-1.16 c0.01-0.15,0.02-0.29,0.02-0.45s-0.01-0.3-0.02-0.45l1.48-1.16c0.55-0.43,0.7-1.19,0.35-1.84l-1.8-3.1 c-0.25-0.45-0.74-0.73-1.26-0.73c-0.17,0-0.35,0.03-0.52,0.09l-1.76,0.7c-0.25-0.17-0.51-0.31-0.77-0.45l-0.26-1.84 c-0.09-0.71-0.69-1.24-1.42-1.24h-3.61c-0.71,0-1.32,0.54-1.41,1.22L8.52,5.09C8.26,5.23,8.01,5.37,7.75,5.54L5.99,4.83 c-0.17-0.07-0.35-0.1-0.52-0.1c-0.5,0-0.98,0.27-1.22,0.72L2.43,8.55c-0.36,0.61-0.21,1.4,0.36,1.84l1.48,1.16 C4.27,11.7,4.26,11.85,4.26,12c0,0.16,0.01,0.3,0.02,0.45l-1.49,1.16C2.24,14.04,2.09,14.8,2.43,15.45z M5.2,13.63l0.63-0.49 l-0.05-0.79c-0.01-0.11-0.01-0.58,0-0.7l0.05-0.79L5.2,10.37L3.77,9.25l1.74-3l1.69,0.68l0.73,0.29l0.66-0.43 c0.19-0.13,0.4-0.25,0.65-0.38l0.67-0.36L10,5.3l0.25-1.79h3.48l0.26,1.8l0.11,0.76l0.69,0.36c0.23,0.12,0.44,0.24,0.64,0.37 l0.65,0.43l0.72-0.29l1.7-0.68l1.75,3.02l-1.43,1.12l-0.62,0.49l0.05,0.79c0.01,0.11,0.01,0.58,0,0.7l-0.05,0.79l0.62,0.49 l1.43,1.12l-1.74,3.02l-1.69-0.68l-0.72-0.29l-0.65,0.43c-0.19,0.13-0.4,0.25-0.65,0.38l-0.67,0.36l-0.11,0.75l-0.25,1.77h-3.5 L10,18.71l-0.11-0.76l-0.69-0.36c-0.23-0.12-0.44-0.24-0.64-0.37l-0.65-0.43l-0.72,0.29L5.5,17.76l-1.73-3.01L5.2,13.63z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,16c2.21,0,4-1.79,4-4s-1.79-4-4-4c-2.21,0-4,1.79-4,4S9.79,16,12,16z M12,9.5c1.38,0,2.5,1.12,2.5,2.5 s-1.12,2.5-2.5,2.5c-1.38,0-2.5-1.12-2.5-2.5S10.62,9.5,12,9.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings_16dp.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings_16dp.xml
index 4237323..66d1cb9 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings_16dp.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_settings_16dp.xml
@@ -21,11 +21,9 @@
     android:viewportHeight="24">
 
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M2.43,15.45l1.79,3.09c0.25,0.45,0.74,0.73,1.25,0.73c0.17,0,0.35-0.03,0.52-0.09l1.76-0.7c0.25,0.17,0.51,0.31,0.77,0.45 l0.26,1.84c0.09,0.71,0.69,1.24,1.42,1.24h3.61c0.72,0,1.33-0.53,1.43-1.19l0.26-1.86c0.25-0.14,0.51-0.28,0.76-0.45l1.76,0.7 c0.17,0.07,0.35,0.1,0.53,0.1c0.5,0,0.98-0.27,1.23-0.72l1.82-3.14c0.34-0.61,0.19-1.38-0.36-1.82l-1.48-1.16 c0.01-0.15,0.02-0.29,0.02-0.45s-0.01-0.3-0.02-0.45l1.48-1.16c0.55-0.43,0.7-1.19,0.35-1.84l-1.8-3.1 c-0.25-0.45-0.74-0.73-1.26-0.73c-0.17,0-0.35,0.03-0.52,0.09l-1.76,0.7c-0.25-0.17-0.51-0.31-0.77-0.45l-0.26-1.84 c-0.09-0.71-0.69-1.24-1.42-1.24h-3.61c-0.71,0-1.32,0.54-1.41,1.22L8.52,5.09C8.26,5.23,8.01,5.37,7.75,5.54L5.99,4.83 c-0.17-0.07-0.35-0.1-0.52-0.1c-0.5,0-0.98,0.27-1.22,0.72L2.43,8.55c-0.36,0.61-0.21,1.4,0.36,1.84l1.48,1.16 C4.27,11.7,4.26,11.85,4.26,12c0,0.16,0.01,0.3,0.02,0.45l-1.49,1.16C2.24,14.04,2.09,14.8,2.43,15.45z M5.2,13.63l0.63-0.49 l-0.05-0.79C5.77,12.24,5.76,12.12,5.76,12c0-0.11,0.01-0.24,0.02-0.35l0.05-0.79L5.2,10.37L3.77,9.25l1.74-3l1.69,0.68l0.73,0.29 l0.66-0.43c0.19-0.13,0.4-0.25,0.65-0.38l0.67-0.36L10,5.3l0.25-1.79h3.48l0.26,1.8l0.11,0.76l0.69,0.36 c0.23,0.12,0.44,0.24,0.64,0.37l0.65,0.43l0.72-0.29l1.7-0.68l1.75,3.02l-1.43,1.12l-0.62,0.49l0.05,0.79 c0.01,0.11,0.02,0.23,0.02,0.35c0,0.12-0.01,0.23-0.02,0.35l-0.05,0.79l0.62,0.49l1.43,1.12l-1.74,3.02l-1.69-0.68l-0.72-0.29 l-0.65,0.43c-0.19,0.13-0.4,0.25-0.65,0.38l-0.67,0.36l-0.11,0.75l-0.25,1.77h-3.5L10,18.71l-0.11-0.76l-0.69-0.36 c-0.23-0.12-0.44-0.24-0.64-0.37l-0.65-0.43l-0.72,0.29L5.5,17.76l-1.73-3.01L5.2,13.63z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M2.2,15.53,4,18.7a1.46,1.46,0,0,0,1.28 0.75 ,1.61,1.61,0,0,0,0.53-0.1l1.8-0.72a9,9,0,0,0,0.79 0.46 L8.7,21a1.45,1.45,0,0,0,1.45,1.27h3.7A1.47,1.47,0,0,0,15.31,21l0.27-1.91c0.26-0.14 0.52 -0.29 0.78 -0.46l1.8 0.72 a1.47,1.47,0,0,0,0.54 0.1 A1.43,1.43,0,0,0,20,18.75l1.86-3.22a1.47,1.47,0,0,0-0.37-1.86l-1.52-1.19c0-0.15,0-0.3,0-0.46s0-0.31,0-0.46l1.52-1.19a1.47,1.47,0,0,0,0.36-1.88L20,5.31a1.46,1.46,0,0,0-1.29-0.75,1.71,1.71,0,0,0-0.53 0.1 l-1.8 0.72 a9,9,0,0,0-0.79-0.46L15.29,3a1.45,1.45,0,0,0-1.45-1.27h-3.7A1.46,1.46,0,0,0,8.7,3L8.43,4.92c-0.26 0.14 -0.52 0.29 -0.78 0.46 L5.84,4.65a1.47,1.47,0,0,0-0.54-0.1,1.42,1.42,0,0,0-1.25 0.73 L2.2,8.47a1.44,1.44,0,0,0,0.37,1.88l1.52,1.19c0,0.15,0,0.31,0,0.46s0,0.31,0,0.46L2.56,13.65A1.48,1.48,0,0,0,2.2,15.53ZM5,13.64l0.63-0.49,0-0.79c0-0.12,0-0.23,0-0.36s0-0.24,0-0.36l0-0.79L5,10.36,3.52,9.19,5.33,6.06l1.76 0.71 0.73 0.29 0.65-0.42a6.59,6.59,0,0,1,0.67-0.4l0.67-0.36 0.11 -0.75 0.26 -1.87h3.63l0.27,1.87 0.1 0.77 0.69 0.35a6,6,0,0,1,0.66 0.39 l0.65 0.42 0.73-0.29,1.76-0.71L20.5,9.21,19,10.38l-0.63 0.49 0.05 0.79 c0,0.12,0,0.23,0,0.36s0,0.24,0,0.36l-0.05 0.79 0.63 0.49 ,1.48,1.17L18.68,18l-1.76-0.7L16.19,17l-0.65 0.42 a6.59,6.59,0,0,1-0.67 0.4 l-0.67 0.36 -0.11 0.75 -0.26,1.84H10.18l-0.27-1.87-0.1-0.77-0.69-0.35a6,6,0,0,1-0.66-0.39L7.81,17l-0.73 0.29 L5.33,18,3.52,14.8Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12,16a4,4,0,1,0-4-4A4,4,0,0,0,12,16Zm0-6.5A2.5,2.5,0,1,1,9.5,12,2.5,2.5,0,0,1,12,9.5Z" />
-</vector>
+        android:fillColor="#FFFFFF"
+        android:pathData="M12,16c2.21,0,4-1.79,4-4s-1.79-4-4-4c-2.21,0-4,1.79-4,4S9.79,16,12,16z M12,9.5c1.38,0,2.5,1.12,2.5,2.5 s-1.12,2.5-2.5,2.5c-1.38,0-2.5-1.12-2.5-2.5S10.62,9.5,12,9.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_airplane.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_airplane.xml
deleted file mode 100644
index 2d36a39..0000000
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_airplane.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M2.52,16.17a1.25,1.25,0,0,0,1.11 0.19 L9.5,14.52v3.87L8,19.52a1.26,1.26,0,0,0-0.5,1v0.75a1.25,1.25,0,0,0,1.25,1.25h6.5a1.25,1.25,0,0,0,1.25-1.25v-0.75a1.26,1.26,0,0,0-0.5-1l-1.5-1.13V14.52l5.88,1.84a1.23,1.23,0,0,0,1.11-0.19,1.25,1.25,0,0,0,0.51-1V13.33a1.74,1.74,0,0,0-0.89-1.52L14.5,8.06V3.75a2.5,2.5,0,0,0-5,0V8.06L2.89,11.8A1.78,1.78,0,0,0,2,13.33v1.83A1.25,1.25,0,0,0,2.52,16.17Zm1.11-3.06L11,8.94V3.75a1,1,0,0,1,2,0V8.94l7.37,4.17a0.26 0.26 ,0,0,1,0.13 0.22 v1.49L13,12.48v6.66l2,1.5V21H9v-0.38l2-1.5V12.48L3.51,14.82V13.33A0.25 0.25 ,0,0,1,3.63,13.11Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_flashlight.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_flashlight.xml
deleted file mode 100644
index 3bde46f..0000000
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_signal_flashlight.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M9,22h6a0.76 0.76 ,0,0,0,0.75-0.75V11.46l1.89-3.07A0.77 0.77 ,0,0,0,17.75,8V2.75A0.76 0.76 ,0,0,0,17,2H7a0.76 0.76 ,0,0,0-0.75 0.75 v5a0.77 0.77 ,0,0,0,0.11 0.39 l1.89,3.07v10A0.76 0.76 ,0,0,0,9,22ZM16.25,3.5V5H7.75V3.5Zm-8.5,4v-1h8.5V7.79l-1.89,3.07a0.77 0.77 ,0,0,0-0.11 0.39 V20.5H9.75V11a0.77 0.77 ,0,0,0-0.11-0.39Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M 12 12.75 C 12.6903559373 12.75 13.25 13.3096440627 13.25 14 C 13.25 14.6903559373 12.6903559373 15.25 12 15.25 C 11.3096440627 15.25 10.75 14.6903559373 10.75 14 C 10.75 13.3096440627 11.3096440627 12.75 12 12.75 Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_swap_vert.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_swap_vert.xml
index 297d886..f4c1ba1 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_swap_vert.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_swap_vert.xml
@@ -1,31 +1,21 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- * * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
 
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M6,8,8.25,5.81V13a0.75 0.75 ,0,1,0,1.5,0V5.81L12,8A0.75 0.75 ,0,0,0,13,8,0.75 0.75 ,0,0,0,13,7l-3.5-3.5a0.75 0.75 ,0,0,0-1.06,0L5,7A0.75 0.75 ,0,1,0,6,8Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M19,16A0.75 0.75 ,0,0,0,18,16l-2.22,2.22V11a0.75 0.75 ,0,0,0-1.5,0v7.21L12,16A0.75 0.75 ,0,1,0,11,17l3.5,3.5a0.75 0.75 ,0,0,0,1.06,0L19,17A0.75 0.75 ,0,0,0,19,16Z" />
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M19.03,16.99c-0.29-0.29-0.77-0.29-1.06,0l-2.22,2.22v-8.46c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v8.46 l-2.22-2.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l3.5,3.5c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22l3.5-3.5 C19.32,17.76,19.32,17.29,19.03,16.99z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M11.97,7.01c0.29,0.29,0.77,0.29,1.06,0s0.29-0.77,0-1.06l-3.5-3.5C9.38,2.3,9.19,2.23,9,2.23S8.62,2.3,8.47,2.45 l-3.5,3.5c-0.29,0.29-0.29,0.77,0,1.06s0.77,0.29,1.06,0l2.22-2.22v8.46C8.25,13.66,8.59,14,9,14s0.75-0.34,0.75-0.75V4.79 L11.97,7.01z"/>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml
new file mode 100644
index 0000000..41abc92
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_tune_black_16dp.xml
@@ -0,0 +1,25 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="16dp" android:viewportHeight="24" android:viewportWidth="24" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M3.75,4.75C3.34,4.75,3,5.09,3,5.5s0.34,0.75,0.75,0.75H14v-1.5H3.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.25,4.75H17v-1.5c0-0.41-0.34-0.75-0.75-0.75S15.5,2.84,15.5,3.25v4.5c0,0.41,0.34,0.75,0.75,0.75S17,8.16,17,7.75v-1.5 h3.25C20.66,6.25,21,5.91,21,5.5S20.66,4.75,20.25,4.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.25,11.25H10v1.5h10.25c0.41,0,0.75-0.34,0.75-0.75S20.66,11.25,20.25,11.25z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M3.75,17.75C3.34,17.75,3,18.09,3,18.5s0.34,0.75,0.75,0.75H10v-1.5H3.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M20.25,17.75H13v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v4.5c0,0.41,0.34,0.75,0.75,0.75S13,21.16,13,20.75 v-1.5h7.25c0.41,0,0.75-0.34,0.75-0.75S20.66,17.75,20.25,17.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M8.5,9.75C8.5,9.34,8.16,9,7.75,9S7,9.34,7,9.75v1.5H3.75C3.34,11.25,3,11.59,3,12s0.34,0.75,0.75,0.75H7v1.5 C7,14.66,7.34,15,7.75,15s0.75-0.34,0.75-0.75V9.75z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm.xml
index 167d15f..bd7f234 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm.xml
@@ -21,17 +21,15 @@
     android:viewportHeight="24">
 
     <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M13.93,16.02c0.15,0.15,0.34,0.22,0.53,0.22c0.19,0,0.38-0.07,0.53-0.22c0.29-0.29,0.3-0.77,0.01-1.06l-2.25-2.28V7.75 C12.75,7.34,12.41,7,12,7s-0.75,0.34-0.75,0.75V13c0,0.2,0.08,0.39,0.22,0.53L13.93,16.02z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M14.43,16.52a0.76 0.76 ,0,0,0,0.54 0.23 0.79 0.79 ,0,0,0,0.53-0.22 0.75 0.75,0,0,0,0-1.06l-2.75-2.78V8a0.75 0.75 ,0,0,0-1.5,0v5a0.75 0.75 ,0,0,0,0.22 0.53 Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M16.4,2.55c-0.25,0.33-0.18,0.8,0.15,1.05l4.02,3c0.13,0.1,0.29,0.15,0.45,0.15c0.23,0,0.45-0.1,0.6-0.3 c0.25-0.33,0.18-0.8-0.15-1.05l-4.02-3C17.12,2.15,16.65,2.22,16.4,2.55z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M16.4,2.55a0.75 0.75 ,0,0,0,0.15,1.05l4,3a0.78 0.78 ,0,0,0,0.45 0.15 0.73 0.73 ,0,0,0,0.6-0.3 0.75 0.75,0,0,0-0.15-1l-4-3A0.75 0.75 ,0,0,0,16.4,2.55Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M2.98,6.75c0.16,0,0.31-0.05,0.45-0.15l4.02-3c0.33-0.25,0.4-0.72,0.15-1.05C7.35,2.22,6.88,2.15,6.55,2.4l-4.02,3 C2.2,5.65,2.13,6.12,2.38,6.45C2.52,6.65,2.75,6.75,2.98,6.75z" />
     <path
-        android:fillColor="#000000"
-        android:pathData="M3,6.75a0.78 0.78 ,0,0,0,0.45-0.15l4-3a0.75 0.75 ,0,1,0-0.9-1.2l-4,3a0.75 0.75 ,0,0,0-0.15,1A0.73 0.73 ,0,0,0,3,6.75Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M3.08,13A9,9,0,0,0,12,22h0a8.81,8.81,0,0,0,6.3-2.63A9,9,0,0,0,20.92,13v0A8.92,8.92,0,1,0,3.08,13ZM12,5.5A7.47,7.47,0,0,1,19.42,13h0.75l-0.75,0a7.47,7.47,0,0,1-2.18,5.29A7.33,7.33,0,0,1,12,20.5h0a7.5,7.5,0,0,1,0-15Z" />
+        android:fillColor="#FFFFFF"
+        android:pathData="M3.08,13c0,4.96,4,9,8.92,9c0,0,0.01,0,0.01,0c2.38,0,4.61-0.93,6.3-2.63c1.68-1.7,2.61-3.95,2.61-6.35V13 c0-4.96-4-9-8.92-9S3.08,8.04,3.08,13z M12,5.5c4.09,0,7.42,3.36,7.42,7.5h0.75l-0.75,0.02c0,2-0.78,3.88-2.18,5.3 c-1.4,1.41-3.26,2.19-5.23,2.19c0,0-0.01,0-0.01,0c-4.09,0-7.42-3.36-7.42-7.5S7.91,5.5,12,5.5z" />
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
new file mode 100644
index 0000000..aa0c740
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
@@ -0,0 +1,24 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M11.25,7.75v1.32l1.5,1.5V7.75C12.75,7.34,12.41,7,12,7S11.25,7.34,11.25,7.75z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M21.47,5.4l-4.02-3c-0.33-0.25-0.8-0.18-1.05,0.15c-0.25,0.33-0.18,0.8,0.15,1.05l4.02,3c0.13,0.1,0.29,0.15,0.45,0.15 c0.23,0,0.45-0.1,0.6-0.3C21.87,6.12,21.8,5.65,21.47,5.4z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M7.45,3.6c0.33-0.25,0.4-0.72,0.15-1.05C7.35,2.22,6.88,2.15,6.55,2.4L5.42,3.24l1.07,1.07L7.45,3.6z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M18.6,16.42l1.1,1.1c0.78-1.35,1.21-2.9,1.21-4.51V13c0-4.96-4-9-8.92-9c-1.66,0-3.21,0.47-4.55,1.27l1.1,1.1 C9.58,5.82,10.75,5.5,12,5.5c4.09,0,7.42,3.36,7.42,7.5v0.02C19.42,14.22,19.13,15.38,18.6,16.42z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M4.67,4.61c-0.29-0.29-0.77-0.29-1.06,0L3.6,4.6L2.53,5.4C2.2,5.65,2.13,6.12,2.38,6.45c0.15,0.2,0.37,0.3,0.6,0.3 c0.16,0,0.31-0.05,0.45-0.15l0.64-0.48l1.1,1.1C3.87,8.79,3.08,10.8,3.08,13c0,4.96,4,9,8.92,9c0,0,0.01,0,0.01,0 c2.14,0,4.17-0.76,5.78-2.15l1.93,1.93c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22c0,0,0,0,0,0 c0.29-0.29,0.29-0.77,0-1.06L4.67,4.61z M12.01,20.5C12.01,20.5,12,20.5,12.01,20.5c-4.1,0-7.43-3.36-7.43-7.5 c0-1.78,0.62-3.42,1.65-4.71l5.29,5.29l2.92,2.95c0.03,0.03,0.06,0.04,0.09,0.06l2.2,2.2C15.4,19.9,13.75,20.5,12.01,20.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml
new file mode 100644
index 0000000..9f4d035
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_ringer_vibrate.xml
@@ -0,0 +1,24 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="19dp" android:viewportHeight="24" android:viewportWidth="24" android:width="19dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M9,4C7.9,4,7,4.9,7,6v12c0,1.1,0.9,2,2,2h6c1.1,0,2-0.9,2-2V6c0-1.1-0.9-2-2-2H9z M15.5,6v12c0,0.28-0.22,0.5-0.5,0.5H9 c-0.28,0-0.5-0.22-0.5-0.5V6c0-0.28,0.22-0.5,0.5-0.5h6C15.28,5.5,15.5,5.72,15.5,6z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M19.25,17c0.41,0,0.75-0.34,0.75-0.75v-8.5C20,7.34,19.66,7,19.25,7S18.5,7.34,18.5,7.75v8.5C18.5,16.66,18.84,17,19.25,17 z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22.25,9c-0.41,0-0.75,0.34-0.75,0.75v4.5c0,0.41,0.34,0.75,0.75,0.75S23,14.66,23,14.25v-4.5C23,9.34,22.66,9,22.25,9z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M2.5,14.25v-4.5C2.5,9.34,2.16,9,1.75,9S1,9.34,1,9.75v4.5C1,14.66,1.34,15,1.75,15S2.5,14.66,2.5,14.25z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M4,16.25C4,16.66,4.34,17,4.75,17s0.75-0.34,0.75-0.75v-8.5C5.5,7.34,5.16,7,4.75,7S4,7.34,4,7.75V16.25z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_camera.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_camera.xml
new file mode 100644
index 0000000..ab73718
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_camera.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M22,7c0-1.1-0.9-2-2-2h-3l-1.41-1.41C15.21,3.21,14.7,3,14.17,3H9.83C9.3,3,8.79,3.21,8.41,3.59L7,5H4C2.9,5,2,5.9,2,7v12 c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V7z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4c-0.28,0-0.5-0.22-0.5-0.5V7c0-0.28,0.22-0.5,0.5-0.5 h3.62l1.85-1.85C9.57,4.55,9.69,4.5,9.83,4.5h4.34c0.13,0,0.26,0.05,0.35,0.15l1.85,1.85H20c0.28,0,0.5,0.22,0.5,0.5V19z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M12,9c-2.21,0-4,1.79-4,4c0,2.21,1.79,4,4,4c2.21,0,4-1.79,4-4C16,10.79,14.21,9,12,9z M12,15.5c-1.38,0-2.5-1.12-2.5-2.5 c0-1.38,1.12-2.5,2.5-2.5c1.38,0,2.5,1.12,2.5,2.5C14.5,14.38,13.38,15.5,12,15.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_mic_none.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_mic_none.xml
new file mode 100644
index 0000000..8baf94d
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_mic_none.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="18dp" android:viewportHeight="24" android:viewportWidth="24" android:width="18dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M12,15.5c1.93,0,3.5-1.57,3.5-3.5V5.5C15.5,3.57,13.93,2,12,2S8.5,3.57,8.5,5.5V12C8.5,13.93,10.07,15.5,12,15.5z M10,5.5 c0-1.1,0.9-2,2-2s2,0.9,2,2V12c0,1.1-0.9,2-2,2s-2-0.9-2-2V5.5z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M17.75,11.25C17.34,11.25,17,11.59,17,12c0,2.76-2.24,5-5,5s-5-2.24-5-5c0-0.41-0.34-0.75-0.75-0.75S5.5,11.59,5.5,12 c0,3.33,2.52,6.08,5.75,6.45v2.8c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-2.8c3.23-0.37,5.75-3.12,5.75-6.45 C18.5,11.59,18.16,11.25,17.75,11.25z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml
new file mode 100644
index 0000000..468c8b6
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/stat_sys_vpn_ic.xml
@@ -0,0 +1,21 @@
+
+<!--
+   Copyright (C) 2019 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<vector android:height="17dp" android:viewportHeight="24" android:viewportWidth="24" android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
+  <path android:fillColor="@android:color/white" android:pathData="M 6.5 9.5 C 7.60456949966 9.5 8.5 10.3954305003 8.5 11.5 C 8.5 12.6045694997 7.60456949966 13.5 6.5 13.5 C 5.39543050034 13.5 4.5 12.6045694997 4.5 11.5 C 4.5 10.3954305003 5.39543050034 9.5 6.5 9.5 Z"/>
+  <path android:fillColor="@android:color/white" android:pathData="M22,9H11.39C10.48,7.22,8.64,6,6.5,6C6.15,6,5.8,6.03,5.44,6.1c-2.13,0.4-3.88,2.09-4.32,4.22C0.38,13.87,3.08,17,6.5,17 c2.14,0,3.98-1.22,4.89-3H15v2c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-2h1c0.55,0,1-0.45,1-1v-3C23,9.45,22.55,9,22,9z M21.5,12.5 h-2v3h-3v-3h-6.14c-0.45,1.72-2,3-3.86,3c-2.21,0-4-1.79-4-4c0-2.21,1.79-4,4-4c1.86,0,3.41,1.28,3.86,3H21.5V12.5z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
index 48c3769..23d2e7b 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
@@ -22,4 +22,15 @@
          1: 2 button mode (back, home buttons + swipe up for overview)
          2: gestures only for back, home and overview -->
     <integer name="config_navBarInteractionMode">2</integer>
-</resources>
\ No newline at end of file
+
+    <!-- Controls whether the nav bar can move from the bottom to the side in landscape.
+         Only applies if the device display is not square. -->
+    <bool name="config_navBarCanMove">false</bool>
+
+    <!-- Controls whether the navigation bar lets through taps. -->
+    <bool name="config_navBarTapThrough">true</bool>
+
+    <!-- Controls the size of the back gesture inset. -->
+    <dimen name="config_backGestureInset">48dp</dimen>
+
+</resources>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
index 721d11b..c839b2c 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
@@ -19,6 +19,8 @@
 <resources>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_height">16dp</dimen>
+    <!-- Height of the bottom navigation bar in portrait; often the same as @dimen/navigation_bar_height -->
+    <dimen name="navigation_bar_height_landscape">16dp</dimen>
     <!-- Width of the navigation bar when it is placed vertically on the screen -->
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 95abd05..ce39a70 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7149,6 +7149,19 @@
 
     // Settings > Display > Theme
     DARK_UI_SETTINGS = 1698;
+
+    // Settings > global bubble settings
+    BUBBLE_SETTINGS = 1699;
+
+    // Settings > app > bubble settings
+    APP_BUBBLE_SETTINGS = 1700;
+
+    // OPEN: Settings > System > Aware > Info dialog
+    DIALOG_AWARE_STATUS = 1701;
+
+    // Open: Settings > app > bubble settings > confirmation dialog
+    DIALOG_APP_BUBBLE_SETTINGS = 1702;
+
     // ---- End Q Constants, all Q constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 1bcc888..bd72976 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -533,6 +533,9 @@
 
   // Network Suggestion API surface metrics.
   optional WifiNetworkSuggestionApiLog wifi_network_suggestion_api_log = 142;
+
+  // WifiLock statistics
+  optional WifiLockStats wifi_lock_stats = 143;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -703,8 +706,8 @@
     // External scorer
     NOMINATOR_EXTERNAL_SCORED = 6;
 
-    // Netrec
-    NOMINATOR_NETREC = 7;
+    // Network Specifier
+    NOMINATOR_SPECIFIER = 7;
 
     // User connected choice override
     NOMINATOR_SAVED_USER_CONNECT_CHOICE = 8;
@@ -1752,6 +1755,9 @@
 
     // Firmware generated an alert
     TYPE_FIRMWARE_ALERT = 4;
+
+    // IP Manager lost reachability to network neighbors
+    TYPE_IP_REACHABILITY_LOST = 5;
   }
 
   // What event triggered WifiIsUnusableEvent.
@@ -2012,6 +2018,10 @@
 
   // Whether the primary registered cell of current entry is same as that of previous entry
   optional bool is_same_registered_cell = 33;
+
+  // The device mobility state
+  optional DeviceMobilityStatePnoScanStats.DeviceMobilityState
+          device_mobility_state = 34;
 }
 
 message WifiUsabilityStats {
@@ -2041,6 +2051,9 @@
 
     // Firmware generated an alert
     TYPE_FIRMWARE_ALERT = 4;
+
+    // IP Manager lost reachability to network neighbors
+    TYPE_IP_REACHABILITY_LOST = 5;
   }
 
   // The current wifi usability state
@@ -2051,6 +2064,10 @@
 
   // What event triggered WifiUsabilityStats.
   optional UsabilityStatsTriggerType trigger_type = 3;
+
+  // Firmware alert code. Only valid when the stats was triggered by a firmware
+  // alert, otherwise -1.
+  optional int32 firmware_alert_code = 4 [default = -1];
 }
 
 message DeviceMobilityStatePnoScanStats {
@@ -2451,3 +2468,30 @@
   // Histogram for size of the network lists provided by various apps on the device.
   repeated HistogramBucketInt32 network_list_size_histogram = 4;
 }
+
+// WifiLock metrics
+message WifiLockStats {
+    // Amount of time wifi is actively in HIGH_PERF mode (ms)
+    // This means the lock takes effect and the device takes the actions required for this mode
+    optional int64 high_perf_active_time_ms = 1;
+
+    // Amount of time wifi is actively in LOW_LATENCY mode (ms)
+    // This means the lock takes effect and the device takes the actions required for this mode
+    optional int64 low_latency_active_time_ms = 2;
+
+    // Histogram of HIGH_PERF lock acquisition duration (seconds)
+    // Note that acquiring the lock does not necessarily mean that device is actively in that mode
+    repeated HistogramBucketInt32 high_perf_lock_acq_duration_sec_histogram = 3;
+
+    // Histogram of LOW_LATENCY lock acquisition duration (seconds)
+    // Note that acquiring the lock does not necessarily mean that device is actively in that mode
+    repeated HistogramBucketInt32 low_latency_lock_acq_duration_sec_histogram = 4;
+
+    // Histogram of HIGH_PERF active session duration (seconds)
+    // This means the lock takes effect and the device takes the actions required for this mode
+    repeated HistogramBucketInt32 high_perf_active_session_duration_sec_histogram = 5;
+
+    // Histogram of LOW_LATENCY active session duration (seconds)
+    // This means the lock takes effect and the device takes the actions required for this mode
+    repeated HistogramBucketInt32 low_latency_active_session_duration_sec_histogram = 6;
+}
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 85c82bc..f4c2777 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -447,27 +447,33 @@
         validate();
         return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
     }
-    native long rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
+    native long rsnAllocationCreateFromBitmap(long con, long type, int mip, long bitmapHandle,
+                int usage);
     synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
         validate();
-        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
+        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp.getNativeInstance(), usage);
     }
 
-    native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
-    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
+    native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, long bitmapHandle,
+                int usage);
+    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp,
+                int usage) {
         validate();
-        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
+        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp.getNativeInstance(),
+                usage);
     }
 
-    native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
+    native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, long bitmapHandle,
+                int usage);
     synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
         validate();
-        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
+        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp.getNativeInstance(),
+                usage);
     }
-    native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
+    native long  rsnAllocationCreateBitmapRef(long con, long type, long bitmapHandle);
     synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
         validate();
-        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
+        return rsnAllocationCreateBitmapRef(mContext, type, bmp.getNativeInstance());
     }
     native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
     synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
@@ -475,10 +481,10 @@
         return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
     }
 
-    native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
+    native void  rsnAllocationCopyToBitmap(long con, long alloc, long bitmapHandle);
     synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
         validate();
-        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
+        rsnAllocationCopyToBitmap(mContext, alloc, bmp.getNativeInstance());
     }
 
     native void rsnAllocationSyncAll(long con, long alloc, int src);
@@ -487,8 +493,10 @@
         rsnAllocationSyncAll(mContext, alloc, src);
     }
 
-    native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, long[] stride, int xBytesSize, int dimY, int dimZ);
-    synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, long[] stride, int xBytesSize, int dimY, int dimZ) {
+    native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, long[] stride,
+                int xBytesSize, int dimY, int dimZ);
+    synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, long[] stride, int xBytesSize,
+                int dimY, int dimZ) {
         validate();
         return rsnAllocationGetByteBuffer(mContext, alloc, stride, xBytesSize, dimY, dimZ);
     }
@@ -529,10 +537,10 @@
         validate();
         rsnAllocationGenerateMipmaps(mContext, alloc);
     }
-    native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
+    native void  rsnAllocationCopyFromBitmap(long con, long alloc, long bitmapHandle);
     synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
         validate();
-        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
+        rsnAllocationCopyFromBitmap(mContext, alloc, bmp.getNativeInstance());
     }
 
 
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 52d0e08e..dfee961 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1321,10 +1321,10 @@
 
 static jlong
 nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
-                            jobject jbitmap, jint usage)
+                            jlong bitmapPtr, jint usage)
 {
     SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
 
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
@@ -1335,10 +1335,10 @@
 
 static jlong
 nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
-                                        jint mip, jobject jbitmap, jint usage)
+                                        jint mip, jlong bitmapPtr, jint usage)
 {
     SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
 
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
@@ -1349,10 +1349,10 @@
 
 static jlong
 nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
-                                jobject jbitmap, jint usage)
+                                jlong bitmapPtr, jint usage)
 {
     SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
 
     const void* ptr = bitmap.getPixels();
     jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
@@ -1362,10 +1362,10 @@
 }
 
 static void
-nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
+nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jlong bitmapPtr)
 {
     SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
     int w = bitmap.width();
     int h = bitmap.height();
 
@@ -1376,10 +1376,10 @@
 }
 
 static void
-nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
+nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jlong bitmapPtr)
 {
     SkBitmap bitmap;
-    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
+    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
 
     void* ptr = bitmap.getPixels();
     rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.computeByteSize());
@@ -2866,13 +2866,13 @@
 {"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
 {"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
 
-{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
-{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
-{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
-{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
+{"rsnAllocationCreateTyped",         "(JJIIJ)J",                              (void*)nAllocationCreateTyped },
+{"rsnAllocationCreateFromBitmap",    "(JJIJI)J",                              (void*)nAllocationCreateFromBitmap },
+{"rsnAllocationCreateBitmapBackedAllocation",    "(JJIJI)J",                  (void*)nAllocationCreateBitmapBackedAllocation },
+{"rsnAllocationCubeCreateFromBitmap","(JJIJI)J",                              (void*)nAllocationCubeCreateFromBitmap },
 
-{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
-{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
+{"rsnAllocationCopyFromBitmap",      "(JJJ)V",                                (void*)nAllocationCopyFromBitmap },
+{"rsnAllocationCopyToBitmap",        "(JJJ)V",                                (void*)nAllocationCopyToBitmap },
 
 {"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
 {"rsnAllocationSetupBufferQueue",    "(JJI)V",                                (void*)nAllocationSetupBufferQueue },
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 47cd917..6e2c228 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -777,6 +777,7 @@
             final int removedWindowId = removeAccessibilityInteractionConnectionInternalLocked(
                     token, mGlobalWindowTokens, mGlobalInteractionConnections);
             if (removedWindowId >= 0) {
+                mSecurityPolicy.onAccessibilityClientRemovedLocked(removedWindowId);
                 if (DEBUG) {
                     Slog.i(LOG_TAG, "Removed global connection for pid:" + Binder.getCallingPid()
                             + " with windowId: " + removedWindowId + " and token: " + window.asBinder());
@@ -790,6 +791,7 @@
                         removeAccessibilityInteractionConnectionInternalLocked(
                         token, userState.mWindowTokens, userState.mInteractionConnections);
                 if (removedWindowIdForUser >= 0) {
+                    mSecurityPolicy.onAccessibilityClientRemovedLocked(removedWindowIdForUser);
                     if (DEBUG) {
                         Slog.i(LOG_TAG, "Removed user connection for pid:" + Binder.getCallingPid()
                                 + " with windowId: " + removedWindowIdForUser + " and userId:"
@@ -1332,6 +1334,7 @@
             userState.mWindowTokens.remove(windowId);
             userState.mInteractionConnections.remove(windowId);
         }
+        mSecurityPolicy.onAccessibilityClientRemovedLocked(windowId);
         if (DEBUG) {
             Slog.i(LOG_TAG, "Removing interaction connection to windowId: " + windowId);
         }
@@ -2549,6 +2552,7 @@
                 pw.append(", autoclickEnabled=" + userState.mIsAutoclickEnabled);
                 pw.append(", nonInteractiveUiTimeout=" + userState.mNonInteractiveUiTimeout);
                 pw.append(", interactiveUiTimeout=" + userState.mInteractiveUiTimeout);
+                pw.append(", installedServiceCount=" + userState.mInstalledServices.size());
                 if (mUiAutomationManager.isUiAutomationRunningLocked()) {
                     pw.append(", ");
                     mUiAutomationManager.dumpUiAutomationService(fd, pw, args);
@@ -2556,7 +2560,7 @@
                 }
                 pw.append("}");
                 pw.println();
-                pw.append("           services:{");
+                pw.append("     Bound services:{");
                 final int serviceCount = userState.mBoundServices.size();
                 for (int j = 0; j < serviceCount; j++) {
                     if (j > 0) {
@@ -2567,6 +2571,30 @@
                     AccessibilityServiceConnection service = userState.mBoundServices.get(j);
                     service.dump(fd, pw, args);
                 }
+                pw.println("}");
+                pw.append("     Enabled services:{");
+                Iterator<ComponentName> it = userState.mEnabledServices.iterator();
+                if (it.hasNext()) {
+                    ComponentName componentName = it.next();
+                    pw.append(componentName.toShortString());
+                    while (it.hasNext()) {
+                        componentName = it.next();
+                        pw.append(", ");
+                        pw.append(componentName.toShortString());
+                    }
+                }
+                pw.println("}");
+                pw.append("     Binding services:{");
+                it = userState.mBindingServices.iterator();
+                if (it.hasNext()) {
+                    ComponentName componentName = it.next();
+                    pw.append(componentName.toShortString());
+                    while (it.hasNext()) {
+                        componentName = it.next();
+                        pw.append(", ");
+                        pw.append(componentName.toShortString());
+                    }
+                }
                 pw.println("}]");
                 pw.println();
             }
@@ -2582,6 +2610,7 @@
                     pw.append(window.toString());
                     pw.append(']');
                 }
+                pw.println();
             }
         }
     }
@@ -3266,6 +3295,18 @@
             mWindows = null;
         }
 
+        /**
+         * A callback when accessibility interaction client is removed.
+         */
+        public void onAccessibilityClientRemovedLocked(int windowId) {
+            // Active window cannot update immediately, if windows callback is unregistered.
+            // Update active window to invalid, when its a11y interaction client is removed.
+            if (mWindowsForAccessibilityCallback == null && windowId >= 0
+                    && mActiveWindowId == windowId) {
+                mActiveWindowId = INVALID_WINDOW_ID;
+            }
+        }
+
         public void updateWindowsLocked(List<WindowInfo> windows) {
             if (mWindows == null) {
                 mWindows = new ArrayList<>();
@@ -4085,6 +4126,13 @@
             return mBindingServices;
         }
 
+        /**
+         * Returns enabled service list.
+         */
+        public Set<ComponentName> getEnabledServicesLocked() {
+            return mEnabledServices;
+        }
+
         public int getSoftKeyboardShowMode() {
             return mSoftKeyboardShowMode;
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 3bd6220..b66caa5 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -123,12 +123,12 @@
         synchronized (mLock) {
             UserState userState = mUserStateWeakReference.get();
             if (userState == null) return;
-            if (userState.mEnabledServices.remove(mComponentName)) {
+            if (userState.getEnabledServicesLocked().remove(mComponentName)) {
                 final long identity = Binder.clearCallingIdentity();
                 try {
                     mSystemSupport.persistComponentNamesToSettingLocked(
                             Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                            userState.mEnabledServices, userState.mUserId);
+                            userState.getEnabledServicesLocked(), userState.mUserId);
                 } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
@@ -183,6 +183,14 @@
                 mWasConnectedAndDied = false;
                 serviceInterface = mServiceInterface;
             }
+            // There's a chance that service is removed from enabled_accessibility_services setting
+            // key, but skip unbinding because of it's in binding state. Unbinds it if it's
+            // not in enabled service list.
+            if (serviceInterface != null
+                    && !userState.getEnabledServicesLocked().contains(mComponentName)) {
+                mSystemSupport.onClientChangeLocked(false);
+                return;
+            }
         }
         if (serviceInterface == null) {
             binderDied();
diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
index 4bbf682..72c84e2 100644
--- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
@@ -64,9 +64,7 @@
                 public void binderDied() {
                     mUiAutomationServiceOwner.unlinkToDeath(this, 0);
                     mUiAutomationServiceOwner = null;
-                    if (mUiAutomationService != null) {
-                        destroyUiAutomationService();
-                    }
+                    destroyUiAutomationService();
                 }
             };
 
@@ -201,17 +199,20 @@
 
     private void destroyUiAutomationService() {
         synchronized (mLock) {
-            mUiAutomationService.mServiceInterface.asBinder().unlinkToDeath(mUiAutomationService,
-                    0);
-            mUiAutomationService.onRemoved();
-            mUiAutomationService.resetLocked();
-            mUiAutomationService = null;
-            mUiAutomationFlags = 0;
-            if (mUiAutomationServiceOwner != null) {
-                mUiAutomationServiceOwner.unlinkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0);
-                mUiAutomationServiceOwner = null;
+            if (mUiAutomationService != null) {
+                mUiAutomationService.mServiceInterface.asBinder().unlinkToDeath(
+                        mUiAutomationService, 0);
+                mUiAutomationService.onRemoved();
+                mUiAutomationService.resetLocked();
+                mUiAutomationService = null;
+                mUiAutomationFlags = 0;
+                if (mUiAutomationServiceOwner != null) {
+                    mUiAutomationServiceOwner.unlinkToDeath(
+                            mUiAutomationServiceOwnerDeathRecipient, 0);
+                    mUiAutomationServiceOwner = null;
+                }
+                mSystemSupport.onClientChangeLocked(false);
             }
-            mSystemSupport.onClientChangeLocked(false);
         }
     }
 
diff --git a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
index 21088e4..19226be 100644
--- a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
+++ b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
@@ -47,7 +47,8 @@
             RemoteAppPredictionServiceCallbacks callback, boolean bindInstantServiceAllowed,
             boolean verbose) {
         super(context, serviceInterface, componentName, userId, callback,
-                context.getMainThreadHandler(), bindInstantServiceAllowed,
+                context.getMainThreadHandler(),
+                bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0,
                 verbose, /* initialCapacity= */ 1);
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 87a265c..fdc3567 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -42,6 +42,7 @@
 import android.database.ContentObserver;
 import android.graphics.Rect;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcelable;
@@ -61,6 +62,7 @@
 import android.util.LocalLog;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillManager.SmartSuggestionMode;
@@ -72,6 +74,8 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.infra.AbstractRemoteService;
+import com.android.internal.infra.GlobalWhitelistState;
+import com.android.internal.infra.WhitelistHelper;
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
@@ -146,6 +150,7 @@
     private final LocalLog mWtfHistory = new LocalLog(50);
 
     private final AutofillCompatState mAutofillCompatState = new AutofillCompatState();
+
     private final LocalService mLocalService = new LocalService();
     private final ActivityManagerInternal mAm;
 
@@ -178,6 +183,8 @@
     @GuardedBy("mLock")
     int mAugmentedServiceRequestTimeoutMs;
 
+    final AugmentedAutofillState mAugmentedAutofillState = new AugmentedAutofillState();
+
     public AutofillManagerService(Context context) {
         super(context,
                 new SecureSettingsServiceNameResolver(context, Settings.Secure.AUTOFILL_SERVICE),
@@ -187,7 +194,7 @@
 
         DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_AUTOFILL,
                 ActivityThread.currentApplication().getMainExecutor(),
-                (namespace, key, value) -> onDeviceConfigChange(key, value));
+                (namespace, key, value) -> onDeviceConfigChange(key));
 
         setLogLevelFromSettings();
         setMaxPartitionsFromSettings();
@@ -198,20 +205,25 @@
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         context.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler());
 
+        mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(),
+                com.android.internal.R.string.config_defaultAugmentedAutofillService);
+        mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
+                (u, s, t) -> onAugmentedServiceNameChanged(u, s, t));
+
         if (mSupportedSmartSuggestionModes != AutofillManager.FLAG_SMART_SUGGESTION_OFF) {
-            // Must eager load the services so they bind to the augmented autofill service
             final UserManager um = getContext().getSystemService(UserManager.class);
             final List<UserInfo> users = um.getUsers();
             for (int i = 0; i < users.size(); i++) {
                 final int userId = users.get(i).id;
+                // Must eager load the services so they bind to the augmented autofill service
                 getServiceForUserLocked(userId);
+
+                // And also set the global state
+                mAugmentedAutofillState.setServiceInfo(userId,
+                        mAugmentedAutofillResolver.getServiceName(userId),
+                        mAugmentedAutofillResolver.isTemporary(userId));
             }
         }
-
-        mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(),
-                com.android.internal.R.string.config_defaultAugmentedAutofillService);
-        mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
-                (u, s) -> getServiceForUserLocked(u).updateRemoteAugmentedAutofillService());
     }
 
     @Override // from AbstractMasterSystemService
@@ -258,7 +270,7 @@
         }
     }
 
-    private void onDeviceConfigChange(@NonNull String key, @Nullable String value) {
+    private void onDeviceConfigChange(@NonNull String key) {
         switch (key) {
             case AutofillManager.DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES:
             case AutofillManager.DEVICE_CONFIG_AUGMENTED_SERVICE_IDLE_UNBIND_TIMEOUT:
@@ -270,6 +282,14 @@
         }
     }
 
+    private void onAugmentedServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName,
+            boolean isTemporary) {
+        mAugmentedAutofillState.setServiceInfo(userId, serviceName, isTemporary);
+        synchronized (mLock) {
+            getServiceForUserLocked(userId).updateRemoteAugmentedAutofillService();
+        }
+    }
+
     @Override // from AbstractMasterSystemService
     protected AutofillManagerServiceImpl newServiceLocked(@UserIdInt int resolvedUserId,
             boolean disabled) {
@@ -783,15 +803,7 @@
             final boolean compatModeEnabled = mAutofillCompatState.isCompatibilityModeRequested(
                     packageName, versionCode, userId);
             final AutofillOptions options = new AutofillOptions(loggingLevel, compatModeEnabled);
-
-            synchronized (mLock) {
-                final AutofillManagerServiceImpl service =
-                        getServiceForUserLocked(UserHandle.getCallingUserId());
-                if (service != null) {
-                    service.setAugmentedAutofillWhitelistLocked(options, packageName);
-                }
-            }
-
+            mAugmentedAutofillState.injectAugmentedAutofillInfo(options, userId, packageName);
             return options;
         }
     }
@@ -934,6 +946,89 @@
         }
     }
 
+    /**
+     * Augmented autofill metadata associated with all services.
+     *
+     * <p>This object is defined here instead of on each {@link AutofillManagerServiceImpl} because
+     * it cannot hold a lock on the main lock when
+     * {@link AugmentedAutofillState#injectAugmentedAutofillInfo(AutofillOptions, int, String)}
+     * is called by external services.
+     */
+    static final class AugmentedAutofillState extends GlobalWhitelistState {
+
+        @GuardedBy("mGlobalWhitelistStateLock")
+        private final SparseArray<String> mServicePackages = new SparseArray<>();
+        @GuardedBy("mGlobalWhitelistStateLock")
+        private final SparseBooleanArray mTemporaryServices = new SparseBooleanArray();
+
+        private void setServiceInfo(@UserIdInt int userId, @Nullable String serviceName,
+                boolean isTemporary) {
+            synchronized (mGlobalWhitelistStateLock) {
+                if (isTemporary) {
+                    mTemporaryServices.put(userId, true);
+                } else {
+                    mTemporaryServices.delete(userId);
+                }
+                if (serviceName != null) {
+                    final ComponentName componentName =
+                            ComponentName.unflattenFromString(serviceName);
+                    if (componentName == null) {
+                        Slog.w(TAG, "setServiceInfo(): invalid name: " + serviceName);
+                        mServicePackages.remove(userId);
+                    } else {
+                        mServicePackages.put(userId, componentName.getPackageName());
+                    }
+                } else {
+                    mServicePackages.remove(userId);
+                }
+            }
+        }
+
+        public void injectAugmentedAutofillInfo(@NonNull AutofillOptions options,
+                @UserIdInt int userId, @NonNull String packageName) {
+            synchronized (mGlobalWhitelistStateLock) {
+                if (mWhitelisterHelpers == null) return;
+                final WhitelistHelper helper = mWhitelisterHelpers.get(userId);
+                if (helper != null) {
+                    options.augmentedAutofillEnabled = helper.isWhitelisted(packageName);
+                    options.whitelistedActivitiesForAugmentedAutofill = helper
+                            .getWhitelistedComponents(packageName);
+                }
+            }
+        }
+
+        @Override
+        public boolean isWhitelisted(@UserIdInt int userId, @NonNull ComponentName componentName) {
+            synchronized (mGlobalWhitelistStateLock) {
+                if (!super.isWhitelisted(userId, componentName)) return false;
+
+                if (Build.IS_USER && mTemporaryServices.get(userId)) {
+                    final String packageName = componentName.getPackageName();
+                    if (!packageName.equals(mServicePackages.get(userId))) {
+                        Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill "
+                                + "while using temporary service " + mServicePackages.get(userId));
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+            super.dump(prefix, pw);
+
+            synchronized (mGlobalWhitelistStateLock) {
+                if (mServicePackages.size() > 0) {
+                    pw.print(prefix); pw.print("Service packages: "); pw.println(mServicePackages);
+                }
+                if (mTemporaryServices.size() > 0) {
+                    pw.print(prefix); pw.print("Temp services: "); pw.println(mTemporaryServices);
+                }
+            }
+        }
+    }
+
     final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
         @Override
         public void addClient(IAutoFillManagerClient client, ComponentName componentName,
@@ -1370,6 +1465,8 @@
                         pw.println(); pw.println("WTF history:"); pw.println();
                         mWtfHistory.reverseDump(fd, pw, args);
                     }
+                    pw.println("Augmented Autofill State: ");
+                    mAugmentedAutofillState.dump(prefix, pw);
                 }
             } finally {
                 sDebug = realDebug;
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index ff284dc..4bd6fbd 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -31,7 +31,6 @@
 import android.app.ActivityManagerInternal;
 import android.app.ActivityTaskManager;
 import android.app.IActivityTaskManager;
-import android.content.AutofillOptions;
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -40,7 +39,6 @@
 import android.metrics.LogMaker;
 import android.os.AsyncTask;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -76,7 +74,6 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.infra.WhitelistHelper;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.server.LocalServices;
@@ -170,12 +167,6 @@
     @Nullable
     private ServiceInfo mRemoteAugmentedAutofillServiceInfo;
 
-    /**
-     * List of packages/activities that are whitelisted to be trigger augmented autofill.
-     */
-    @GuardedBy("mLock")
-    private final WhitelistHelper mAugmentedWhitelistHelper = new WhitelistHelper();
-
     AutofillManagerServiceImpl(AutofillManagerService master, Object lock,
             LocalLog uiLatencyHistory, LocalLog wtfHistory, int userId, AutoFillUI ui,
             AutofillCompatState autofillCompatState,
@@ -247,7 +238,8 @@
         if (isEnabledLocked()) return FLAG_ADD_CLIENT_ENABLED;
 
         // Check if it's enabled for augmented autofill
-        if (isSetupCompletedLocked() && isWhitelistedForAugmentedAutofillLocked(componentName)) {
+        if (isAugmentedAutofillServiceAvailableLocked()
+                && isWhitelistedForAugmentedAutofillLocked(componentName)) {
             return FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY;
         }
 
@@ -950,8 +942,6 @@
             pw.println(mRemoteAugmentedAutofillServiceInfo);
         }
 
-        mAugmentedWhitelistHelper.dump(prefix, "Augmented autofill whitelist", pw);
-
         pw.print(prefix); pw.print("Field classification enabled: ");
             pw.println(isFieldClassificationEnabledLocked());
         pw.print(prefix); pw.print("Compat pkgs: ");
@@ -1148,19 +1138,39 @@
                 mRemoteAugmentedAutofillService.destroy();
                 mRemoteAugmentedAutofillService = null;
                 mRemoteAugmentedAutofillServiceInfo = null;
+                resetAugmentedAutofillWhitelistLocked();
             }
 
-            if (isEnabledLocked()) {
+            final boolean available = isAugmentedAutofillServiceAvailableLocked();
+            if (sVerbose) Slog.v(TAG, "updateRemoteAugmentedAutofillService(): " + available);
+
+            if (available) {
                 mRemoteAugmentedAutofillService = getRemoteAugmentedAutofillServiceLocked();
             }
         }
     }
 
+    private boolean isAugmentedAutofillServiceAvailableLocked() {
+        if (mMaster.verbose) {
+            Slog.v(TAG, "isAugmentedAutofillService(): "
+                    + "setupCompleted=" + isSetupCompletedLocked()
+                    + ", disabled=" + isDisabledByUserRestrictionsLocked()
+                    + ", augmentedService="
+                    + mMaster.mAugmentedAutofillResolver.getServiceName(mUserId));
+        }
+        if (!isSetupCompletedLocked() || isDisabledByUserRestrictionsLocked()
+                || mMaster.mAugmentedAutofillResolver.getServiceName(mUserId) == null) {
+            return false;
+        }
+        return true;
+    }
+
     /**
      * Sets which packages and activities can trigger augmented autofill.
      *
      * @return whether caller UID is the augmented autofill service for the user
      */
+    @GuardedBy("mLock")
     boolean setAugmentedAutofillWhitelistLocked(List<String> packages,
             List<ComponentName> activities, int callingUid) {
 
@@ -1213,27 +1223,7 @@
 
     @GuardedBy("mLock")
     boolean isWhitelistedForAugmentedAutofillLocked(@NonNull ComponentName componentName) {
-        if (Build.IS_USER && mMaster.mAugmentedAutofillResolver.isTemporary(mUserId)) {
-            final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId);
-            final ComponentName component = ComponentName.unflattenFromString(serviceName);
-            final String servicePackage = component == null ? null : component.getPackageName();
-            final String packageName = componentName.getPackageName();
-            if (!packageName.equals(servicePackage)) {
-                Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill while "
-                        + "using temporary service " + servicePackage);
-                return false;
-            }
-        }
-
-        return mAugmentedWhitelistHelper.isWhitelisted(componentName);
-    }
-
-    @GuardedBy("mLock")
-    void setAugmentedAutofillWhitelistLocked(@NonNull AutofillOptions options,
-            @NonNull String packageName) {
-        options.augmentedAutofillEnabled = mAugmentedWhitelistHelper.isWhitelisted(packageName);
-        options.whitelistedActivitiesForAugmentedAutofill = mAugmentedWhitelistHelper
-                .getWhitelistedComponents(packageName);
+        return mMaster.mAugmentedAutofillState.isWhitelisted(mUserId, componentName);
     }
 
     /**
@@ -1247,11 +1237,21 @@
             if (mMaster.verbose) {
                 Slog.v(TAG, "whitelisting packages: " + packages + "and activities: " + components);
             }
-            mAugmentedWhitelistHelper.setWhitelist(packages, components);
-            mRemoteAugmentedAutofillService = getRemoteAugmentedAutofillServiceLocked();
+            mMaster.mAugmentedAutofillState.setWhitelist(mUserId, packages, components);
         }
     }
 
+    /**
+     * Resets the augmented autofill whitelist.
+     */
+    @GuardedBy("mLock")
+    void resetAugmentedAutofillWhitelistLocked() {
+        if (mMaster.verbose) {
+            Slog.v(TAG, "resetting augmented autofill whitelist");
+        }
+        mMaster.mAugmentedAutofillState.resetWhitelist(mUserId);
+    }
+
     private void sendStateToClients(boolean resetClient) {
         final RemoteCallbackList<IAutoFillManagerClient> clients;
         final int userClientCount;
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index 3c17ac3..adf5829 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -58,7 +58,8 @@
             boolean bindInstantServiceAllowed, boolean verbose, int idleUnbindTimeoutMs,
             int requestTimeoutMs) {
         super(context, AugmentedAutofillService.SERVICE_INTERFACE, serviceName, userId, callbacks,
-                context.getMainThreadHandler(), bindInstantServiceAllowed, verbose);
+                context.getMainThreadHandler(),
+                bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0, verbose);
         mIdleUnbindTimeoutMs = idleUnbindTimeoutMs;
         mRequestTimeoutMs = requestTimeoutMs;
 
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index b8a7d44..0ce6c87 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -64,7 +64,8 @@
     RemoteFillService(Context context, ComponentName componentName, int userId,
             FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed) {
         super(context, AutofillService.SERVICE_INTERFACE, componentName, userId, callbacks,
-                context.getMainThreadHandler(), bindInstantServiceAllowed, sVerbose);
+                context.getMainThreadHandler(), Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
+                | (bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0), sVerbose);
         mCallbacks = callbacks;
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index c62794d..0402b8f 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2540,13 +2540,14 @@
         boolean saveOnFinish = true;
         final SaveInfo saveInfo = response.getSaveInfo();
         final AutofillId saveTriggerId;
+        final int flags;
         if (saveInfo != null) {
             saveTriggerId = saveInfo.getTriggerId();
             if (saveTriggerId != null) {
                 writeLog(MetricsEvent.AUTOFILL_EXPLICIT_SAVE_TRIGGER_DEFINITION);
             }
-            mSaveOnAllViewsInvisible =
-                    (saveInfo.getFlags() & SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) != 0;
+            flags = saveInfo.getFlags();
+            mSaveOnAllViewsInvisible = (flags & SaveInfo.FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE) != 0;
 
             // We only need to track views if we want to save once they become invisible.
             if (mSaveOnAllViewsInvisible) {
@@ -2561,11 +2562,12 @@
                     Collections.addAll(trackedViews, saveInfo.getOptionalIds());
                 }
             }
-            if ((saveInfo.getFlags() & SaveInfo.FLAG_DONT_SAVE_ON_FINISH) != 0) {
+            if ((flags & SaveInfo.FLAG_DONT_SAVE_ON_FINISH) != 0) {
                 saveOnFinish = false;
             }
 
         } else {
+            flags = 0;
             saveTriggerId = null;
         }
 
@@ -2592,7 +2594,8 @@
         try {
             if (sVerbose) {
                 Slog.v(TAG, "updateTrackedIdsLocked(): " + trackedViews + " => " + fillableIds
-                        + " triggerId: " + saveTriggerId + " saveOnFinish:" + saveOnFinish);
+                        + " triggerId: " + saveTriggerId + " saveOnFinish:" + saveOnFinish
+                        + " flags: " + flags + " hasSaveInfo: " + (saveInfo != null));
             }
             mClient.setTrackedViews(id, toArray(trackedViews), mSaveOnAllViewsInvisible,
                     saveOnFinish, toArray(fillableIds), saveTriggerId);
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 7106664..79afe8e 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -31,11 +31,14 @@
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
 import android.app.job.JobService;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.FileUtils;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
@@ -49,6 +52,7 @@
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
 
+import java.io.File;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Collections;
@@ -86,6 +90,18 @@
 
     private Set<ComponentName> mTransportWhitelist;
 
+    private final BroadcastReceiver mUserRemovedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+                int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+                if (userId > 0) { // for only non system users
+                    onRemovedNonSystemUser(userId);
+                }
+            }
+        }
+    };
+
     /** Instantiate a new instance of {@link BackupManagerService}. */
     public BackupManagerService(
             Context context, Trampoline trampoline, HandlerThread backupThread) {
@@ -99,6 +115,23 @@
         if (mTransportWhitelist == null) {
             mTransportWhitelist = Collections.emptySet();
         }
+
+        mContext.registerReceiver(mUserRemovedReceiver,
+                new IntentFilter(Intent.ACTION_USER_REMOVED));
+    }
+
+    /**
+     * Remove backup state for non system {@code userId} when the user is removed from the device.
+     * For non system users, backup state is stored in both the user's own dir and the system dir.
+     * When the user is removed, the user's own dir gets removed by the OS. This method ensures that
+     * the part of the user backup state which is in the system dir also gets removed.
+     */
+    private void onRemovedNonSystemUser(int userId) {
+        Slog.i(TAG, "Removing state for non system user " + userId);
+        File dir = UserBackupManagerFiles.getStateDirInSystemDir(userId);
+        if (!FileUtils.deleteContentsAndDir(dir)) {
+            Slog.w(TAG, "Failed to delete state dir for removed user: " + userId);
+        }
     }
 
     /**
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 8f0c5d8..a9b292b3 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -47,7 +47,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.DumpUtils;
-import com.android.server.backup.utils.FileUtils;
 import com.android.server.backup.utils.RandomAccessFileUtils;
 
 import java.io.File;
@@ -95,7 +94,7 @@
      * Name of file for non-system users that remembers whether backup was explicitly activated or
      * deactivated with a call to setBackupServiceActive.
      */
-    private static final String REMEMBER_ACTIVATED_FILENAME_PREFIX = "backup-remember-activated";
+    private static final String REMEMBER_ACTIVATED_FILENAME = "backup-remember-activated";
 
     // Product-level suppression of backup/restore.
     private static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable";
@@ -143,8 +142,7 @@
 
     /** Stored in the system user's directory and the file is indexed by the user it refers to. */
     protected File getRememberActivatedFileForNonSystemUser(int userId) {
-        return FileUtils.createNewFile(UserBackupManagerFiles.getStateFileInSystemDir(
-                REMEMBER_ACTIVATED_FILENAME_PREFIX, userId));
+        return UserBackupManagerFiles.getStateFileInSystemDir(REMEMBER_ACTIVATED_FILENAME, userId);
     }
 
     /** Stored in the system user's directory and the file is indexed by the user it refers to. */
@@ -336,8 +334,13 @@
         // action since we need to remember that a permissioned call was made irrespective of
         // whether the call changes the state or not.
         if (userId != UserHandle.USER_SYSTEM) {
-            RandomAccessFileUtils.writeBoolean(getRememberActivatedFileForNonSystemUser(userId),
-                    makeActive);
+            try {
+                File rememberFile = getRememberActivatedFileForNonSystemUser(userId);
+                createFile(rememberFile);
+                RandomAccessFileUtils.writeBoolean(rememberFile, makeActive);
+            } catch (IOException e) {
+                Slog.e(TAG, "Unable to persist backup service activity", e);
+            }
         }
 
         if (mGlobalDisable) {
@@ -395,7 +398,7 @@
     @Override
     public boolean isBackupServiceActive(int userId) {
         synchronized (mStateLock) {
-            return isUserReadyForBackup(userId);
+            return mService != null && isBackupActivatedForUser(userId);
         }
     }
 
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java
index 4638ac6..8e60542 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java
@@ -49,8 +49,13 @@
         return new File(Environment.getDownloadCacheDirectory(), BACKUP_STAGING_DIR);
     }
 
-    /** Stored in the system user's directory and the file is indexed by the user it refers to. */
-    static File getStateFileInSystemDir(String prefix, int userId) {
-        return new File(getBaseStateDir(UserHandle.USER_SYSTEM), prefix + "-" + userId);
+    /** A user specific dir within the system user's directory. */
+    static File getStateDirInSystemDir(int userId) {
+        return new File(getBaseStateDir(UserHandle.USER_SYSTEM), "" + userId);
+    }
+
+    /** Stored in a user specific dir within the system user's directory. */
+    static File getStateFileInSystemDir(String filename, int userId) {
+        return new File(getStateDirInSystemDir(userId), filename);
     }
 }
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 3865b27..a3e7d36 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -72,7 +72,9 @@
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.FgThread;
+import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.wm.ActivityTaskManagerInternal;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -84,6 +86,7 @@
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -161,6 +164,20 @@
     }
 
     @Override
+    public void onUnlockUser(int userHandle) {
+        Set<Association> associations = readAllAssociations(userHandle);
+        Set<String> companionAppPackages = new HashSet<>();
+        for (Association association : associations) {
+            companionAppPackages.add(association.companionAppPackage);
+        }
+        ActivityTaskManagerInternal atmInternal = LocalServices.getService(
+                ActivityTaskManagerInternal.class);
+        if (atmInternal != null) {
+            atmInternal.setCompanionAppPackages(userHandle, companionAppPackages);
+        }
+    }
+
+    @Override
     public void binderDied() {
         Handler.getMain().post(this::cleanup);
     }
@@ -519,6 +536,11 @@
             if (size(old) == size(associations)) return;
 
             Set<Association> finalAssociations = associations;
+            Set<String> companionAppPackages = new HashSet<>();
+            for (Association association : finalAssociations) {
+                companionAppPackages.add(association.companionAppPackage);
+            }
+
             file.write((out) -> {
                 XmlSerializer xml = Xml.newSerializer();
                 try {
@@ -542,6 +564,9 @@
                 }
 
             });
+            ActivityTaskManagerInternal atmInternal = LocalServices.getService(
+                    ActivityTaskManagerInternal.class);
+            atmInternal.setCompanionAppPackages(userId, companionAppPackages);
         }
     }
 
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index b2760e0..9b02c4e 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.MANAGE_CONTENT_CAPTURE;
 import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
+import static android.view.contentcapture.ContentCaptureHelper.toList;
 import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_FALSE;
 import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_OK;
 import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_SECURITY_EXCEPTION;
@@ -40,6 +41,7 @@
 import android.content.pm.UserInfo;
 import android.database.ContentObserver;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -50,9 +52,12 @@
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.service.contentcapture.ActivityEvent.ActivityEventType;
+import android.util.ArraySet;
 import android.util.LocalLog;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.SparseBooleanArray;
+import android.view.contentcapture.ContentCaptureCondition;
 import android.view.contentcapture.ContentCaptureHelper;
 import android.view.contentcapture.ContentCaptureManager;
 import android.view.contentcapture.IContentCaptureManager;
@@ -60,6 +65,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.infra.AbstractRemoteService;
+import com.android.internal.infra.GlobalWhitelistState;
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
@@ -117,10 +123,13 @@
     @GuardedBy("mLock") int mDevCfgLogHistorySize;
     @GuardedBy("mLock") int mDevCfgIdleUnbindTimeoutMs;
 
+    final GlobalContentCaptureOptions mGlobalContentCaptureOptions =
+            new GlobalContentCaptureOptions();
+
     public ContentCaptureManagerService(@NonNull Context context) {
         super(context, new FrameworkResourcesServiceNameResolver(context,
                 com.android.internal.R.string.config_defaultContentCaptureService),
-                UserManager.DISALLOW_CONTENT_CAPTURE, /* refreshServiceOnPackageUpdate=*/ false);
+                UserManager.DISALLOW_CONTENT_CAPTURE, /* refreshServiceOnPackageUpdate= */ false);
         DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                 ActivityThread.currentApplication().getMainExecutor(),
                 (namespace, key, value) -> onDeviceConfigChange(key, value));
@@ -136,12 +145,12 @@
             mRequestsHistory = null;
         }
 
-        // Sets which services are disabled by settings
         final UserManager um = getContext().getSystemService(UserManager.class);
         final List<UserInfo> users = um.getUsers();
         for (int i = 0; i < users.size(); i++) {
             final int userId = users.get(i).id;
             final boolean disabled = !isEnabledBySettings(userId);
+            // Sets which services are disabled by settings
             if (disabled) {
                 Slog.i(mTag, "user " + userId + " disabled by settings");
                 if (mDisabledBySettings == null) {
@@ -149,6 +158,10 @@
                 }
                 mDisabledBySettings.put(userId, true);
             }
+            // Sets the global options for the service.
+            mGlobalContentCaptureOptions.setServiceInfo(userId,
+                    mServiceNameResolver.getServiceName(userId),
+                    mServiceNameResolver.isTemporary(userId));
         }
     }
 
@@ -188,6 +201,14 @@
     }
 
     @Override // from AbstractMasterSystemService
+    protected void onServiceNameChanged(@UserIdInt int userId, @NonNull String serviceName,
+            boolean isTemporary) {
+        mGlobalContentCaptureOptions.setServiceInfo(userId, serviceName, isTemporary);
+
+        super.onServiceNameChanged(userId, serviceName, isTemporary);
+    }
+
+    @Override // from AbstractMasterSystemService
     protected void enforceCallingPermissionForManagement() {
         getContext().enforceCallingPermission(MANAGE_CONTENT_CAPTURE, mTag);
     }
@@ -429,23 +450,16 @@
     }
 
     @GuardedBy("mLock")
-    private boolean assertCalledByServiceLocked(@NonNull String methodName, @UserIdInt int userId,
-            int callingUid, @NonNull IResultReceiver result) {
-        final boolean isService = isCalledByServiceLocked(methodName, userId, callingUid);
-        if (isService) return true;
-
-        try {
-            result.send(RESULT_CODE_SECURITY_EXCEPTION, /* resultData= */ null);
-        } catch (RemoteException e) {
-            Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e);
+    private void assertCalledByServiceLocked(@NonNull String methodName) {
+        if (!isCalledByServiceLocked(methodName)) {
+            throw new SecurityException("caller is not user's ContentCapture service");
         }
-        return false;
     }
 
     @GuardedBy("mLock")
-    private boolean isCalledByServiceLocked(@NonNull String methodName, @UserIdInt int userId,
-            int callingUid) {
-
+    private boolean isCalledByServiceLocked(@NonNull String methodName) {
+        final int userId = UserHandle.getCallingUserId();
+        final int callingUid = Binder.getCallingUid();
         final String serviceName = mServiceNameResolver.getServiceName(userId);
         if (serviceName == null) {
             Slog.e(mTag, methodName + ": called by UID " + callingUid
@@ -453,7 +467,7 @@
             return false;
         }
 
-        final ComponentName serviceComponent  = ComponentName.unflattenFromString(serviceName);
+        final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName);
         if (serviceComponent == null) {
             Slog.w(mTag, methodName + ": invalid service name: " + serviceName);
             return false;
@@ -478,6 +492,27 @@
         return true;
     }
 
+    /**
+     * Executes the given {@code runnable} and if it throws a {@link SecurityException},
+     * send it back to the receiver.
+     *
+     * @return whether the exception was thrown or not.
+     */
+    private boolean throwsSecurityException(@NonNull IResultReceiver result,
+            @NonNull Runnable runable) {
+        try {
+            runable.run();
+            return false;
+        } catch (SecurityException e) {
+            try {
+                result.send(RESULT_CODE_SECURITY_EXCEPTION, bundleFor(e.getMessage()));
+            } catch (RemoteException e2) {
+                Slog.w(mTag, "Unable to send security exception (" + e + "): ", e2);
+            }
+        }
+        return true;
+    }
+
     @Override // from AbstractMasterSystemService
     protected void dumpLocked(String prefix, PrintWriter pw) {
         super.dumpLocked(prefix, pw);
@@ -496,13 +531,15 @@
         pw.print(prefix2); pw.print("logHistorySize: "); pw.println(mDevCfgLogHistorySize);
         pw.print(prefix2); pw.print("idleUnbindTimeoutMs: ");
         pw.println(mDevCfgIdleUnbindTimeoutMs);
+        pw.print(prefix); pw.println("Global Options:");
+        mGlobalContentCaptureOptions.dump(prefix2, pw);
     }
 
     final class ContentCaptureManagerServiceStub extends IContentCaptureManager.Stub {
 
         @Override
         public void startSession(@NonNull IBinder activityToken,
-                @NonNull ComponentName componentName, @NonNull String sessionId, int flags,
+                @NonNull ComponentName componentName, int sessionId, int flags,
                 @NonNull IResultReceiver result) {
             Preconditions.checkNotNull(activityToken);
             Preconditions.checkNotNull(sessionId);
@@ -519,7 +556,7 @@
         }
 
         @Override
-        public void finishSession(@NonNull String sessionId) {
+        public void finishSession(int sessionId) {
             Preconditions.checkNotNull(sessionId);
             final int userId = UserHandle.getCallingUserId();
 
@@ -547,6 +584,8 @@
         @Override
         public void removeUserData(@NonNull UserDataRemovalRequest request) {
             Preconditions.checkNotNull(request);
+            assertCalledByPackageOwner(request.getPackageName());
+
             final int userId = UserHandle.getCallingUserId();
             synchronized (mLock) {
                 final ContentCapturePerUserService service = getServiceForUserLocked(userId);
@@ -556,13 +595,14 @@
 
         @Override
         public void isContentCaptureFeatureEnabled(@NonNull IResultReceiver result) {
-            final int userId = UserHandle.getCallingUserId();
             boolean enabled;
             synchronized (mLock) {
-                final boolean isService = assertCalledByServiceLocked(
-                        "isContentCaptureFeatureEnabled()", userId, Binder.getCallingUid(), result);
-                if (!isService) return;
+                if (throwsSecurityException(result,
+                        () -> assertCalledByServiceLocked("isContentCaptureFeatureEnabled()"))) {
+                    return;
+                }
 
+                final int userId = UserHandle.getCallingUserId();
                 enabled = !mDisabledByDeviceConfig && !isDisabledBySettingsLocked(userId);
             }
             try {
@@ -574,15 +614,8 @@
 
         @Override
         public void getServiceSettingsActivity(@NonNull IResultReceiver result) {
-            try {
-                enforceCallingPermissionForManagement();
-            } catch (SecurityException e) {
-                try {
-                    result.send(RESULT_CODE_SECURITY_EXCEPTION, bundleFor(e.getMessage()));
-                } catch (RemoteException e2) {
-                    Slog.w(mTag, "Unable to send getServiceSettingsIntent() exception: " + e2);
-                    return;
-                }
+            if (throwsSecurityException(result, () -> enforceCallingPermissionForManagement())) {
+                return;
             }
 
             final int userId = UserHandle.getCallingUserId();
@@ -600,13 +633,34 @@
         }
 
         @Override
+        public void getContentCaptureConditions(@NonNull String packageName,
+                @NonNull IResultReceiver result) {
+            if (throwsSecurityException(result, () -> assertCalledByPackageOwner(packageName))) {
+                return;
+            }
+
+            final int userId = UserHandle.getCallingUserId();
+            final ArrayList<ContentCaptureCondition> conditions;
+            synchronized (mLock) {
+                final ContentCapturePerUserService service = getServiceForUserLocked(userId);
+                conditions = service == null ? null
+                        : toList(service.getContentCaptureConditionsLocked(packageName));
+            }
+            try {
+                result.send(RESULT_CODE_OK, bundleFor(conditions));
+            } catch (RemoteException e) {
+                Slog.w(mTag, "Unable to send getServiceComponentName(): " + e);
+            }
+        }
+
+        @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(getContext(), mTag, pw)) return;
 
             boolean showHistory = true;
             if (args != null) {
                 for (String arg : args) {
-                    switch(arg) {
+                    switch (arg) {
                         case "--no-history":
                             showHistory = false;
                             break;
@@ -670,13 +724,7 @@
 
         @Override
         public ContentCaptureOptions getOptionsForPackage(int userId, @NonNull String packageName) {
-            synchronized (mLock) {
-                final ContentCapturePerUserService service = peekServiceForUserLocked(userId);
-                if (service != null) {
-                    return service.getOptionsForPackageLocked(packageName);
-                }
-            }
-            return null;
+            return mGlobalContentCaptureOptions.getOptions(userId, packageName);
         }
 
         @Override
@@ -690,4 +738,92 @@
             }
         }
     }
+
+    /**
+     * Content capture options associated with all services.
+     *
+     * <p>This object is defined here instead of on each {@link ContentCapturePerUserService}
+     * because it cannot hold a lock on the main lock when
+     * {@link GlobalContentCaptureOptions#getOptions(int, String)} is called by external services.
+     */
+    final class GlobalContentCaptureOptions extends GlobalWhitelistState {
+
+        @GuardedBy("mGlobalWhitelistStateLock")
+        private final SparseArray<String> mServicePackages = new SparseArray<>();
+        @GuardedBy("mGlobalWhitelistStateLock")
+        private final SparseBooleanArray mTemporaryServices = new SparseBooleanArray();
+
+        private void setServiceInfo(@UserIdInt int userId, @Nullable String serviceName,
+                boolean isTemporary) {
+            synchronized (mGlobalWhitelistStateLock) {
+                if (isTemporary) {
+                    mTemporaryServices.put(userId, true);
+                } else {
+                    mTemporaryServices.delete(userId);
+                }
+                if (serviceName != null) {
+                    final ComponentName componentName =
+                            ComponentName.unflattenFromString(serviceName);
+                    if (componentName == null) {
+                        Slog.w(mTag, "setServiceInfo(): invalid name: " + serviceName);
+                        mServicePackages.remove(userId);
+                    } else {
+                        mServicePackages.put(userId, componentName.getPackageName());
+                    }
+                } else {
+                    mServicePackages.remove(userId);
+                }
+            }
+        }
+
+        @Nullable
+        @GuardedBy("mGlobalWhitelistStateLock")
+        public ContentCaptureOptions getOptions(@UserIdInt int userId,
+                @NonNull String packageName) {
+            synchronized (mGlobalWhitelistStateLock) {
+                if (!isWhitelisted(userId, packageName)) {
+                    if (packageName.equals(mServicePackages.get(userId))) {
+                        if (verbose) Slog.v(mTag, "getOptionsForPackage() lite for " + packageName);
+                        return new ContentCaptureOptions(mDevCfgLoggingLevel);
+                    }
+                    if (verbose) {
+                        Slog.v(mTag, "getOptionsForPackage(" + packageName + "): not whitelisted");
+                    }
+                    return null;
+                }
+
+                final ArraySet<ComponentName> whitelistedComponents =
+                        getWhitelistedComponents(userId, packageName);
+                if (Build.IS_USER && mServiceNameResolver.isTemporary(userId)) {
+                    if (!packageName.equals(mServicePackages.get(userId))) {
+                        Slog.w(mTag, "Ignoring package " + packageName
+                                + " while using temporary service " + mServicePackages.get(userId));
+                        return null;
+                    }
+                }
+                final ContentCaptureOptions options = new ContentCaptureOptions(mDevCfgLoggingLevel,
+                        mDevCfgMaxBufferSize, mDevCfgIdleFlushingFrequencyMs,
+                        mDevCfgTextChangeFlushingFrequencyMs, mDevCfgLogHistorySize,
+                        whitelistedComponents);
+                if (verbose) {
+                    Slog.v(mTag, "getOptionsForPackage(" + packageName + "): " + options);
+                }
+                return options;
+            }
+        }
+
+        @Override
+        public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+            super.dump(prefix, pw);
+
+            synchronized (mGlobalWhitelistStateLock) {
+                if (mServicePackages.size() > 0) {
+                    pw.print(prefix); pw.print("Service packages: "); pw.println(mServicePackages);
+                }
+                if (mTemporaryServices.size() > 0) {
+                    pw.print(prefix); pw.print("Temp services: "); pw.println(mTemporaryServices);
+                }
+            }
+        }
+    }
 }
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index d909736..5649526 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -17,6 +17,7 @@
 package com.android.server.contentcapture;
 
 import static android.service.contentcapture.ContentCaptureService.setClientState;
+import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID;
 import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED;
 import static android.view.contentcapture.ContentCaptureSession.STATE_DUPLICATED_ID;
 import static android.view.contentcapture.ContentCaptureSession.STATE_INTERNAL_ERROR;
@@ -54,6 +55,8 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
+import android.util.SparseArray;
+import android.view.contentcapture.ContentCaptureCondition;
 import android.view.contentcapture.UserDataRemovalRequest;
 
 import com.android.internal.annotations.GuardedBy;
@@ -78,8 +81,7 @@
     private static final String TAG = ContentCapturePerUserService.class.getSimpleName();
 
     @GuardedBy("mLock")
-    private final ArrayMap<String, ContentCaptureServerSession> mSessions =
-            new ArrayMap<>();
+    private final SparseArray<ContentCaptureServerSession> mSessions = new SparseArray<>();
 
     /**
      * Reference to the remote service.
@@ -101,6 +103,13 @@
     private final WhitelistHelper mWhitelistHelper = new WhitelistHelper();
 
     /**
+     * List of conditions keyed by package.
+     */
+    @GuardedBy("mLock")
+    private final ArrayMap<String, ArraySet<ContentCaptureCondition>> mConditionsByPkg =
+            new ArrayMap<>();
+
+    /**
      * When {@code true}, remote service died but service state is kept so it's restored after
      * the system re-binds to it.
      */
@@ -126,6 +135,7 @@
             if (mMaster.debug) Slog.d(TAG, "updateRemoteService(): destroying old remote service");
             mRemoteService.destroy();
             mRemoteService = null;
+            resetContentCaptureWhitelistLocked();
         }
 
         // Updates the component name
@@ -225,9 +235,8 @@
     // TODO(b/119613670): log metrics
     @GuardedBy("mLock")
     public void startSessionLocked(@NonNull IBinder activityToken,
-            @NonNull ActivityPresentationInfo activityPresentationInfo,
-            @NonNull String sessionId, int uid, int flags,
-            @NonNull IResultReceiver clientReceiver) {
+            @NonNull ActivityPresentationInfo activityPresentationInfo, int sessionId, int uid,
+            int flags, @NonNull IResultReceiver clientReceiver) {
         if (activityPresentationInfo == null) {
             Slog.w(TAG, "basic activity info is null");
             setClientState(clientReceiver, STATE_DISABLED | STATE_INTERNAL_ERROR,
@@ -237,7 +246,8 @@
         final int taskId = activityPresentationInfo.taskId;
         final int displayId = activityPresentationInfo.displayId;
         final ComponentName componentName = activityPresentationInfo.componentName;
-        final boolean whiteListed = isWhitelistedLocked(componentName);
+        final boolean whiteListed = mMaster.mGlobalContentCaptureOptions.isWhitelisted(mUserId,
+                componentName);
         final ComponentName serviceComponentName = getServiceComponentName();
         final boolean enabled = isEnabledLocked();
         if (mMaster.mRequestsHistory != null) {
@@ -314,14 +324,9 @@
         newSession.notifySessionStartedLocked(clientReceiver);
     }
 
-    @GuardedBy("mLock")
-    private boolean isWhitelistedLocked(@NonNull ComponentName componentName) {
-        return mWhitelistHelper.isWhitelisted(componentName);
-    }
-
     // TODO(b/119613670): log metrics
     @GuardedBy("mLock")
-    public void finishSessionLocked(@NonNull String sessionId) {
+    public void finishSessionLocked(int sessionId) {
         if (!isEnabledLocked()) {
             return;
         }
@@ -385,8 +390,8 @@
     @GuardedBy("mLock")
     public boolean sendActivityAssistDataLocked(@NonNull IBinder activityToken,
             @NonNull Bundle data) {
-        final String id = getSessionId(activityToken);
-        if (id != null) {
+        final int id = getSessionId(activityToken);
+        if (id != NO_SESSION_ID) {
             final ContentCaptureServerSession session = mSessions.get(id);
             final Bundle assistData = data.getBundle(ASSIST_KEY_DATA);
             final AssistStructure assistStructure = data.getParcelable(ASSIST_KEY_STRUCTURE);
@@ -402,7 +407,7 @@
     }
 
     @GuardedBy("mLock")
-    public void removeSessionLocked(@NonNull String sessionId) {
+    public void removeSessionLocked(int sessionId) {
         mSessions.remove(sessionId);
     }
 
@@ -479,7 +484,7 @@
                 return null;
             }
         }
-        ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel,
+        final ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel,
                 mMaster.mDevCfgMaxBufferSize, mMaster.mDevCfgIdleFlushingFrequencyMs,
                 mMaster.mDevCfgTextChangeFlushingFrequencyMs, mMaster.mDevCfgLogHistorySize,
                 whitelistedComponents);
@@ -490,6 +495,13 @@
     }
 
     @GuardedBy("mLock")
+    @Nullable
+    ArraySet<ContentCaptureCondition> getContentCaptureConditionsLocked(
+            @NonNull String packageName) {
+        return mConditionsByPkg.get(packageName);
+    }
+
+    @GuardedBy("mLock")
     void onActivityEventLocked(@NonNull ComponentName componentName, @ActivityEventType int type) {
         if (mRemoteService == null) {
             if (mMaster.debug) Slog.d(mTag, "onActivityEvent(): no remote service");
@@ -521,9 +533,7 @@
             mRemoteService.dump(prefix2, pw);
         }
 
-        mWhitelistHelper.dump(prefix, "Whitelist", pw);
-
-        if (mSessions.isEmpty()) {
+        if (mSessions.size() == 0) {
             pw.print(prefix); pw.println("no sessions");
         } else {
             final int sessionsSize = mSessions.size();
@@ -541,14 +551,25 @@
      * Returns the session id associated with the given activity.
      */
     @GuardedBy("mLock")
-    private String getSessionId(@NonNull IBinder activityToken) {
+    private int getSessionId(@NonNull IBinder activityToken) {
         for (int i = 0; i < mSessions.size(); i++) {
             ContentCaptureServerSession session = mSessions.valueAt(i);
             if (session.isActivitySession(activityToken)) {
                 return mSessions.keyAt(i);
             }
         }
-        return null;
+        return NO_SESSION_ID;
+    }
+
+    /**
+     * Resets the content capture whitelist.
+     */
+    @GuardedBy("mLock")
+    private void resetContentCaptureWhitelistLocked() {
+        if (mMaster.verbose) {
+            Slog.v(TAG, "resetting content capture whitelist");
+        }
+        mMaster.mGlobalContentCaptureOptions.resetWhitelist(mUserId);
     }
 
     private final class ContentCaptureServiceRemoteCallback extends
@@ -564,8 +585,22 @@
                         + ", " + (activities == null
                         ? "null_activities" : activities.size() + " activities") + ")");
             }
+            mMaster.mGlobalContentCaptureOptions.setWhitelist(mUserId, packages, activities);
+        }
+
+        @Override
+        public void setContentCaptureConditions(String packageName,
+                List<ContentCaptureCondition> conditions) {
+            if (mMaster.verbose) {
+                Slog.v(TAG, "setContentCaptureConditions(" + packageName + "): "
+                        + (conditions == null ? "null" : conditions.size() + " conditions"));
+            }
             synchronized (mLock) {
-                mWhitelistHelper.setWhitelist(packages, activities);
+                if (conditions == null) {
+                    mConditionsByPkg.remove(packageName);
+                } else {
+                    mConditionsByPkg.put(packageName, new ArraySet<>(conditions));
+                }
             }
             // TODO(b/119613670): log metrics
         }
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
index 9b2c05f..1ad66d8 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
@@ -16,6 +16,7 @@
 package com.android.server.contentcapture;
 
 import static android.service.contentcapture.ContentCaptureService.setClientState;
+import static android.view.contentcapture.ContentCaptureSession.NO_SESSION_ID;
 import static android.view.contentcapture.ContentCaptureSession.STATE_ACTIVE;
 import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED;
 import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_RESURRECTED;
@@ -57,7 +58,7 @@
     /**
      * Canonical session id.
      */
-    private final String mId;
+    private final int mId;
 
     /**
      * UID of the app whose contents is being captured.
@@ -66,11 +67,12 @@
 
     ContentCaptureServerSession(@NonNull IBinder activityToken,
             @NonNull ContentCapturePerUserService service, @NonNull ComponentName appComponentName,
-            @NonNull IResultReceiver sessionStateReceiver,
-            int taskId, int displayId, @NonNull String sessionId, int uid, int flags) {
+            @NonNull IResultReceiver sessionStateReceiver, int taskId, int displayId, int sessionId,
+            int uid, int flags) {
+        Preconditions.checkArgument(sessionId != NO_SESSION_ID);
         mActivityToken = activityToken;
         mService = service;
-        mId = Preconditions.checkNotNull(sessionId);
+        mId = sessionId;
         mUid = uid;
         mContentCaptureContext = new ContentCaptureContext(/* clientContext= */ null,
                 appComponentName, taskId, displayId, flags);
diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
index df9ccbc..3fa3fdf 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
@@ -47,7 +47,8 @@
             ContentCapturePerUserService perUserService, boolean bindInstantServiceAllowed,
             boolean verbose, int idleUnbindTimeoutMs) {
         super(context, serviceInterface, serviceComponentName, userId, perUserService,
-                context.getMainThreadHandler(), bindInstantServiceAllowed, verbose,
+                context.getMainThreadHandler(),
+                bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0, verbose,
                 /* initialCapacity= */ 2);
         mPerUserService = perUserService;
         mServerCallback = callback.asBinder();
@@ -97,9 +98,8 @@
      * Called by {@link ContentCaptureServerSession} to generate a call to the
      * {@link RemoteContentCaptureService} to indicate the session was created.
      */
-    public void onSessionStarted(@Nullable ContentCaptureContext context,
-            @NonNull String sessionId, int uid, @NonNull IResultReceiver clientReceiver,
-            int initialState) {
+    public void onSessionStarted(@Nullable ContentCaptureContext context, int sessionId, int uid,
+            @NonNull IResultReceiver clientReceiver, int initialState) {
         scheduleAsyncRequest(
                 (s) -> s.onSessionStarted(context, sessionId, uid, clientReceiver, initialState));
     }
@@ -108,15 +108,14 @@
      * Called by {@link ContentCaptureServerSession} to generate a call to the
      * {@link RemoteContentCaptureService} to indicate the session was finished.
      */
-    public void onSessionFinished(@NonNull String sessionId) {
+    public void onSessionFinished(int sessionId) {
         scheduleAsyncRequest((s) -> s.onSessionFinished(sessionId));
     }
 
     /**
      * Called by {@link ContentCaptureServerSession} to send snapshot data to the service.
      */
-    public void onActivitySnapshotRequest(@NonNull String sessionId,
-            @NonNull SnapshotData snapshotData) {
+    public void onActivitySnapshotRequest(int sessionId, @NonNull SnapshotData snapshotData) {
         scheduleAsyncRequest((s) -> s.onActivitySnapshot(sessionId, snapshotData));
     }
 
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java
index 442972a..4b36352 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java
@@ -47,7 +47,8 @@
             int userId, Callbacks callbacks,
             boolean bindInstantServiceAllowed, boolean verbose) {
         super(context, ContentSuggestionsService.SERVICE_INTERFACE, serviceName, userId, callbacks,
-                context.getMainThreadHandler(), bindInstantServiceAllowed, verbose,
+                context.getMainThreadHandler(),
+                bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0, verbose,
                 /* initialCapacity= */ 1);
     }
 
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 259aa50..9e1b3b8 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -21,6 +21,7 @@
         ":gsiservice_aidl",
         "java/com/android/server/EventLogTags.logtags",
         "java/com/android/server/am/EventLogTags.logtags",
+        "java/com/android/server/policy/EventLogTags.logtags",
     ],
 
     libs: [
@@ -50,6 +51,7 @@
         "android.hardware.configstore-V1.0-java",
         "android.hardware.contexthub-V1.0-java",
         "android.hidl.manager-V1.2-java",
+        "dnsresolver_aidl_interface-java",
         "netd_aidl_interface-java",
         "netd_event_listener_interface-java",
     ],
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 3d918fc..0f39029 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -3825,6 +3825,7 @@
                 Slog.w(TAG, "Failure sending alarm.", e);
             }
             Trace.traceEnd(Trace.TRACE_TAG_POWER);
+            decrementAlarmCount(alarm.uid);
         }
     }
 
@@ -4148,6 +4149,10 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case ALARM_EVENT: {
+                    // This code is used when the kernel timer driver is not available, which
+                    // shouldn't happen. Here, we try our best to simulate it, which may be useful
+                    // when porting Android to a new device. Note that we can't wake up a device
+                    // this way, so WAKE_UP alarms will be delivered only when the device is awake.
                     ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
                     synchronized (mLock) {
                         final long nowELAPSED = mInjector.getElapsedRealtime();
@@ -4167,6 +4172,7 @@
                                 removeImpl(alarm.operation, null);
                             }
                         }
+                        decrementAlarmCount(alarm.uid);
                     }
                     break;
                 }
@@ -4760,7 +4766,6 @@
                 mAppWakeupHistory.recordAlarmForPackage(alarm.sourcePackage,
                         UserHandle.getUserId(alarm.creatorUid), nowELAPSED);
             }
-            decrementAlarmCount(alarm.uid);
             final BroadcastStats bs = inflight.mBroadcastStats;
             bs.count++;
             if (bs.nesting == 0) {
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 39f7f0f..6a9f5b6 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -357,10 +357,27 @@
                 && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);
     }
 
+    private boolean shouldShutdownLocked() {
+        if (mHealthInfo.batteryLevel > 0) {
+            return false;
+        }
+
+        // Battery-less devices should not shutdown.
+        if (!mHealthInfo.batteryPresent) {
+            return false;
+        }
+
+        // If battery state is not CHARGING, shutdown.
+        // - If battery present and state == unknown, this is an unexpected error state.
+        // - If level <= 0 and state == full, this is also an unexpected state
+        // - All other states (NOT_CHARGING, DISCHARGING) means it is not charging.
+        return mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_CHARGING;
+    }
+
     private void shutdownIfNoPowerLocked() {
         // shut down gracefully if our battery is critically low and we are not powered.
         // wait until the system has booted before attempting to display the shutdown dialog.
-        if (mHealthInfo.batteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)) {
+        if (shouldShutdownLocked()) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2be92cd..6405254 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -63,6 +63,7 @@
 import android.net.ConnectivityManager;
 import android.net.ICaptivePortal;
 import android.net.IConnectivityManager;
+import android.net.IDnsResolver;
 import android.net.IIpConnectivityMetrics;
 import android.net.INetd;
 import android.net.INetdEventCallback;
@@ -294,6 +295,8 @@
 
     private INetworkManagementService mNMS;
     @VisibleForTesting
+    protected IDnsResolver mDnsResolver;
+    @VisibleForTesting
     protected INetd mNetd;
     private INetworkStatsService mStatsService;
     private INetworkPolicyManager mPolicyManager;
@@ -525,6 +528,11 @@
         return sMagicDecoderRing.get(what, Integer.toString(what));
     }
 
+    private static IDnsResolver getDnsResolver() {
+        return IDnsResolver.Stub
+                .asInterface(ServiceManager.getService("dnsresolver"));
+    }
+
     /** Handler thread used for both of the handlers below. */
     @VisibleForTesting
     protected final HandlerThread mHandlerThread;
@@ -810,13 +818,14 @@
 
     public ConnectivityService(Context context, INetworkManagementService netManager,
             INetworkStatsService statsService, INetworkPolicyManager policyManager) {
-        this(context, netManager, statsService, policyManager, new IpConnectivityLog());
+        this(context, netManager, statsService, policyManager,
+            getDnsResolver(), new IpConnectivityLog());
     }
 
     @VisibleForTesting
     protected ConnectivityService(Context context, INetworkManagementService netManager,
             INetworkStatsService statsService, INetworkPolicyManager policyManager,
-            IpConnectivityLog logger) {
+            IDnsResolver dnsresolver, IpConnectivityLog logger) {
         if (DBG) log("ConnectivityService starting up");
 
         mSystemProperties = getSystemProperties();
@@ -853,6 +862,7 @@
         mPolicyManagerInternal = checkNotNull(
                 LocalServices.getService(NetworkPolicyManagerInternal.class),
                 "missing NetworkPolicyManagerInternal");
+        mDnsResolver = checkNotNull(dnsresolver, "missing IDnsResolver");
         mProxyTracker = makeProxyTracker();
 
         mNetd = NetdService.getInstance();
@@ -941,7 +951,7 @@
 
         mTethering = makeTethering();
 
-        mPermissionMonitor = new PermissionMonitor(mContext, mNMS);
+        mPermissionMonitor = new PermissionMonitor(mContext, mNMS, mNetd);
 
         // Set up the listener for user state for creating user VPNs.
         // Should run on mHandler to avoid any races.
@@ -1006,7 +1016,7 @@
 
         mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
 
-        mDnsManager = new DnsManager(mContext, mNMS, mSystemProperties);
+        mDnsManager = new DnsManager(mContext, mDnsResolver, mSystemProperties);
         registerPrivateDnsSettingsCallbacks();
     }
 
@@ -1882,6 +1892,15 @@
         return false;
     }
 
+    private boolean checkAnyPermissionOf(int pid, int uid, String... permissions) {
+        for (String permission : permissions) {
+            if (mContext.checkPermission(permission, pid, uid) == PERMISSION_GRANTED) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void enforceAnyPermissionOf(String... permissions) {
         if (!checkAnyPermissionOf(permissions)) {
             throw new SecurityException("Requires one of the following permissions: "
@@ -1956,6 +1975,12 @@
                 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
     }
 
+    private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) {
+        return checkAnyPermissionOf(pid, uid,
+                android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP,
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+    }
+
     private void enforceConnectivityRestrictedNetworksPermission() {
         try {
             mContext.enforceCallingOrSelfPermission(
@@ -3021,9 +3046,9 @@
             // NetworkFactories, so network traffic isn't interrupted for an unnecessarily
             // long time.
             try {
-                mNMS.removeNetwork(nai.network.netId);
-            } catch (Exception e) {
-                loge("Exception removing network: " + e);
+                mNetd.networkDestroy(nai.network.netId);
+            } catch (RemoteException | ServiceSpecificException e) {
+                loge("Exception destroying network: " + e);
             }
             mDnsManager.removeNetwork(nai.network);
         }
@@ -3728,16 +3753,6 @@
                     break;
                 }
                 case EVENT_SYSTEM_READY: {
-                    for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
-                        // Might have been called already in handleRegisterNetworkAgent since
-                        // mSystemReady is set before sending EVENT_SYSTEM_READY, but calling
-                        // this several times is fine.
-                        try {
-                            nai.networkMonitor().notifySystemReady();
-                        } catch (RemoteException e) {
-                            e.rethrowFromSystemServer();
-                        }
-                    }
                     mMultipathPolicyTracker.start();
                     break;
                 }
@@ -4952,13 +4967,19 @@
         }
     }
 
-    // This checks that the passed capabilities either do not request a specific SSID, or the
-    // calling app has permission to do so.
+    // This checks that the passed capabilities either do not request a specific SSID/SignalStrength
+    // , or the calling app has permission to do so.
     private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
             int callerPid, int callerUid) {
         if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) {
             throw new SecurityException("Insufficient permissions to request a specific SSID");
         }
+
+        if (nc.hasSignalStrength()
+                && !checkNetworkSignalStrengthWakeupPermission(callerPid, callerUid)) {
+            throw new SecurityException(
+                    "Insufficient permissions to request a specific signal strength");
+        }
     }
 
     private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) {
@@ -5372,10 +5393,10 @@
         final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
         final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
                 new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
-                mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mNMS,
-                factorySerialNumber);
+                mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mDnsResolver,
+                mNMS, factorySerialNumber);
         // Make sure the network capabilities reflect what the agent info says.
-        nai.networkCapabilities = mixInCapabilities(nai, nc);
+        nai.setNetworkCapabilities(mixInCapabilities(nai, nc));
         final String extraInfo = networkInfo.getExtraInfo();
         final String name = TextUtils.isEmpty(extraInfo)
                 ? nai.networkCapabilities.getSSID() : extraInfo;
@@ -5406,15 +5427,6 @@
         synchronized (mNetworkForNetId) {
             mNetworkForNetId.put(nai.network.netId, nai);
         }
-        synchronized (this) {
-            if (mSystemReady) {
-                try {
-                    networkMonitor.notifySystemReady();
-                } catch (RemoteException e) {
-                    e.rethrowFromSystemServer();
-                }
-            }
-        }
 
         try {
             networkMonitor.start();
@@ -5468,12 +5480,12 @@
             // Start or stop DNS64 detection and 464xlat according to network state.
             networkAgent.clatd.update();
             notifyIfacesChangedForNetworkStats();
+            try {
+                networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
+            } catch (RemoteException e) {
+                e.rethrowFromSystemServer();
+            }
             if (networkAgent.everConnected) {
-                try {
-                    networkAgent.networkMonitor().notifyLinkPropertiesChanged();
-                } catch (RemoteException e) {
-                    e.rethrowFromSystemServer();
-                }
                 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
             }
         }
@@ -5701,7 +5713,7 @@
         final NetworkCapabilities prevNc;
         synchronized (nai) {
             prevNc = nai.networkCapabilities;
-            nai.networkCapabilities = newNc;
+            nai.setNetworkCapabilities(newNc);
         }
 
         updateUids(nai, prevNc, newNc);
@@ -5716,11 +5728,6 @@
             // If the requestable capabilities have changed or the score changed, we can't have been
             // called by rematchNetworkAndRequests, so it's safe to start a rematch.
             rematchAllNetworksAndRequests(nai, oldScore);
-            try {
-                nai.networkMonitor().notifyNetworkCapabilitiesChanged();
-            } catch (RemoteException e) {
-                e.rethrowFromSystemServer();
-            }
             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
         }
 
@@ -5979,11 +5986,6 @@
         }
 
         if (capabilitiesChanged) {
-            try {
-                nai.networkMonitor().notifyNetworkCapabilitiesChanged();
-            } catch (RemoteException e) {
-                e.rethrowFromSystemServer();
-            }
             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
         }
 
@@ -6380,6 +6382,11 @@
                 Slog.wtf(TAG, networkAgent.name() + " connected with null LinkProperties");
             }
 
+            // NetworkCapabilities need to be set before sending the private DNS config to
+            // NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
+            synchronized (networkAgent) {
+                networkAgent.setNetworkCapabilities(networkAgent.networkCapabilities);
+            }
             handlePerNetworkPrivateDnsConfig(networkAgent, mDnsManager.getPrivateDnsConfig());
             updateLinkProperties(networkAgent, new LinkProperties(networkAgent.linkProperties),
                     null);
@@ -6392,7 +6399,8 @@
                 if (networkAgent.networkMisc.acceptPartialConnectivity) {
                     networkAgent.networkMonitor().setAcceptPartialConnectivity();
                 }
-                networkAgent.networkMonitor().notifyNetworkConnected();
+                networkAgent.networkMonitor().notifyNetworkConnected(
+                        networkAgent.linkProperties, networkAgent.networkCapabilities);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index b393d87..33b846f 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Binder;
@@ -32,6 +33,9 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
 import android.os.StatFs;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -39,8 +43,11 @@
 import android.text.TextUtils;
 import android.text.format.Time;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Slog;
 
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.IDropBoxManagerService;
 import com.android.internal.util.DumpUtils;
@@ -76,9 +83,6 @@
     private static final int DEFAULT_RESERVE_PERCENT = 10;
     private static final int QUOTA_RESCAN_MILLIS = 5000;
 
-    // mHandler 'what' value.
-    private static final int MSG_SEND_BROADCAST = 1;
-
     private static final boolean PROFILE_DUMP = false;
 
     // TODO: This implementation currently uses one file per entry, which is
@@ -95,6 +99,9 @@
     private FileList mAllFiles = null;
     private ArrayMap<String, FileList> mFilesByTag = null;
 
+    private long mLowPriorityRateLimitPeriod = 0;
+    private ArraySet<String> mLowPriorityTags = null;
+
     // Various bits of disk information
 
     private StatFs mStatFs = null;
@@ -105,7 +112,7 @@
     private volatile boolean mBooted = false;
 
     // Provide a way to perform sendBroadcast asynchronously to avoid deadlocks.
-    private final Handler mHandler;
+    private final DropBoxManagerBroadcastHandler mHandler;
 
     private int mMaxFiles = -1; // -1 means uninitialized.
 
@@ -152,8 +159,142 @@
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             DropBoxManagerService.this.dump(fd, pw, args);
         }
+
+        @Override
+        public void onShellCommand(FileDescriptor in, FileDescriptor out,
+                                   FileDescriptor err, String[] args, ShellCallback callback,
+                                   ResultReceiver resultReceiver) {
+            (new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver);
+        }
     };
 
+    private class ShellCmd extends ShellCommand {
+        @Override
+        public int onCommand(String cmd) {
+            if (cmd == null) {
+                return handleDefaultCommands(cmd);
+            }
+            final PrintWriter pw = getOutPrintWriter();
+            try {
+                switch (cmd) {
+                    case "set-rate-limit":
+                        final long period = Long.parseLong(getNextArgRequired());
+                        DropBoxManagerService.this.setLowPriorityRateLimit(period);
+                        break;
+                    case "add-low-priority":
+                        final String addedTag = getNextArgRequired();
+                        DropBoxManagerService.this.addLowPriorityTag(addedTag);
+                        break;
+                    case "remove-low-priority":
+                        final String removeTag = getNextArgRequired();
+                        DropBoxManagerService.this.removeLowPriorityTag(removeTag);
+                        break;
+                    case "restore-defaults":
+                        DropBoxManagerService.this.restoreDefaults();
+                        break;
+                    default:
+                        return handleDefaultCommands(cmd);
+                }
+            } catch (Exception e) {
+                pw.println(e);
+            }
+            return 0;
+        }
+
+        @Override
+        public void onHelp() {
+            PrintWriter pw = getOutPrintWriter();
+            pw.println("Dropbox manager service commands:");
+            pw.println("  help");
+            pw.println("    Print this help text.");
+            pw.println("  set-rate-limit PERIOD");
+            pw.println("    Sets low priority broadcast rate limit period to PERIOD ms");
+            pw.println("  add-low-priority TAG");
+            pw.println("    Add TAG to dropbox low priority list");
+            pw.println("  remove-low-priority TAG");
+            pw.println("    Remove TAG from dropbox low priority list");
+            pw.println("  restore-defaults");
+            pw.println("    restore dropbox settings to defaults");
+        }
+    }
+
+    private class DropBoxManagerBroadcastHandler extends Handler {
+        private final Object mLock = new Object();
+
+        static final int MSG_SEND_BROADCAST = 1;
+        static final int MSG_SEND_DEFERRED_BROADCAST = 2;
+
+        @GuardedBy("mLock")
+        private final ArrayMap<String, Intent> mDeferredMap = new ArrayMap();
+
+        DropBoxManagerBroadcastHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_SEND_BROADCAST:
+                    prepareAndSendBroadcast((Intent) msg.obj);
+                    break;
+                case MSG_SEND_DEFERRED_BROADCAST:
+                    Intent deferredIntent;
+                    synchronized (mLock) {
+                        deferredIntent = mDeferredMap.remove((String) msg.obj);
+                    }
+                    if (deferredIntent != null) {
+                        prepareAndSendBroadcast(deferredIntent);
+                    }
+                    break;
+            }
+        }
+
+        private void prepareAndSendBroadcast(Intent intent) {
+            if (!DropBoxManagerService.this.mBooted) {
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+            }
+            getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM,
+                    android.Manifest.permission.READ_LOGS);
+        }
+
+        private Intent createIntent(String tag, long time) {
+            final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
+            dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag);
+            dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time);
+            return dropboxIntent;
+        }
+
+        /**
+         * Schedule a dropbox broadcast to be sent asynchronously.
+         */
+        public void sendBroadcast(String tag, long time) {
+            sendMessage(obtainMessage(MSG_SEND_BROADCAST, createIntent(tag, time)));
+        }
+
+        /**
+         * Possibly schedule a delayed dropbox broadcast. The broadcast will only be scheduled if
+         * no broadcast is currently scheduled. Otherwise updated the scheduled broadcast with the
+         * new intent information, effectively dropping the previous broadcast.
+         */
+        public void maybeDeferBroadcast(String tag, long time) {
+            synchronized (mLock) {
+                final Intent intent = mDeferredMap.get(tag);
+                if (intent == null) {
+                    // Schedule new delayed broadcast.
+                    mDeferredMap.put(tag, createIntent(tag, time));
+                    sendMessageDelayed(obtainMessage(MSG_SEND_DEFERRED_BROADCAST, tag),
+                            mLowPriorityRateLimitPeriod);
+                } else {
+                    // Broadcast is already scheduled. Update intent with new data.
+                    intent.putExtra(DropBoxManager.EXTRA_TIME, time);
+                    final int dropped = intent.getIntExtra(DropBoxManager.EXTRA_DROPPED_COUNT, 0);
+                    intent.putExtra(DropBoxManager.EXTRA_DROPPED_COUNT, dropped + 1);
+                    return;
+                }
+            }
+        }
+    }
+
     /**
      * Creates an instance of managed drop box storage using the default dropbox
      * directory.
@@ -176,15 +317,7 @@
         super(context);
         mDropBoxDir = path;
         mContentResolver = getContext().getContentResolver();
-        mHandler = new Handler(looper) {
-            @Override
-            public void handleMessage(Message msg) {
-                if (msg.what == MSG_SEND_BROADCAST) {
-                    getContext().sendBroadcastAsUser((Intent)msg.obj, UserHandle.SYSTEM,
-                            android.Manifest.permission.READ_LOGS);
-                }
-            }
-        };
+        mHandler = new DropBoxManagerBroadcastHandler(looper);
     }
 
     @Override
@@ -211,6 +344,8 @@
                             mReceiver.onReceive(getContext(), (Intent) null);
                         }
                     });
+
+                getLowPriorityResourceConfigs();
                 break;
 
             case PHASE_BOOT_COMPLETED:
@@ -231,6 +366,8 @@
         final String tag = entry.getTag();
         try {
             int flags = entry.getFlags();
+            Slog.i(TAG, "add tag=" + tag + " isTagEnabled=" + isTagEnabled(tag)
+                    + " flags=0x" + Integer.toHexString(flags));
             if ((flags & DropBoxManager.IS_EMPTY) != 0) throw new IllegalArgumentException();
 
             init();
@@ -285,7 +422,8 @@
 
                 long len = temp.length();
                 if (len > max) {
-                    Slog.w(TAG, "Dropping: " + tag + " (" + temp.length() + " > " + max + " bytes)");
+                    Slog.w(TAG, "Dropping: " + tag + " (" + temp.length() + " > "
+                            + max + " bytes)");
                     temp.delete();
                     temp = null;  // Pass temp = null to createEntry() to leave a tombstone
                     break;
@@ -295,17 +433,16 @@
             long time = createEntry(temp, tag, flags);
             temp = null;
 
-            final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
-            dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag);
-            dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time);
-            if (!mBooted) {
-                dropboxIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            }
             // Call sendBroadcast after returning from this call to avoid deadlock. In particular
             // the caller may be holding the WindowManagerService lock but sendBroadcast requires a
             // lock in ActivityManagerService. ActivityManagerService has been caught holding that
             // very lock while waiting for the WindowManagerService lock.
-            mHandler.sendMessage(mHandler.obtainMessage(MSG_SEND_BROADCAST, dropboxIntent));
+            if (mLowPriorityTags != null && mLowPriorityTags.contains(tag)) {
+                // Rate limit low priority Dropbox entries
+                mHandler.maybeDeferBroadcast(tag, time);
+            } else {
+                mHandler.sendBroadcast(tag, time);
+            }
         } catch (IOException e) {
             Slog.e(TAG, "Can't write: " + tag, e);
         } finally {
@@ -379,6 +516,22 @@
         return null;
     }
 
+    private synchronized void setLowPriorityRateLimit(long period) {
+        mLowPriorityRateLimitPeriod = period;
+    }
+
+    private synchronized void addLowPriorityTag(String tag) {
+        mLowPriorityTags.add(tag);
+    }
+
+    private synchronized void removeLowPriorityTag(String tag) {
+        mLowPriorityTags.remove(tag);
+    }
+
+    private synchronized void restoreDefaults() {
+        getLowPriorityResourceConfigs();
+    }
+
     public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
 
@@ -418,6 +571,10 @@
         out.append("Drop box contents: ").append(mAllFiles.contents.size()).append(" entries\n");
         out.append("Max entries: ").append(mMaxFiles).append("\n");
 
+        out.append("Low priority rate limit period: ");
+        out.append(mLowPriorityRateLimitPeriod).append(" ms\n");
+        out.append("Low priority tags: ").append(mLowPriorityTags).append("\n");
+
         if (!searchArgs.isEmpty()) {
             out.append("Searching for:");
             for (String a : searchArgs) out.append(" ").append(a);
@@ -933,4 +1090,21 @@
 
         return mCachedQuotaBlocks * mBlockSize;
     }
+
+    private void getLowPriorityResourceConfigs() {
+        mLowPriorityRateLimitPeriod = Resources.getSystem().getInteger(
+                R.integer.config_dropboxLowPriorityBroadcastRateLimitPeriod);
+
+        final String[] lowPrioritytags = Resources.getSystem().getStringArray(
+                R.array.config_dropboxLowPriorityTags);
+        final int size = lowPrioritytags.length;
+        if (size == 0) {
+            mLowPriorityTags = null;
+            return;
+        }
+        mLowPriorityTags = new ArraySet(size);
+        for (int i = 0; i < size; i++) {
+            mLowPriorityTags.add(lowPrioritytags[i]);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index f5bd11c..99bbcf8 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -70,25 +70,24 @@
         checkPermission();
         if (!"running".equals(SystemProperties.get("init.svc.gsid"))) {
             SystemProperties.set("ctl.start", "gsid");
-        }
-        for (int sleepMs = 64; sleepMs <= (GSID_ROUGH_TIMEOUT_MS << 1); sleepMs <<= 1) {
-            try {
-                Thread.sleep(sleepMs);
-            } catch (InterruptedException e) {
-                Slog.e(TAG, "Interrupted when waiting for GSID");
-                break;
-            }
-            if ("running".equals(SystemProperties.get("init.svc.gsid"))) {
-                synchronized (this) {
-                    if (mGsiService == null) {
-                        mGsiService = connect(this);
-                    }
-                    return mGsiService;
+            for (int sleepMs = 64; sleepMs <= (GSID_ROUGH_TIMEOUT_MS << 1); sleepMs <<= 1) {
+                try {
+                    Thread.sleep(sleepMs);
+                } catch (InterruptedException e) {
+                    Slog.e(TAG, "Interrupted when waiting for GSID");
+                    break;
+                }
+                if ("running".equals(SystemProperties.get("init.svc.gsid"))) {
+                    break;
                 }
             }
         }
-        Slog.e(TAG, "Unable to start gsid");
-        return null;
+        synchronized (this) {
+            if (mGsiService == null) {
+                mGsiService = connect(this);
+            }
+            return mGsiService;
+        }
     }
 
     private void checkPermission() {
@@ -125,19 +124,24 @@
     }
 
     @Override
+    public boolean isEnabled() throws RemoteException {
+        return getGsiService().isGsiEnabled();
+    }
+
+    @Override
     public boolean remove() throws RemoteException {
         return getGsiService().removeGsiInstall();
     }
 
     @Override
-    public boolean toggle() throws RemoteException {
+    public boolean setEnable(boolean enable) throws RemoteException {
         IGsiService gsiService = getGsiService();
-        if (gsiService.isGsiRunning()) {
-            return gsiService.disableGsiInstall();
-        } else {
+        if (enable) {
             final int status = gsiService.getGsiBootStatus();
             final boolean singleBoot = (status == IGsiService.BOOT_STATUS_SINGLE_BOOT);
             return gsiService.setGsiBootable(singleBoot) == 0;
+        } else {
+            return gsiService.disableGsiInstall();
         }
     }
 
diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java
new file mode 100644
index 0000000..164837a
--- /dev/null
+++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_HEALTH_CHECK_PASSED_PACKAGE;
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_REQUESTED_PACKAGES;
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_SUPPORTED_PACKAGES;
+
+import android.Manifest;
+import android.annotation.MainThread;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.IBinder;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.watchdog.ExplicitHealthCheckService;
+import android.service.watchdog.IExplicitHealthCheckService;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Controls the connections with {@link ExplicitHealthCheckService}.
+ */
+class ExplicitHealthCheckController {
+    private static final String TAG = "ExplicitHealthCheckController";
+    private final Object mLock = new Object();
+    private final Context mContext;
+
+    // Called everytime the service is connected, so the watchdog can sync it's state with
+    // the health check service. In practice, should never be null after it has been #setEnabled.
+    @GuardedBy("mLock") @Nullable private Runnable mOnConnected;
+    // Called everytime a package passes the health check, so the watchdog is notified of the
+    // passing check. In practice, should never be null after it has been #setEnabled.
+    @GuardedBy("mLock") @Nullable private Consumer<String> mPassedConsumer;
+    // Actual binder object to the explicit health check service.
+    @GuardedBy("mLock") @Nullable private IExplicitHealthCheckService mRemoteService;
+    // Cache for packages supporting explicit health checks. This cache should not change while
+    // the health check service is running.
+    @GuardedBy("mLock") @Nullable private List<String> mSupportedPackages;
+    // Connection to the explicit health check service, necessary to unbind
+    @GuardedBy("mLock") @Nullable private ServiceConnection mConnection;
+    // Bind state of the explicit health check service.
+    @GuardedBy("mLock") private boolean mEnabled;
+
+    ExplicitHealthCheckController(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Requests an explicit health check for {@code packageName}.
+     * After this request, the callback registered on {@link #setCallbacks} can receive explicit
+     * health check passed results.
+     *
+     * @throws IllegalStateException if the service is not started
+     */
+    public void request(String packageName) throws RemoteException {
+        synchronized (mLock) {
+            if (!mEnabled) {
+                return;
+            }
+
+            enforceServiceReadyLocked();
+
+            Slog.i(TAG, "Requesting health check for package " + packageName);
+            mRemoteService.request(packageName);
+        }
+    }
+
+    /**
+     * Cancels all explicit health checks for {@code packageName}.
+     * After this request, the callback registered on {@link #setCallbacks} can no longer receive
+     * explicit health check passed results.
+     *
+     * @throws IllegalStateException if the service is not started
+     */
+    public void cancel(String packageName) throws RemoteException {
+        synchronized (mLock) {
+            if (!mEnabled) {
+                return;
+            }
+
+            enforceServiceReadyLocked();
+
+            Slog.i(TAG, "Cancelling health check for package " + packageName);
+            mRemoteService.cancel(packageName);
+        }
+    }
+
+    /**
+     * Returns the packages that we can request explicit health checks for.
+     * The packages will be returned to the {@code consumer}.
+     *
+     * @throws IllegalStateException if the service is not started
+     */
+    public void getSupportedPackages(Consumer<List<String>> consumer) throws RemoteException {
+        synchronized (mLock) {
+            if (!mEnabled) {
+                consumer.accept(Collections.emptyList());
+                return;
+            }
+
+            enforceServiceReadyLocked();
+
+            if (mSupportedPackages == null) {
+                Slog.d(TAG, "Getting health check supported packages");
+                mRemoteService.getSupportedPackages(new RemoteCallback(result -> {
+                    mSupportedPackages = result.getStringArrayList(EXTRA_SUPPORTED_PACKAGES);
+                    consumer.accept(mSupportedPackages);
+                }));
+            } else {
+                Slog.d(TAG, "Getting cached health check supported packages");
+                consumer.accept(mSupportedPackages);
+            }
+        }
+    }
+
+    /**
+     * Returns the packages for which health checks are currently in progress.
+     * The packages will be returned to the {@code consumer}.
+     *
+     * @throws IllegalStateException if the service is not started
+     */
+    public void getRequestedPackages(Consumer<List<String>> consumer) throws RemoteException {
+        synchronized (mLock) {
+            if (!mEnabled) {
+                consumer.accept(Collections.emptyList());
+                return;
+            }
+
+            enforceServiceReadyLocked();
+
+            Slog.d(TAG, "Getting health check requested packages");
+            mRemoteService.getRequestedPackages(new RemoteCallback(
+                    result -> consumer.accept(
+                            result.getStringArrayList(EXTRA_REQUESTED_PACKAGES))));
+        }
+    }
+
+    /** Enables or disables explicit health checks. */
+    public void setEnabled(boolean enabled) {
+        synchronized (mLock) {
+            if (enabled == mEnabled) {
+                return;
+            }
+
+            Slog.i(TAG, "Setting explicit health checks enabled " + enabled);
+            mEnabled = enabled;
+            if (enabled) {
+                bindService();
+            } else {
+                unbindService();
+            }
+        }
+    }
+
+    /**
+     * Sets callbacks to listen to important events from the controller.
+     * Should be called at initialization.
+     */
+    public void setCallbacks(Runnable onConnected, Consumer<String> passedConsumer) {
+        Preconditions.checkNotNull(onConnected);
+        Preconditions.checkNotNull(passedConsumer);
+        mOnConnected = onConnected;
+        mPassedConsumer = passedConsumer;
+    }
+
+    /** Binds to the explicit health check service. */
+    private void bindService() {
+        synchronized (mLock) {
+            if (mRemoteService != null) {
+                return;
+            }
+            ComponentName component = getServiceComponentNameLocked();
+            if (component == null) {
+                Slog.wtf(TAG, "Explicit health check service not found");
+                return;
+            }
+
+            Intent intent = new Intent();
+            intent.setComponent(component);
+            // TODO: Fix potential race conditions during mConnection state transitions.
+            // E.g after #onServiceDisconected, the mRemoteService object is invalid until
+            // we get an #onServiceConnected.
+            mConnection = new ServiceConnection() {
+                @Override
+                public void onServiceConnected(ComponentName name, IBinder service) {
+                    initState(service);
+                    Slog.i(TAG, "Explicit health check service is connected " + name);
+                }
+
+                @Override
+                @MainThread
+                public void onServiceDisconnected(ComponentName name) {
+                    // Service crashed or process was killed, #onServiceConnected will be called.
+                    // Don't need to re-bind.
+                    Slog.i(TAG, "Explicit health check service is disconnected " + name);
+                }
+
+                @Override
+                public void onBindingDied(ComponentName name) {
+                    // Application hosting service probably got updated
+                    // Need to re-bind.
+                    synchronized (mLock) {
+                        if (mEnabled) {
+                            unbindService();
+                            bindService();
+                        }
+                    }
+                    Slog.i(TAG, "Explicit health check service binding is dead " + name);
+                }
+
+                @Override
+                public void onNullBinding(ComponentName name) {
+                    // Should never happen. Service returned null from #onBind.
+                    Slog.wtf(TAG, "Explicit health check service binding is null?? " + name);
+                }
+            };
+
+            Slog.i(TAG, "Binding to explicit health service");
+            mContext.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE,
+                    UserHandle.of(UserHandle.USER_SYSTEM));
+        }
+    }
+
+    /** Unbinds the explicit health check service. */
+    private void unbindService() {
+        synchronized (mLock) {
+            if (mRemoteService != null) {
+                Slog.i(TAG, "Unbinding from explicit health service");
+                mContext.unbindService(mConnection);
+                mRemoteService = null;
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ServiceInfo getServiceInfoLocked() {
+        final String packageName =
+                mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
+        if (packageName == null) {
+            Slog.w(TAG, "no external services package!");
+            return null;
+        }
+
+        final Intent intent = new Intent(ExplicitHealthCheckService.SERVICE_INTERFACE);
+        intent.setPackage(packageName);
+        final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
+                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+            Slog.w(TAG, "No valid components found.");
+            return null;
+        }
+        return resolveInfo.serviceInfo;
+    }
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ComponentName getServiceComponentNameLocked() {
+        final ServiceInfo serviceInfo = getServiceInfoLocked();
+        if (serviceInfo == null) {
+            return null;
+        }
+
+        final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
+        if (!Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE
+                .equals(serviceInfo.permission)) {
+            Slog.w(TAG, name.flattenToShortString() + " does not require permission "
+                    + Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE);
+            return null;
+        }
+        return name;
+    }
+
+    private void initState(IBinder service) {
+        synchronized (mLock) {
+            mSupportedPackages = null;
+            mRemoteService = IExplicitHealthCheckService.Stub.asInterface(service);
+            try {
+                mRemoteService.setCallback(new RemoteCallback(result -> {
+                    String packageName = result.getString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE);
+                    if (!TextUtils.isEmpty(packageName)) {
+                        synchronized (mLock) {
+                            if (mPassedConsumer == null) {
+                                Slog.w(TAG, "Health check passed for package " + packageName
+                                        + "but no consumer registered.");
+                            } else {
+                                mPassedConsumer.accept(packageName);
+                            }
+                        }
+                    } else {
+                        Slog.w(TAG, "Empty package passed explicit health check?");
+                    }
+                }));
+                if (mOnConnected == null) {
+                    Slog.w(TAG, "Health check service connected but no runnable registered.");
+                } else {
+                    mOnConnected.run();
+                }
+            } catch (RemoteException e) {
+                Slog.wtf(TAG, "Could not setCallback on explicit health check service");
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void enforceServiceReadyLocked() {
+        if (mRemoteService == null) {
+            // TODO: Try to bind to service
+            throw new IllegalStateException("Explicit health check service not ready");
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index f0244c3..3410d8d 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -52,6 +52,7 @@
 import android.location.Criteria;
 import android.location.GeocoderParams;
 import android.location.Geofence;
+import android.location.GnssCapabilities;
 import android.location.GnssMeasurementCorrections;
 import android.location.IBatchedLocationCallback;
 import android.location.IGnssMeasurementsListener;
@@ -102,6 +103,7 @@
 import com.android.server.location.GeofenceManager;
 import com.android.server.location.GeofenceProxy;
 import com.android.server.location.GnssBatchingProvider;
+import com.android.server.location.GnssCapabilitiesProvider;
 import com.android.server.location.GnssLocationProvider;
 import com.android.server.location.GnssMeasurementCorrectionsProvider;
 import com.android.server.location.GnssMeasurementsProvider;
@@ -200,8 +202,8 @@
     private GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider;
     private GnssNavigationMessageProvider mGnssNavigationMessageProvider;
     @GuardedBy("mLock")
-    private String mLocationControllerExtraPackage;
-    private boolean mLocationControllerExtraPackageEnabled;
+    private String mExtraLocationControllerPackage;
+    private boolean mExtraLocationControllerPackageEnabled;
     private IGpsGeofenceHardware mGpsGeofenceProxy;
 
     // list of currently active providers
@@ -249,8 +251,8 @@
     private int[] mCurrentUserProfiles = new int[]{UserHandle.USER_SYSTEM};
 
     private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider;
-
     private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider;
+    private GnssCapabilitiesProvider mGnssCapabilitiesProvider;
 
     private GnssBatchingProvider mGnssBatchingProvider;
     @GuardedBy("mLock")
@@ -323,16 +325,24 @@
                 });
         mPackageManager.addOnPermissionsChangeListener(
                 uid -> {
-                    synchronized (mLock) {
-                        onPermissionsChangedLocked();
-                    }
+                    // listener invoked on ui thread, move to our thread to reduce risk of blocking
+                    // ui thread
+                    mHandler.post(() -> {
+                        synchronized (mLock) {
+                            onPermissionsChangedLocked();
+                        }
+                    });
                 });
 
         mActivityManager.addOnUidImportanceListener(
                 (uid, importance) -> {
-                    synchronized (mLock) {
-                        onUidImportanceChangedLocked(uid, importance);
-                    }
+                    // listener invoked on ui thread, move to our thread to reduce risk of blocking
+                    // ui thread
+                    mHandler.post(() -> {
+                        synchronized (mLock) {
+                            onUidImportanceChangedLocked(uid, importance);
+                        }
+                    });
                 },
                 FOREGROUND_IMPORTANCE_CUTOFF);
         mContext.getContentResolver().registerContentObserver(
@@ -394,9 +404,13 @@
                 LocalServices.getService(PowerManagerInternal.class);
         localPowerManager.registerLowPowerModeObserver(ServiceType.LOCATION,
                 state -> {
-                    synchronized (mLock) {
-                        onBatterySaverModeChangedLocked(state.locationMode);
-                    }
+                    // listener invoked on ui thread, move to our thread to reduce risk of blocking
+                    // ui thread
+                    mHandler.post(() -> {
+                        synchronized (mLock) {
+                            onBatterySaverModeChangedLocked(state.locationMode);
+                        }
+                    });
                 });
 
         new PackageMonitor() {
@@ -761,6 +775,7 @@
             mGnssSystemInfoProvider = gnssProvider.getGnssSystemInfoProvider();
             mGnssBatchingProvider = gnssProvider.getGnssBatchingProvider();
             mGnssMetricsProvider = gnssProvider.getGnssMetricsProvider();
+            mGnssCapabilitiesProvider = gnssProvider.getGnssCapabilitiesProvider();
             mGnssStatusProvider = gnssProvider.getGnssStatusProvider();
             mNetInitiatedListener = gnssProvider.getNetInitiatedListener();
             mGnssMeasurementsProvider = gnssProvider.getGnssMeasurementsProvider();
@@ -2958,10 +2973,10 @@
         mContext.enforceCallingPermission(
                 android.Manifest.permission.LOCATION_HARDWARE,
                 "Location Hardware permission not granted to obtain GNSS chipset capabilities.");
-        if (!hasGnssPermissions(packageName) || mGnssMeasurementCorrectionsProvider == null) {
-            return -1;
+        if (!hasGnssPermissions(packageName) || mGnssCapabilitiesProvider == null) {
+            return GnssCapabilities.INVALID_CAPABILITIES;
         }
-        return mGnssMeasurementCorrectionsProvider.getCapabilities();
+        return mGnssCapabilitiesProvider.getGnssCapabilities();
     }
 
     @Override
@@ -3045,35 +3060,35 @@
     }
 
     @Override
-    public void setLocationControllerExtraPackage(String packageName) {
+    public void setExtraLocationControllerPackage(String packageName) {
         mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
                 Manifest.permission.LOCATION_HARDWARE + " permission required");
         synchronized (mLock) {
-            mLocationControllerExtraPackage = packageName;
+            mExtraLocationControllerPackage = packageName;
         }
     }
 
     @Override
-    public String getLocationControllerExtraPackage() {
+    public String getExtraLocationControllerPackage() {
         synchronized (mLock) {
-            return mLocationControllerExtraPackage;
+            return mExtraLocationControllerPackage;
         }
     }
 
     @Override
-    public void setLocationControllerExtraPackageEnabled(boolean enabled) {
+    public void setExtraLocationControllerPackageEnabled(boolean enabled) {
         mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
                 Manifest.permission.LOCATION_HARDWARE + " permission required");
         synchronized (mLock) {
-            mLocationControllerExtraPackageEnabled = enabled;
+            mExtraLocationControllerPackageEnabled = enabled;
         }
     }
 
     @Override
-    public boolean isLocationControllerExtraPackageEnabled() {
+    public boolean isExtraLocationControllerPackageEnabled() {
         synchronized (mLock) {
-            return mLocationControllerExtraPackageEnabled
-                    && (mLocationControllerExtraPackage != null);
+            return mExtraLocationControllerPackageEnabled
+                    && (mExtraLocationControllerPackage != null);
         }
     }
 
@@ -3610,9 +3625,9 @@
                 pw.println("  mBlacklist=null");
             }
 
-            if (mLocationControllerExtraPackage != null) {
-                pw.println(" Location controller extra package: " + mLocationControllerExtraPackage
-                        + " enabled: " + mLocationControllerExtraPackageEnabled);
+            if (mExtraLocationControllerPackage != null) {
+                pw.println(" Location controller extra package: " + mExtraLocationControllerPackage
+                        + " enabled: " + mExtraLocationControllerPackageEnabled);
             }
 
             if (!mBackgroundThrottlePackageWhitelist.isEmpty()) {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 61a7182..d1ae284 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1610,20 +1610,6 @@
     }
 
     @Override
-    public void setDnsConfigurationForNetwork(int netId, String[] servers, String[] domains,
-                    int[] params, String tlsHostname, String[] tlsServers) {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
-        final String[] tlsFingerprints = new String[0];
-        try {
-            mNetdService.setResolverConfiguration(
-                    netId, servers, domains, params, tlsHostname, tlsServers, tlsFingerprints);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Override
     public void addVpnUidRanges(int netId, UidRange[] ranges) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
@@ -2082,21 +2068,6 @@
     }
 
     @Override
-    public void removeNetwork(int netId) {
-        mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
-
-        try {
-            mNetdService.networkDestroy(netId);
-        } catch (ServiceSpecificException e) {
-            Log.w(TAG, "removeNetwork(" + netId + "): ", e);
-            throw e;
-        } catch (RemoteException e) {
-            Log.w(TAG, "removeNetwork(" + netId + "): ", e);
-            throw e.rethrowAsRuntimeException();
-        }
-    }
-
-    @Override
     public void addInterfaceToNetwork(String iface, int netId) {
         modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface);
     }
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 660109c..2ba4d97 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -26,11 +26,12 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.AtomicFile;
-import android.util.Log;
 import android.util.Slog;
 import android.util.Xml;
 
@@ -54,10 +55,12 @@
 import java.lang.annotation.Retention;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Consumer;
 
 /**
  * Monitors the health of packages on the system and notifies interested observers when packages
@@ -84,10 +87,10 @@
     private final Object mLock = new Object();
     // System server context
     private final Context mContext;
-    // Handler to run package cleanup runnables
-    private final Handler mTimerHandler;
-    // Handler for processing IO and observer actions
-    private final Handler mWorkerHandler;
+    // Handler to run short running tasks
+    private final Handler mShortTaskHandler;
+    // Handler for processing IO and long running tasks
+    private final Handler mLongTaskHandler;
     // Contains (observer-name -> observer-handle) that have ever been registered from
     // previous boots. Observers with all packages expired are periodically pruned.
     // It is saved to disk on system shutdown and repouplated on startup so it survives reboots.
@@ -97,6 +100,12 @@
     private final AtomicFile mPolicyFile;
     // Runnable to prune monitored packages that have expired
     private final Runnable mPackageCleanup;
+    private final ExplicitHealthCheckController mHealthCheckController;
+    // Flag to control whether explicit health checks are supported or not
+    @GuardedBy("mLock")
+    private boolean mIsHealthCheckEnabled = true;
+    @GuardedBy("mLock")
+    private boolean mIsPackagesReady;
     // Last SystemClock#uptimeMillis a package clean up was executed.
     // 0 if mPackageCleanup not running.
     private long mUptimeAtLastRescheduleMs;
@@ -104,32 +113,30 @@
     // 0 if mPackageCleanup not running.
     private long mDurationAtLastReschedule;
 
-    // TODO(b/120598832): Remove redundant context param
     private PackageWatchdog(Context context) {
-        mContext = context;
-        mPolicyFile = new AtomicFile(new File(new File(Environment.getDataDirectory(), "system"),
-                        "package-watchdog.xml"));
-        mTimerHandler = new Handler(Looper.myLooper());
-        mWorkerHandler = BackgroundThread.getHandler();
-        mPackageCleanup = this::rescheduleCleanup;
-        loadFromFile();
+        // Needs to be constructed inline
+        this(context, new AtomicFile(
+                        new File(new File(Environment.getDataDirectory(), "system"),
+                                "package-watchdog.xml")),
+                new Handler(Looper.myLooper()), BackgroundThread.getHandler(),
+                new ExplicitHealthCheckController(context));
     }
 
     /**
-     * Creates a PackageWatchdog for testing that uses the same {@code looper} for all handlers
-     * and creates package-watchdog.xml in an apps data directory.
+     * Creates a PackageWatchdog that allows injecting dependencies.
      */
     @VisibleForTesting
-    PackageWatchdog(Context context, Looper looper) {
+    PackageWatchdog(Context context, AtomicFile policyFile, Handler shortTaskHandler,
+            Handler longTaskHandler, ExplicitHealthCheckController controller) {
         mContext = context;
-        mPolicyFile = new AtomicFile(new File(context.getFilesDir(), "package-watchdog.xml"));
-        mTimerHandler = new Handler(looper);
-        mWorkerHandler = mTimerHandler;
+        mPolicyFile = policyFile;
+        mShortTaskHandler = shortTaskHandler;
+        mLongTaskHandler = longTaskHandler;
         mPackageCleanup = this::rescheduleCleanup;
+        mHealthCheckController = controller;
         loadFromFile();
     }
 
-
     /** Creates or gets singleton instance of PackageWatchdog. */
     public static PackageWatchdog getInstance(Context context) {
         synchronized (PackageWatchdog.class) {
@@ -141,6 +148,20 @@
     }
 
     /**
+     * Called during boot to notify when packages are ready on the device so we can start
+     * binding.
+     */
+    public void onPackagesReady() {
+        synchronized (mLock) {
+            mIsPackagesReady = true;
+            mHealthCheckController.setCallbacks(this::updateHealthChecks,
+                    packageName -> onHealthCheckPassed(packageName));
+            // Controller is disabled at creation until here where we may enable it
+            mHealthCheckController.setEnabled(mIsHealthCheckEnabled);
+        }
+    }
+
+    /**
      * Registers {@code observer} to listen for package failures
      *
      * <p>Observers are expected to call this on boot. It does not specify any packages but
@@ -163,40 +184,63 @@
      * Starts observing the health of the {@code packages} for {@code observer} and notifies
      * {@code observer} of any package failures within the monitoring duration.
      *
-     * <p>If monitoring a package with {@code withExplicitHealthCheck}, at the end of the monitoring
-     * duration if {@link #onExplicitHealthCheckPassed} was never called,
+     * <p>If monitoring a package supporting explicit health check, at the end of the monitoring
+     * duration if {@link #onHealthCheckPassed} was never called,
      * {@link PackageHealthObserver#execute} will be called as if the package failed.
      *
      * <p>If {@code observer} is already monitoring a package in {@code packageNames},
      * the monitoring window of that package will be reset to {@code durationMs} and the health
-     * check state will be reset to a default depending on {@code withExplictHealthCheck}.
+     * check state will be reset to a default depending on if the package is contained in
+     * {@link mPackagesWithExplicitHealthCheckEnabled}.
      *
      * @throws IllegalArgumentException if {@code packageNames} is empty
      * or {@code durationMs} is less than 1
      */
-    public void startObservingHealth(PackageHealthObserver observer, List<String> packageNames,
-            long durationMs, boolean withExplicitHealthCheck) {
-        if (packageNames.isEmpty() || durationMs < 1) {
+    public void startObservingHealth(PackageHealthObserver observer, List<String> packages,
+            long durationMs) {
+        if (packages.isEmpty() || durationMs < 1) {
             throw new IllegalArgumentException("Observation not started, no packages specified"
                     + "or invalid duration");
         }
+        if (!mIsPackagesReady) {
+            // TODO: Queue observation requests when packages are not ready
+            Slog.w(TAG, "Attempt to observe when packages not ready");
+            return;
+        }
+
+        try {
+            Slog.i(TAG, "Getting packages supporting explicit health check");
+            mHealthCheckController.getSupportedPackages(supportedPackages ->
+                    startObservingInner(observer, packages, durationMs, supportedPackages));
+        } catch (RemoteException e) {
+            Slog.wtf(TAG, "Failed to fetch supported explicit health check packages");
+        }
+    }
+
+    private void startObservingInner(PackageHealthObserver observer,
+            List<String> packageNames, long durationMs,
+            List<String> healthCheckSupportedPackages) {
+        Slog.i(TAG, "Start observing packages " + packageNames
+                + ". Explicit health check supported packages " + healthCheckSupportedPackages);
         List<MonitoredPackage> packages = new ArrayList<>();
         for (int i = 0; i < packageNames.size(); i++) {
-            // When observing packages withExplicitHealthCheck,
-            // MonitoredPackage#mHasExplicitHealthCheckPassed will be false initially.
-            packages.add(new MonitoredPackage(packageNames.get(i), durationMs,
-                            !withExplicitHealthCheck));
+            String packageName = packageNames.get(i);
+            boolean shouldEnableHealthCheck = healthCheckSupportedPackages.contains(packageName);
+            // If we should enable explicit health check for a package,
+            // MonitoredPackage#mHasHealthCheckPassed will be false
+            // until PackageWatchdog#onHealthCheckPassed
+            packages.add(new MonitoredPackage(packageName, durationMs, !shouldEnableHealthCheck));
         }
         synchronized (mLock) {
             ObserverInternal oldObserver = mAllObservers.get(observer.getName());
             if (oldObserver == null) {
-                Slog.d(TAG, observer.getName() + " started monitoring health of packages "
-                        + packageNames);
+                Slog.d(TAG, observer.getName() + " started monitoring health "
+                        + "of packages " + packageNames);
                 mAllObservers.put(observer.getName(),
                         new ObserverInternal(observer.getName(), packages));
             } else {
-                Slog.d(TAG, observer.getName() + " added the following packages to monitor "
-                        + packageNames);
+                Slog.d(TAG, observer.getName() + " added the following "
+                        + "packages to monitor " + packageNames);
                 oldObserver.updatePackages(packages);
             }
         }
@@ -204,9 +248,97 @@
         // Always reschedule because we may need to expire packages
         // earlier than we are already scheduled for
         rescheduleCleanup();
+        updateHealthChecks();
         saveToFileAsync();
     }
 
+    private void requestCheck(String packageName) {
+        try {
+            Slog.d(TAG, "Requesting explicit health check for " + packageName);
+            mHealthCheckController.request(packageName);
+        } catch (RemoteException e) {
+            Slog.wtf(TAG, "Failed to request explicit health check for " + packageName, e);
+        }
+    }
+
+    private void cancelCheck(String packageName) {
+        try {
+            Slog.d(TAG, "Cancelling explicit health check for " + packageName);
+            mHealthCheckController.cancel(packageName);
+        } catch (RemoteException e) {
+            Slog.wtf(TAG, "Failed to cancel explicit health check for " + packageName, e);
+        }
+    }
+
+    private void actOnDifference(Collection<String> collection1, Collection<String> collection2,
+            Consumer<String> action) {
+        Iterator<String> iterator = collection1.iterator();
+        while (iterator.hasNext()) {
+            String packageName = iterator.next();
+            if (!collection2.contains(packageName)) {
+                action.accept(packageName);
+            }
+        }
+    }
+
+    private void updateChecksInner(List<String> supportedPackages,
+            List<String> previousRequestedPackages) {
+        boolean shouldUpdateFile = false;
+
+        synchronized (mLock) {
+            Slog.i(TAG, "Updating explicit health checks. Supported packages: " + supportedPackages
+                    + ". Requested packages: " + previousRequestedPackages);
+            Set<String> newRequestedPackages = new ArraySet<>();
+            Iterator<ObserverInternal> oit = mAllObservers.values().iterator();
+            while (oit.hasNext()) {
+                ObserverInternal observer = oit.next();
+                Iterator<MonitoredPackage> pit =
+                        observer.mPackages.values().iterator();
+                while (pit.hasNext()) {
+                    MonitoredPackage monitoredPackage = pit.next();
+                    String packageName = monitoredPackage.mName;
+                    if (!monitoredPackage.mHasPassedHealthCheck) {
+                        if (supportedPackages.contains(packageName)) {
+                            newRequestedPackages.add(packageName);
+                        } else {
+                            shouldUpdateFile = true;
+                            monitoredPackage.mHasPassedHealthCheck = true;
+                        }
+                    }
+                }
+            }
+            // TODO: Support ending the binding if newRequestedPackages is empty.
+            // Will have to re-bind when we #startObservingHealth.
+
+            // Cancel packages no longer requested
+            actOnDifference(previousRequestedPackages, newRequestedPackages, p -> cancelCheck(p));
+            // Request packages not yet requested
+            actOnDifference(newRequestedPackages, previousRequestedPackages, p -> requestCheck(p));
+        }
+
+        if (shouldUpdateFile) {
+            saveToFileAsync();
+        }
+    }
+
+    private void updateHealthChecks() {
+        mShortTaskHandler.post(() -> {
+            try {
+                Slog.i(TAG, "Updating explicit health checks for all available packages");
+                mHealthCheckController.getSupportedPackages(supported -> {
+                    try {
+                        mHealthCheckController.getRequestedPackages(
+                                requested -> updateChecksInner(supported, requested));
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Failed to get requested health check packages", e);
+                    }
+                });
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to get supported health check package", e);
+            }
+        });
+    }
+
     /**
      * Unregisters {@code observer} from listening to package failure.
      * Additionally, this stops observing any packages that may have previously been observed
@@ -250,7 +382,7 @@
      * <p>This method could be called frequently if there is a severe problem on the device.
      */
     public void onPackageFailure(List<VersionedPackage> packages) {
-        mWorkerHandler.post(() -> {
+        mLongTaskHandler.post(() -> {
             synchronized (mLock) {
                 if (mAllObservers.isEmpty()) {
                     return;
@@ -286,49 +418,32 @@
         });
     }
 
-    /**
-     * Updates the observers monitoring {@code packageName} that explicit health check has passed.
-     *
-     * <p> This update is strictly for registered observers at the time of the call
-     * Observers that register after this signal will have no knowledge of prior signals and will
-     * effectively behave as if the explicit health check hasn't passed for {@code packageName}.
-     *
-     * <p> {@code packageName} can still be considered failed if reported by
-     * {@link #onPackageFailure} before the package expires.
-     *
-     * <p> Triggered by components outside the system server when they are fully functional after an
-     * update.
-     */
-    public void onExplicitHealthCheckPassed(String packageName) {
-        Slog.i(TAG, "Health check passed for package: " + packageName);
-        boolean shouldUpdateFile = false;
-        synchronized (mLock) {
-            for (int observerIdx = 0; observerIdx < mAllObservers.size(); observerIdx++) {
-                ObserverInternal observer = mAllObservers.valueAt(observerIdx);
-                MonitoredPackage monitoredPackage = observer.mPackages.get(packageName);
-                if (monitoredPackage != null && !monitoredPackage.mHasPassedHealthCheck) {
-                    monitoredPackage.mHasPassedHealthCheck = true;
-                    shouldUpdateFile = true;
-                }
-            }
-        }
-        if (shouldUpdateFile) {
-            saveToFileAsync();
-        }
-    }
-
     // TODO(b/120598832): Optimize write? Maybe only write a separate smaller file?
     // This currently adds about 7ms extra to shutdown thread
     /** Writes the package information to file during shutdown. */
     public void writeNow() {
         if (!mAllObservers.isEmpty()) {
-            mWorkerHandler.removeCallbacks(this::saveToFile);
+            mLongTaskHandler.removeCallbacks(this::saveToFile);
             pruneObservers(SystemClock.uptimeMillis() - mUptimeAtLastRescheduleMs);
             saveToFile();
             Slog.i(TAG, "Last write to update package durations");
         }
     }
 
+    // TODO(b/120598832): Set depending on DeviceConfig flag
+    /**
+     * Enables or disables explicit health checks.
+     * <p> If explicit health checks are enabled, the health check service is started.
+     * <p> If explicit health checks are disabled, pending explicit health check requests are
+     * passed and the health check service is stopped.
+     */
+    public void setExplicitHealthCheckEnabled(boolean enabled) {
+        synchronized (mLock) {
+            mIsHealthCheckEnabled = enabled;
+            mHealthCheckController.setEnabled(enabled);
+        }
+    }
+
     /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. */
     @Retention(SOURCE)
     @IntDef(value = {PackageHealthObserverImpact.USER_IMPACT_NONE,
@@ -371,6 +486,37 @@
         String getName();
     }
 
+    /**
+     * Updates the observers monitoring {@code packageName} that explicit health check has passed.
+     *
+     * <p> This update is strictly for registered observers at the time of the call
+     * Observers that register after this signal will have no knowledge of prior signals and will
+     * effectively behave as if the explicit health check hasn't passed for {@code packageName}.
+     *
+     * <p> {@code packageName} can still be considered failed if reported by
+     * {@link #onPackageFailure} before the package expires.
+     *
+     * <p> Triggered by components outside the system server when they are fully functional after an
+     * update.
+     */
+    private void onHealthCheckPassed(String packageName) {
+        Slog.i(TAG, "Health check passed for package: " + packageName);
+        boolean shouldUpdateFile = false;
+        synchronized (mLock) {
+            for (int observerIdx = 0; observerIdx < mAllObservers.size(); observerIdx++) {
+                ObserverInternal observer = mAllObservers.valueAt(observerIdx);
+                MonitoredPackage monitoredPackage = observer.mPackages.get(packageName);
+                if (monitoredPackage != null && !monitoredPackage.mHasPassedHealthCheck) {
+                    monitoredPackage.mHasPassedHealthCheck = true;
+                    shouldUpdateFile = true;
+                }
+            }
+        }
+        if (shouldUpdateFile) {
+            saveToFileAsync();
+        }
+    }
+
     /** Reschedules handler to prune expired packages from observers. */
     private void rescheduleCleanup() {
         synchronized (mLock) {
@@ -393,8 +539,8 @@
                     || nextDurationToScheduleMs < remainingDurationMs) {
                 // First schedule or an earlier reschedule
                 pruneObservers(elapsedDurationMs);
-                mTimerHandler.removeCallbacks(mPackageCleanup);
-                mTimerHandler.postDelayed(mPackageCleanup, nextDurationToScheduleMs);
+                mShortTaskHandler.removeCallbacks(mPackageCleanup);
+                mShortTaskHandler.postDelayed(mPackageCleanup, nextDurationToScheduleMs);
                 mDurationAtLastReschedule = nextDurationToScheduleMs;
                 mUptimeAtLastRescheduleMs = uptimeMs;
             }
@@ -437,7 +583,7 @@
                 List<MonitoredPackage> failedPackages =
                         observer.updateMonitoringDurations(elapsedMs);
                 if (!failedPackages.isEmpty()) {
-                    onExplicitHealthCheckFailed(observer, failedPackages);
+                    onHealthCheckFailed(observer, failedPackages);
                 }
                 if (observer.mPackages.isEmpty()) {
                     Slog.i(TAG, "Discarding observer " + observer.mName + ". All packages expired");
@@ -445,12 +591,13 @@
                 }
             }
         }
+        updateHealthChecks();
         saveToFileAsync();
     }
 
-    private void onExplicitHealthCheckFailed(ObserverInternal observer,
+    private void onHealthCheckFailed(ObserverInternal observer,
             List<MonitoredPackage> failedPackages) {
-        mWorkerHandler.post(() -> {
+        mLongTaskHandler.post(() -> {
             synchronized (mLock) {
                 PackageHealthObserver registeredObserver = observer.mRegisteredObserver;
                 if (registeredObserver != null) {
@@ -458,6 +605,7 @@
                     for (int i = 0; i < failedPackages.size(); i++) {
                         String packageName = failedPackages.get(i).mName;
                         long versionCode = 0;
+                        Slog.i(TAG, "Explicit health check failed for package " + packageName);
                         try {
                             versionCode = pm.getPackageInfo(
                                     packageName, 0 /* flags */).getLongVersionCode();
@@ -498,7 +646,7 @@
         } catch (FileNotFoundException e) {
             // Nothing to monitor
         } catch (IOException | NumberFormatException | XmlPullParserException e) {
-            Log.wtf(TAG, "Unable to read monitored packages, deleting file", e);
+            Slog.wtf(TAG, "Unable to read monitored packages, deleting file", e);
             mPolicyFile.delete();
         } finally {
             IoUtils.closeQuietly(infile);
@@ -542,8 +690,8 @@
     }
 
     private void saveToFileAsync() {
-        mWorkerHandler.removeCallbacks(this::saveToFile);
-        mWorkerHandler.post(this::saveToFile);
+        mLongTaskHandler.removeCallbacks(this::saveToFile);
+        mLongTaskHandler.post(this::saveToFile);
     }
 
     /**
diff --git a/services/core/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/ServiceWatcher.java
index a5a515f..e3dc3b7 100644
--- a/services/core/java/com/android/server/ServiceWatcher.java
+++ b/services/core/java/com/android/server/ServiceWatcher.java
@@ -382,7 +382,13 @@
     /**
      * Runs the given function synchronously if currently connected, and returns the default value
      * if not currently connected or if any exception is thrown.
+     *
+     * @deprecated Using this function is an indication that your AIDL API is broken. Calls from
+     * system server to outside MUST be one-way, and so cannot return any result, and this
+     * method should not be needed or used. Use a separate callback interface to allow outside
+     * components to return results back to the system server.
      */
+    @Deprecated
     public final <T> T runOnBinderBlocking(BlockingBinderRunner<T> runner, T defaultValue) {
         try {
             return runOnHandlerBlocking(() -> {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 98311fc..36fa3c6 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -17,12 +17,14 @@
 package com.android.server;
 
 import static android.Manifest.permission.INSTALL_PACKAGES;
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
 import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
+import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE;
 import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES;
-import static android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN;
-import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
@@ -77,7 +79,6 @@
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Binder;
-import android.os.Build;
 import android.os.DropBoxManager;
 import android.os.Environment;
 import android.os.Environment.UserEnvironment;
@@ -209,9 +210,6 @@
 
     private static final boolean ENABLE_ISOLATED_STORAGE = StorageManager.hasIsolatedStorage();
 
-    private static final boolean ENABLE_LEGACY_GREYLIST = SystemProperties
-            .getBoolean(StorageManager.PROP_LEGACY_GREYLIST, true);
-
     /**
      * If {@code 1}, enables the isolated storage feature. If {@code -1},
      * disables the isolated storage feature. If {@code 0}, uses the default
@@ -280,6 +278,7 @@
     private static final boolean EMULATE_FBE_SUPPORTED = true;
 
     private static final String TAG = "StorageManagerService";
+    private static final boolean LOCAL_LOGV = Log.isLoggable(TAG, Log.VERBOSE);
 
     private static final String TAG_STORAGE_BENCHMARK = "storage_benchmark";
     private static final String TAG_STORAGE_TRIM = "storage_trim";
@@ -305,17 +304,9 @@
     private static final String ATTR_LAST_TRIM_MILLIS = "lastTrimMillis";
     private static final String ATTR_LAST_BENCH_MILLIS = "lastBenchMillis";
 
-    private static final String[] LEGACY_STORAGE_PERMISSIONS = {
-            Manifest.permission.READ_EXTERNAL_STORAGE,
-            Manifest.permission.WRITE_EXTERNAL_STORAGE
-    };
-
     private static final String[] ALL_STORAGE_PERMISSIONS = {
             Manifest.permission.READ_EXTERNAL_STORAGE,
-            Manifest.permission.WRITE_EXTERNAL_STORAGE,
-            Manifest.permission.READ_MEDIA_AUDIO,
-            Manifest.permission.READ_MEDIA_VIDEO,
-            Manifest.permission.READ_MEDIA_IMAGES
+            Manifest.permission.WRITE_EXTERNAL_STORAGE
     };
 
     private final AtomicFile mSettingsFile;
@@ -938,13 +929,20 @@
     private void initIfBootedAndConnected() {
         Slog.d(TAG, "Thinking about init, mBootCompleted=" + mBootCompleted
                 + ", mDaemonConnected=" + mDaemonConnected);
-        if (mBootCompleted && mDaemonConnected
-                && !StorageManager.isFileEncryptedNativeOnly()) {
-            // When booting a device without native support, make sure that our
-            // user directories are locked or unlocked based on the current
-            // emulation status.
-            final boolean initLocked = StorageManager.isFileEncryptedEmulatedOnly();
-            Slog.d(TAG, "Setting up emulation state, initlocked=" + initLocked);
+        if (mBootCompleted && mDaemonConnected) {
+            // Tell vold to lock or unlock the user directories based on the
+            // current file-based encryption status.
+            final boolean initLocked;
+            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
+                // For native FBE this is a no-op after reboot, but this is
+                // still needed in case of framework restarts.
+                Slog.d(TAG, "FBE is enabled; ensuring all user directories are locked.");
+                initLocked = true;
+            } else {
+                // This is in case FBE emulation was turned off.
+                Slog.d(TAG, "FBE is disabled; ensuring the FBE emulation state is cleared.");
+                initLocked = false;
+            }
             final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
             for (UserInfo user : users) {
                 try {
@@ -1730,7 +1728,7 @@
             }
 
             final List<PackageInfo> pkgs = pm.getPackagesHoldingPermissions(
-                    LEGACY_STORAGE_PERMISSIONS,
+                    ALL_STORAGE_PERMISSIONS,
                     MATCH_UNINSTALLED_PACKAGES | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
                             | GET_PERMISSIONS);
             for (PackageInfo pkg : pkgs) {
@@ -1747,26 +1745,6 @@
                 if (lastAccess > 0) {
                     appOps.setUidMode(AppOpsManager.OP_LEGACY_STORAGE, uid,
                             AppOpsManager.MODE_ALLOWED);
-
-                    // Grandfather pre-Q app by granting all permissions and fixing them. The user
-                    // needs to uninstall the app to revoke the permissions.
-                    // TODO: Deal with shard Uids
-                    if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q) {
-                        for (String perm : ALL_STORAGE_PERMISSIONS) {
-                            if (ArrayUtils.contains(pkg.requestedPermissions, perm)) {
-                                pm.grantRuntimePermission(packageName, perm, user);
-
-                                int flags = FLAG_PERMISSION_SYSTEM_FIXED;
-                                if (!ArrayUtils.contains(LEGACY_STORAGE_PERMISSIONS, perm)) {
-                                    flags |= FLAG_PERMISSION_HIDDEN;
-                                }
-
-                                pm.updatePermissionFlags(perm, packageName,
-                                        FLAG_PERMISSION_SYSTEM_FIXED | FLAG_PERMISSION_HIDDEN,
-                                        flags, user);
-                            }
-                        }
-                    }
                 }
             }
         }
@@ -2420,23 +2398,6 @@
                 Binder.restoreCallingIdentity(token);
             }
         }
-
-        if ((mask & StorageManager.DEBUG_LEGACY_GREYLIST) != 0) {
-            final boolean enabled = (flags & StorageManager.DEBUG_LEGACY_GREYLIST) != 0;
-
-            final long token = Binder.clearCallingIdentity();
-            try {
-                SystemProperties.set(StorageManager.PROP_LEGACY_GREYLIST,
-                        Boolean.toString(enabled));
-
-                // Perform hard reboot to kick policy into place
-                mHandler.post(() -> {
-                    mContext.getSystemService(PowerManager.class).reboot(null);
-                });
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
     }
 
     @Override
@@ -2881,6 +2842,32 @@
         mVold.commitChanges();
     }
 
+    /**
+     * Check if we should be mounting with checkpointing or are checkpointing now
+     */
+    @Override
+    public boolean needsCheckpoint() throws RemoteException {
+        // Only the system process is permitted to commit checkpoints
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to commit checkpoint changes");
+        }
+
+        return mVold.needsCheckpoint();
+    }
+
+    /**
+     * Abort the current set of changes and either try again, or abort entirely
+     */
+    @Override
+    public void abortChanges(String message, boolean retry) throws RemoteException {
+        // Only the system process is permitted to abort checkpoints
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to commit checkpoint changes");
+        }
+
+        mVold.abortChanges(message, retry);
+    }
+
     @Override
     public String getPassword() throws RemoteException {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
@@ -3837,43 +3824,60 @@
     }
 
     private int getMountMode(int uid, String packageName) {
+        final int mode = getMountModeInternal(uid, packageName);
+        if (LOCAL_LOGV) {
+            Slog.v(TAG, "Resolved mode " + mode + " for " + packageName + "/"
+                    + UserHandle.formatUid(uid));
+        }
+        return mode;
+    }
+
+    private int getMountModeInternal(int uid, String packageName) {
         try {
+            // Get some easy cases out of the way first
             if (Process.isIsolated(uid)) {
                 return Zygote.MOUNT_EXTERNAL_NONE;
             }
-            if (mIPackageManager.checkUidPermission(WRITE_MEDIA_STORAGE, uid)
-                    == PERMISSION_GRANTED) {
-                return Zygote.MOUNT_EXTERNAL_FULL;
-            } else if (mIAppOpsService.checkOperation(OP_LEGACY_STORAGE, uid,
-                    packageName) == MODE_ALLOWED) {
-                return Zygote.MOUNT_EXTERNAL_LEGACY;
-            } else if (mIPackageManager.checkUidPermission(INSTALL_PACKAGES, uid)
-                    == PERMISSION_GRANTED || mIAppOpsService.checkOperation(
-                            OP_REQUEST_INSTALL_PACKAGES, uid, packageName) == MODE_ALLOWED) {
-                return Zygote.MOUNT_EXTERNAL_INSTALLER;
-            } else if (mPmInternal.isInstantApp(packageName, UserHandle.getUserId(uid))) {
+            if (mPmInternal.isInstantApp(packageName, UserHandle.getUserId(uid))) {
                 return Zygote.MOUNT_EXTERNAL_NONE;
+            }
+
+            // Determine if caller is holding runtime permission
+            final boolean hasRead = StorageManager.checkPermissionAndAppOp(mContext, false, 0,
+                    uid, packageName, READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE);
+            final boolean hasWrite = StorageManager.checkPermissionAndAppOp(mContext, false, 0,
+                    uid, packageName, WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE);
+            final boolean hasStorage = hasRead || hasWrite;
+
+            // We're only willing to give out broad access if they also hold
+            // runtime permission; this is a firm CDD requirement
+            final boolean hasFull = mIPackageManager.checkUidPermission(WRITE_MEDIA_STORAGE,
+                    uid) == PERMISSION_GRANTED;
+            if (hasFull && hasStorage) {
+                return Zygote.MOUNT_EXTERNAL_FULL;
+            }
+
+            // We're only willing to give out installer access if they also hold
+            // runtime permission; this is a firm CDD requirement
+            final boolean hasInstall = mIPackageManager.checkUidPermission(INSTALL_PACKAGES,
+                    uid) == PERMISSION_GRANTED;
+            final boolean hasInstallOp = mIAppOpsService.checkOperation(OP_REQUEST_INSTALL_PACKAGES,
+                    uid, packageName) == MODE_ALLOWED;
+            if ((hasInstall || hasInstallOp) && hasStorage) {
+                return Zygote.MOUNT_EXTERNAL_INSTALLER;
+            }
+
+            // Otherwise we're willing to give out sandboxed or non-sandboxed if
+            // they hold the runtime permission
+            final boolean hasLegacy = mIAppOpsService.checkOperation(OP_LEGACY_STORAGE,
+                    uid, packageName) == MODE_ALLOWED;
+            // STOPSHIP: only use app-op once permission model has fully landed
+            final boolean requestedLegacy = !mIPackageManager
+                    .getApplicationInfo(packageName, 0, UserHandle.getUserId(uid))
+                    .isExternalStorageSandboxAllowed();
+            if ((hasLegacy || requestedLegacy) && hasStorage) {
+                return Zygote.MOUNT_EXTERNAL_LEGACY;
             } else {
-                if (ENABLE_LEGACY_GREYLIST) {
-                    // STOPSHIP: remove this temporary workaround once developers
-                    // fix bugs where they're opening _data paths in native code
-                    switch (packageName) {
-                        case "com.facebook.katana": // b/123996076
-                        case "jp.naver.line.android": // b/124767356
-                        case "com.mxtech.videoplayer.ad": // b/124531483
-                        case "com.whatsapp": // b/124766614
-                        case "com.maxmpz.audioplayer": // b/127886230
-                        case "com.estrongs.android.pop": // b/127926473
-                        case "com.roidapp.photogrid": // b/128269119
-                        case "com.cleanmaster.mguard": // b/128384413
-                        case "com.skype.raider": // b/128487044
-                        case "org.telegram.messenger": // b/128652960
-                        case "com.jrtstudio.AnotherMusicPlayer": // b/129084562
-                        case "ak.alizandro.smartaudiobookplayer": // b/129084042
-                        case "com.campmobile.snow": // b/128803870
-                            return Zygote.MOUNT_EXTERNAL_LEGACY;
-                    }
-                }
                 return Zygote.MOUNT_EXTERNAL_WRITE;
             }
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 1870f8d..5522396 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -5,6 +5,9 @@
             "file_patterns": ["AlarmManagerService\\.java"],
             "options": [
                 {
+                  "include-filter": "com.android.server."
+                },
+                {
                   "include-annotation": "android.platform.test.annotations.Presubmit"
                 },
                 {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 26896f5..1c99316 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -73,10 +73,13 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.OptionalInt;
+import java.util.stream.Collectors;
 
 /**
  * Since phone process can be restarted, this class provides a centralized place
@@ -258,8 +261,7 @@
     static final int ENFORCE_PHONE_STATE_PERMISSION_MASK =
                 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
                         | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
-                        | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST
-                        | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
+                        | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST;
 
     static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
                 PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
@@ -625,11 +627,6 @@
                 r.callingPackage = callingPackage;
                 r.callerUid = Binder.getCallingUid();
                 r.callerPid = Binder.getCallingPid();
-                if (r.subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && r.subId != subId) {
-                    throw new IllegalArgumentException(
-                            "PhoneStateListener cannot concurrently listen on multiple " +
-                                    "subscriptions. Previously registered on subId: " + r.subId);
-                }
                 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
                 // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
                 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -825,7 +822,10 @@
                         }
                     }
                     if ((events & PhoneStateListener
-                            .LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) {
+                            .LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0
+                            && TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
+                                    r.context, r.callerPid, r.callerUid, r.callingPackage,
+                            "listen_active_data_subid_change")) {
                         try {
                             r.callback.onActiveDataSubIdChanged(mActiveDataSubId);
                         } catch (RemoteException ex) {
@@ -1159,17 +1159,28 @@
 
     @Override
     public void notifyCarrierNetworkChange(boolean active) {
-        enforceNotifyPermissionOrCarrierPrivilege("notifyCarrierNetworkChange()");
+        // only CarrierService with carrier privilege rule should have the permission.
+        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        try {
+            subId = Arrays.stream(SubscriptionManager.from(mContext)
+                    .getActiveSubscriptionIdList())
+                    .filter(i -> TelephonyPermissions.checkCarrierPrivilegeForSubId(i))
+                    .findFirst().getAsInt();
+        } catch (NoSuchElementException ex) {
+            log("notifyCarrierNetworkChange without carrier privilege");
+        }
+        int phoneId = SubscriptionManager.getPhoneId(subId);
 
         if (VDBG) {
-            log("notifyCarrierNetworkChange: active=" + active);
+            log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId);
         }
 
         synchronized (mRecords) {
             mCarrierNetworkChangeState = active;
             for (Record r : mRecords) {
                 if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE)) {
+                        PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) &&
+                        idMatch(r.subId, subId, phoneId)) {
                     try {
                         r.callback.onCarrierNetworkChange(active);
                     } catch (RemoteException ex) {
@@ -1756,12 +1767,23 @@
             log("notifyActiveDataSubIdChanged: activeDataSubId=" + activeDataSubId);
         }
 
+        // Create a copy to prevent the IPC call while checking carrier privilege under the lock.
+        List<Record> copiedRecords;
         synchronized (mRecords) {
-            mActiveDataSubId = activeDataSubId;
+            copiedRecords = new ArrayList<>(mRecords);
+        }
+        mActiveDataSubId = activeDataSubId;
 
-            for (Record r : mRecords) {
-                if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)) {
+        // Filter the record that does not listen to this change or does not have the permission.
+        copiedRecords = copiedRecords.stream().filter(r -> r.matchPhoneStateListenerEvent(
+                PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)
+                && TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(
+                        mContext, r.callerPid, r.callerUid, r.callingPackage,
+                "notifyActiveDataSubIdChanged")).collect(Collectors.toCollection(ArrayList::new));
+
+        synchronized (mRecords) {
+            for (Record r : copiedRecords) {
+                if (mRecords.contains(r)) {
                     try {
                         r.callback.onActiveDataSubIdChanged(activeDataSubId);
                     } catch (RemoteException ex) {
@@ -1885,7 +1907,7 @@
                 pw.println("mDataConnectionState=" + mDataConnectionState[i]);
                 pw.println("mCellLocation=" + mCellLocation[i]);
                 pw.println("mCellInfo=" + mCellInfo.get(i));
-                pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i).toString());
+                pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i));
                 pw.decreaseIndent();
             }
             pw.println("mCallNetworkType=" + mCallNetworkType);
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 1aeb689..afcf954 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -40,6 +40,7 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
+import android.util.StatsLog;
 
 import com.android.internal.os.ZygoteConnectionConstants;
 import com.android.server.am.ActivityManagerService;
@@ -539,6 +540,7 @@
                         mActivity.addErrorToDropBox(
                                 "watchdog", null, "system_server", null, null, null,
                                 subject, null, stack, null);
+                        StatsLog.write(StatsLog.SYSTEM_SERVER_WATCHDOG_OCCURRED, subject);
                     }
                 };
             dropboxThread.start();
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 712edcc..da66590 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -58,7 +58,6 @@
     private static final int CE_DATABASE_VERSION = 10;
     private static final int DE_DATABASE_VERSION = 3; // Added visibility support in O
 
-
     static final String TABLE_ACCOUNTS = "accounts";
     private static final String ACCOUNTS_ID = "_id";
     private static final String ACCOUNTS_NAME = "name";
@@ -267,6 +266,13 @@
         }
 
         @Override
+        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.e(TAG, "onDowngrade: recreate accounts CE table");
+            resetDatabase(db);
+            onCreate(db);
+        }
+
+        @Override
         public void onOpen(SQLiteDatabase db) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + CE_DATABASE_NAME);
         }
@@ -616,6 +622,13 @@
             }
         }
 
+        @Override
+        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.e(TAG, "onDowngrade: recreate accounts DE table");
+            resetDatabase(db);
+            onCreate(db);
+        }
+
         public SQLiteDatabase getReadableDatabaseUserIsUnlocked() {
             if(!mCeAttached) {
                 Log.wtf(TAG, "getReadableDatabaseUserIsUnlocked called while user " + mUserId
@@ -1399,4 +1412,26 @@
         return new AccountsDb(deDatabaseHelper, context, preNDatabaseFile);
     }
 
+    /**
+     * Removes all tables and triggers created by AccountManager.
+     */
+    private static void resetDatabase(SQLiteDatabase db) {
+        try (Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type ='table'", null)) {
+            while (c.moveToNext()) {
+                String name = c.getString(0);
+                // Skip tables managed by SQLiteDatabase
+                if ("android_metadata".equals(name) || "sqlite_sequence".equals(name)) {
+                    continue;
+                }
+                db.execSQL("DROP TABLE IF EXISTS " + name);
+            }
+        }
+
+        try (Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type ='trigger'", null)) {
+            while (c.moveToNext()) {
+                String name = c.getString(0);
+                db.execSQL("DROP TRIGGER IF EXISTS " + name);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index 8ccb6e2..9325d25 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -307,7 +307,6 @@
                     }
 
                     cancelJobToUpdateAdbKeyStore();
-                    mAdbKeyStore = null;
                     mConnectedKey = null;
                     break;
 
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index e357ce8..f0982d3 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1344,7 +1344,8 @@
                     if (!r.isForeground) {
                         final ServiceMap smap = getServiceMapLocked(r.userId);
                         if (smap != null) {
-                            ActiveForegroundApp active = smap.mActiveForegroundApps.get(r.packageName);
+                            ActiveForegroundApp active = smap.mActiveForegroundApps
+                                    .get(r.packageName);
                             if (active == null) {
                                 active = new ActiveForegroundApp();
                                 active.mPackageName = r.packageName;
@@ -1478,7 +1479,6 @@
             if (sr.isForeground || sr.fgRequired) {
                 anyForeground = true;
                 fgServiceTypes |= sr.foregroundServiceType;
-                break;
             }
         }
         mAm.updateProcessForegroundLocked(proc, anyForeground, fgServiceTypes, oomAdj);
@@ -1525,8 +1525,9 @@
         boolean anyClientActivities = false;
         for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
             ServiceRecord sr = proc.services.valueAt(i);
-            for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
-                ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
+            ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = sr.getConnections();
+            for (int conni = connections.size() - 1; conni >= 0 && !anyClientActivities; conni--) {
+                ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
                 for (int cri=clist.size()-1; cri>=0; cri--) {
                     ConnectionRecord cr = clist.get(cri);
                     if (cr.binding.client == null || cr.binding.client == proc) {
@@ -1753,10 +1754,10 @@
                     callerApp.uid, callerApp.processName, callingPackage);
 
             IBinder binder = connection.asBinder();
-            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
+            ArrayList<ConnectionRecord> clist = s.getConnections().get(binder);
             if (clist == null) {
                 clist = new ArrayList<ConnectionRecord>();
-                s.connections.put(binder, clist);
+                s.putConnection(binder, clist);
             }
             clist.add(c);
             b.connections.add(c);
@@ -1805,7 +1806,7 @@
                                 || (callerApp.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP
                                         && (flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0),
                         b.client);
-                mAm.updateOomAdjLocked(s.app, true);
+                mAm.updateOomAdjLocked();
             }
 
             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
@@ -1856,8 +1857,9 @@
                     b.binder = service;
                     b.requested = true;
                     b.received = true;
-                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
-                        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
+                    ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
+                    for (int conni = connections.size() - 1; conni >= 0; conni--) {
+                        ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
                         for (int i=0; i<clist.size(); i++) {
                             ConnectionRecord c = clist.get(i);
                             if (!filter.equals(c.binding.intent.intent)) {
@@ -2723,6 +2725,10 @@
 
         updateServiceClientActivitiesLocked(app, null, true);
 
+        if (newService && created) {
+            app.addBoundClientUidsOfNewService(r);
+        }
+
         // If the service is in the started state, and there are no
         // pending arguments, then fake up one so its onStartCommand() will
         // be called.
@@ -2882,8 +2888,9 @@
 
         // Report to all of the connections that the service is no longer
         // available.
-        for (int conni=r.connections.size()-1; conni>=0; conni--) {
-            ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
+        ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
+        for (int conni = connections.size() - 1; conni >= 0; conni--) {
+            ArrayList<ConnectionRecord> c = connections.valueAt(conni);
             for (int i=0; i<c.size(); i++) {
                 ConnectionRecord cr = c.get(i);
                 // There is still a connection to the service that is
@@ -3014,6 +3021,7 @@
                 r.stats.stopLaunchedLocked();
             }
             r.app.services.remove(r);
+            r.app.updateBoundClientUids();
             if (r.whitelistManager) {
                 updateWhitelistManagerLocked(r.app);
             }
@@ -3066,11 +3074,11 @@
         IBinder binder = c.conn.asBinder();
         AppBindRecord b = c.binding;
         ServiceRecord s = b.service;
-        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
+        ArrayList<ConnectionRecord> clist = s.getConnections().get(binder);
         if (clist != null) {
             clist.remove(c);
             if (clist.size() == 0) {
-                s.connections.remove(binder);
+                s.removeConnection(binder);
             }
         }
         b.connections.remove(c);
@@ -3295,6 +3303,7 @@
             if (finishing) {
                 if (r.app != null && !r.app.isPersistent()) {
                     r.app.services.remove(r);
+                    r.app.updateBoundClientUids();
                     if (r.whitelistManager) {
                         updateWhitelistManagerLocked(r.app);
                     }
@@ -3390,6 +3399,7 @@
                 Slog.i(TAG, "  Force stopping service " + service);
                 if (service.app != null && !service.app.isPersistent()) {
                     service.app.services.remove(service);
+                    service.app.updateBoundClientUids();
                     if (service.whitelistManager) {
                         updateWhitelistManagerLocked(service.app);
                     }
@@ -3505,8 +3515,9 @@
                 Iterator<ServiceRecord> it = app.services.iterator();
                 while (it.hasNext()) {
                     ServiceRecord r = it.next();
-                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
-                        ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
+                    ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
+                    for (int conni=connections.size()-1; conni>=0; conni--) {
+                        ArrayList<ConnectionRecord> cl = connections.valueAt(conni);
                         for (int i=0; i<cl.size(); i++) {
                             ConnectionRecord c = cl.get(i);
                             if (c.binding.client != app) {
@@ -3543,6 +3554,7 @@
             }
             if (sr.app != app && sr.app != null && !sr.app.isPersistent()) {
                 sr.app.services.remove(sr);
+                sr.app.updateBoundClientUids();
             }
             sr.setProcess(null);
             sr.isolatedProc = null;
@@ -3606,6 +3618,7 @@
             // so make sure the service is cleaned out of it.
             if (!app.isPersistent()) {
                 app.services.removeAt(i);
+                app.updateBoundClientUids();
             }
 
             // Sanity check: if the service listed for the app is not one
@@ -3656,6 +3669,7 @@
 
         if (!allowRestart) {
             app.services.clear();
+            app.clearBoundClientUids();
 
             // Make sure there are no more restarting services for this process.
             for (int i=mRestartingServices.size()-1; i>=0; i--) {
@@ -3702,7 +3716,7 @@
         info.foreground = r.isForeground;
         info.activeSince = r.createRealTime;
         info.started = r.startRequested;
-        info.clientCount = r.connections.size();
+        info.clientCount = r.getConnections().size();
         info.crashCount = r.crashCount;
         info.lastActivityTime = r.lastActivity;
         if (r.isForeground) {
@@ -3718,8 +3732,9 @@
             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
         }
 
-        for (int conni=r.connections.size()-1; conni>=0; conni--) {
-            ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
+        ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
+        for (int conni = connections.size() - 1; conni >= 0; conni--) {
+            ArrayList<ConnectionRecord> connl = connections.valueAt(conni);
             for (int i=0; i<connl.size(); i++) {
                 ConnectionRecord conn = connl.get(i);
                 if (conn.clientLabel != 0) {
@@ -3788,9 +3803,10 @@
     public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
         int userId = UserHandle.getUserId(Binder.getCallingUid());
         ServiceRecord r = getServiceByNameLocked(name, userId);
+        ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
         if (r != null) {
-            for (int conni=r.connections.size()-1; conni>=0; conni--) {
-                ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
+            for (int conni = connections.size() - 1; conni >= 0; conni--) {
+                ArrayList<ConnectionRecord> conn = connections.valueAt(conni);
                 for (int i=0; i<conn.size(); i++) {
                     if (conn.get(i).clientIntent != null) {
                         return conn.get(i).clientIntent;
@@ -4081,11 +4097,12 @@
                 pw.print(" started=");
                 pw.print(r.startRequested);
                 pw.print(" connections=");
-                pw.println(r.connections.size());
-                if (r.connections.size() > 0) {
+                ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
+                pw.println(connections.size());
+                if (connections.size() > 0) {
                     pw.println("    Connections:");
-                    for (int conni=0; conni<r.connections.size(); conni++) {
-                        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
+                    for (int conni = 0; conni < connections.size(); conni++) {
+                        ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
                         for (int i = 0; i < clist.size(); i++) {
                             ConnectionRecord conn = clist.get(i);
                             pw.print("      ");
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 1751856..d7decb4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -20,8 +20,10 @@
 
 import android.app.ActivityThread;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Handler;
 import android.provider.DeviceConfig;
 import android.provider.DeviceConfig.OnPropertyChangedListener;
@@ -38,6 +40,7 @@
  * Settings constants that can modify the activity manager's behavior.
  */
 final class ActivityManagerConstants extends ContentObserver {
+    private static final String TAG = "ActivityManagerConstants";
 
     // Key names stored in the settings value.
     private static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time";
@@ -113,6 +116,22 @@
      */
     private static final String KEY_MAX_CACHED_PROCESSES = "max_cached_processes";
 
+    /**
+     * Default value for mFlagBackgroundActivityStartsEnabled if not explicitly set in
+     * Settings.Global. This allows it to be set experimentally unless it has been
+     * enabled/disabled in developer options. Defaults to true.
+     */
+    private static final String KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED =
+            "default_background_activity_starts_enabled";
+
+    /**
+     * The packages temporarily whitelisted to be able to start activities from background.
+     * The list of packages is {@code ":"} colon delimited.
+     */
+    private static final String KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST =
+            "background_activity_starts_package_names_whitelist";
+
+
     // Maximum number of cached processes we will allow.
     public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
 
@@ -239,7 +258,8 @@
     volatile boolean mFlagActivityStartsLoggingEnabled;
 
     // Indicates whether the background activity starts is enabled.
-    // Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED
+    // Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED.
+    // If not set explicitly the default is controlled by DeviceConfig.
     volatile boolean mFlagBackgroundActivityStartsEnabled;
 
     volatile ArraySet<String> mPackageNamesWhitelistedForBgActivityStarts = new ArraySet<>();
@@ -272,6 +292,16 @@
     // memory trimming.
     public int CUR_TRIM_CACHED_PROCESSES;
 
+    private static final long MIN_AUTOMATIC_HEAP_DUMP_PSS_THRESHOLD_BYTES = 100 * 1024; // 100 KB
+
+    private final boolean mSystemServerAutomaticHeapDumpEnabled;
+
+    /** Package to report to when the memory usage exceeds the limit. */
+    private final String mSystemServerAutomaticHeapDumpPackageName;
+
+    /** Byte limit for dump heap monitoring. */
+    private long mSystemServerAutomaticHeapDumpPssThresholdBytes;
+
     private static final Uri ACTIVITY_MANAGER_CONSTANTS_URI = Settings.Global.getUriFor(
                 Settings.Global.ACTIVITY_MANAGER_CONSTANTS);
 
@@ -282,23 +312,41 @@
                 Settings.Global.getUriFor(
                         Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED);
 
-    private static final Uri BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI =
-                Settings.Global.getUriFor(
-                        Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST);
+    private static final Uri ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI =
+            Settings.Global.getUriFor(Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS);
 
     private final OnPropertyChangedListener mOnDeviceConfigChangedListener =
             new OnPropertyChangedListener() {
                 @Override
                 public void onPropertyChanged(String namespace, String name, String value) {
-                    if (KEY_MAX_CACHED_PROCESSES.equals(name)) {
-                        updateMaxCachedProcesses();
+                    if (name == null) {
+                        return;
+                    }
+                    switch (name) {
+                        case KEY_MAX_CACHED_PROCESSES:
+                            updateMaxCachedProcesses();
+                            break;
+                        case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED:
+                        case KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST:
+                            updateBackgroundActivityStarts();
+                            break;
+                        default:
+                            break;
                     }
                 }
             };
 
-    public ActivityManagerConstants(ActivityManagerService service, Handler handler) {
+    ActivityManagerConstants(Context context, ActivityManagerService service, Handler handler) {
         super(handler);
         mService = service;
+        mSystemServerAutomaticHeapDumpEnabled = Build.IS_DEBUGGABLE
+                && context.getResources().getBoolean(
+                com.android.internal.R.bool.config_debugEnableAutomaticSystemServerHeapDumps);
+        mSystemServerAutomaticHeapDumpPackageName = context.getPackageName();
+        mSystemServerAutomaticHeapDumpPssThresholdBytes = Math.max(
+                MIN_AUTOMATIC_HEAP_DUMP_PSS_THRESHOLD_BYTES,
+                context.getResources().getInteger(
+                        com.android.internal.R.integer.config_debugSystemServerPssThresholdBytes));
     }
 
     public void start(ContentResolver resolver) {
@@ -306,17 +354,20 @@
         mResolver.registerContentObserver(ACTIVITY_MANAGER_CONSTANTS_URI, false, this);
         mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this);
         mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_ENABLED_URI, false, this);
-        mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI,
-                false, this);
+        if (mSystemServerAutomaticHeapDumpEnabled) {
+            mResolver.registerContentObserver(ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI,
+                    false, this);
+        }
         updateConstants();
-        updateActivityStartsLoggingEnabled();
-        updateBackgroundActivityStartsEnabled();
-        updateBackgroundActivityStartsPackageNamesWhitelist();
+        if (mSystemServerAutomaticHeapDumpEnabled) {
+            updateEnableAutomaticSystemServerHeapDumps();
+        }
         DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                 ActivityThread.currentApplication().getMainExecutor(),
                 mOnDeviceConfigChangedListener);
         updateMaxCachedProcesses();
-
+        updateActivityStartsLoggingEnabled();
+        updateBackgroundActivityStarts();
     }
 
     public void setOverrideMaxCachedProcesses(int value) {
@@ -340,9 +391,9 @@
         } else if (ACTIVITY_STARTS_LOGGING_ENABLED_URI.equals(uri)) {
             updateActivityStartsLoggingEnabled();
         } else if (BACKGROUND_ACTIVITY_STARTS_ENABLED_URI.equals(uri)) {
-            updateBackgroundActivityStartsEnabled();
-        } else if (BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI.equals(uri)) {
-            updateBackgroundActivityStartsPackageNamesWhitelist();
+            updateBackgroundActivityStarts();
+        } else if (ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI.equals(uri)) {
+            updateEnableAutomaticSystemServerHeapDumps();
         }
     }
 
@@ -430,24 +481,58 @@
                 Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 1) == 1;
     }
 
-    private void updateBackgroundActivityStartsEnabled() {
-        mFlagBackgroundActivityStartsEnabled = Settings.Global.getInt(mResolver,
-                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1) == 1;
+    private void updateBackgroundActivityStarts() {
+        String whitelistedPackageNames = null;
+        int settingsValue = Settings.Global.getInt(mResolver,
+                Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, -1);
+
+        // If the user has explicitly enabled or disabled, that affects all apps.
+        // Otherwise we take the default state and whitelist from DeviceConfig.
+        if (settingsValue >= 0) {
+            mFlagBackgroundActivityStartsEnabled = settingsValue != 0;
+        } else {
+            boolean enabledInDeviceConfig = DeviceConfig.getBoolean(
+                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                    KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED,
+                    /*defaultValue*/ true);
+            mFlagBackgroundActivityStartsEnabled = enabledInDeviceConfig;
+            if (!enabledInDeviceConfig) {
+                whitelistedPackageNames = DeviceConfig.getProperty(
+                        DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                        KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST);
+            }
+        }
+        if (TextUtils.isEmpty(whitelistedPackageNames)) {
+            if (!mPackageNamesWhitelistedForBgActivityStarts.isEmpty()) {
+                mPackageNamesWhitelistedForBgActivityStarts = new ArraySet<>();
+            }
+        } else {
+            ArraySet<String> newSet = new ArraySet<>();
+            SimpleStringSplitter splitter = new SimpleStringSplitter(':');
+            splitter.setString(whitelistedPackageNames);
+            while (splitter.hasNext()) {
+                newSet.add(splitter.next());
+            }
+            mPackageNamesWhitelistedForBgActivityStarts = newSet;
+        }
     }
 
-    private void updateBackgroundActivityStartsPackageNamesWhitelist() {
-        final String setting = Settings.Global.getString(mResolver,
-                Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST);
-        if (TextUtils.isEmpty(setting)) {
+    private void updateEnableAutomaticSystemServerHeapDumps() {
+        if (!mSystemServerAutomaticHeapDumpEnabled) {
+            Slog.wtf(TAG,
+                    "updateEnableAutomaticSystemServerHeapDumps called when leak detection "
+                            + "disabled");
             return;
         }
-        ArraySet<String> newSet = new ArraySet<>();
-        SimpleStringSplitter splitter = new SimpleStringSplitter(':');
-        splitter.setString(setting);
-        while (splitter.hasNext()) {
-            newSet.add(splitter.next());
-        }
-        mPackageNamesWhitelistedForBgActivityStarts = newSet;
+        // Monitoring is on by default, so if the setting hasn't been set by the user,
+        // monitoring should be on.
+        final boolean enabled = Settings.Global.getInt(mResolver,
+                Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS, 1) == 1;
+
+        // Setting the threshold to 0 stops the checking.
+        final long threshold = enabled ? mSystemServerAutomaticHeapDumpPssThresholdBytes : 0;
+        mService.setDumpHeapDebugLimit(null, 0, threshold,
+                mSystemServerAutomaticHeapDumpPackageName);
     }
 
     private void updateMaxCachedProcesses() {
@@ -460,7 +545,7 @@
                     : mOverrideMaxCachedProcesses;
         } catch (NumberFormatException e) {
             // Bad flag value from Phenotype, revert to default.
-            Slog.e("ActivityManagerConstants",
+            Slog.e(TAG,
                     "Unable to parse flag for max_cached_processes: " + maxCachedProcessesFlag, e);
             CUR_MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
         }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a1f2ac6..a5932cc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -271,6 +271,7 @@
 import android.os.WorkSource;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.sysprop.VoldProperties;
 import android.text.TextUtils;
@@ -1266,6 +1267,7 @@
     String mMemWatchDumpFile;
     int mMemWatchDumpPid;
     int mMemWatchDumpUid;
+    private boolean mMemWatchIsUserInitiated;
     String mTrackAllocationApp = null;
     String mNativeDebuggingApp = null;
 
@@ -1712,9 +1714,14 @@
                 final int uid;
                 final long memLimit;
                 final String reportPackage;
+                final boolean isUserInitiated;
                 synchronized (ActivityManagerService.this) {
-                    procName = mMemWatchDumpProcName;
                     uid = mMemWatchDumpUid;
+                    if (uid == SYSTEM_UID) {
+                        procName = mContext.getString(R.string.android_system_label);
+                    } else {
+                        procName = mMemWatchDumpProcName;
+                    }
                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
                     if (val == null) {
                         val = mMemWatchProcesses.get(procName, 0);
@@ -1726,6 +1733,7 @@
                         memLimit = 0;
                         reportPackage = null;
                     }
+                    isUserInitiated = mMemWatchIsUserInitiated;
                 }
                 if (procName == null) {
                     return;
@@ -1739,8 +1747,9 @@
                     return;
                 }
 
-                String text = mContext.getString(R.string.dump_heap_notification, procName);
-
+                final int titleId = isUserInitiated
+                        ? R.string.dump_heap_ready_notification : R.string.dump_heap_notification;
+                String text = mContext.getString(titleId, procName);
 
                 Intent deleteIntent = new Intent();
                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
@@ -1748,6 +1757,8 @@
                 intent.setClassName("android", DumpHeapActivity.class.getName());
                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
+                intent.putExtra(DumpHeapActivity.KEY_IS_USER_INITIATED, isUserInitiated);
+                intent.putExtra(DumpHeapActivity.KEY_IS_SYSTEM_PROCESS, uid == SYSTEM_UID);
                 if (reportPackage != null) {
                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
                 }
@@ -1755,8 +1766,6 @@
                 Notification notification =
                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
-                        .setWhen(0)
-                        .setOngoing(true)
                         .setAutoCancel(true)
                         .setTicker(text)
                         .setColor(mContext.getColor(
@@ -2126,6 +2135,8 @@
                 mService.mServices.systemServicesReady();
             } else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
                 mService.startBroadcastObservers();
+            } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+                mService.mPackageWatchdog.onPackagesReady();
             }
         }
 
@@ -2143,7 +2154,8 @@
      * Encapsulates global settings related to hidden API enforcement behaviour, including tracking
      * the latest value via a content observer.
      */
-    static class HiddenApiSettings extends ContentObserver {
+    static class HiddenApiSettings extends ContentObserver
+            implements DeviceConfig.OnPropertiesChangedListener {
 
         private final Context mContext;
         private boolean mBlacklistDisabled;
@@ -2153,6 +2165,45 @@
         private int mStatslogSampleRate = -1;
         @HiddenApiEnforcementPolicy private int mPolicy = HIDDEN_API_ENFORCEMENT_DEFAULT;
 
+        /**
+         * Sampling rate for hidden API access event logs with libmetricslogger, as an integer in
+         * the range 0 to 0x10000 inclusive.
+         *
+         * @hide
+         */
+        public static final String HIDDEN_API_ACCESS_LOG_SAMPLING_RATE =
+                "hidden_api_access_log_sampling_rate";
+
+        /**
+         * Sampling rate for hidden API access event logging with statslog, as an integer in the
+         * range 0 to 0x10000 inclusive.
+         *
+         * @hide
+         */
+        public static final String HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE =
+                "hidden_api_access_statslog_sampling_rate";
+
+        public void onPropertiesChanged(DeviceConfig.Properties properties) {
+            int logSampleRate = properties.getInt(HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, 0x0);
+            if (logSampleRate < 0 || logSampleRate > 0x10000) {
+                logSampleRate = -1;
+            }
+            if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
+                mLogSampleRate = logSampleRate;
+                ZYGOTE_PROCESS.setHiddenApiAccessLogSampleRate(mLogSampleRate);
+            }
+
+            int statslogSampleRate =
+                    properties.getInt(HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE, 0);
+            if (statslogSampleRate < 0 || statslogSampleRate > 0x10000) {
+                statslogSampleRate = -1;
+            }
+            if (statslogSampleRate != -1 && statslogSampleRate != mStatslogSampleRate) {
+                mStatslogSampleRate = statslogSampleRate;
+                ZYGOTE_PROCESS.setHiddenApiAccessStatslogSampleRate(mStatslogSampleRate);
+            }
+        }
+
         public HiddenApiSettings(Handler handler, Context context) {
             super(handler);
             mContext = context;
@@ -2164,18 +2215,11 @@
                     false,
                     this);
             mContext.getContentResolver().registerContentObserver(
-                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE),
-                    false,
-                    this);
-            mContext.getContentResolver().registerContentObserver(
-                    Settings.Global.getUriFor(
-                        Settings.Global.HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE),
-                    false,
-                    this);
-            mContext.getContentResolver().registerContentObserver(
                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY),
                     false,
                     this);
+            DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_APP_COMPAT,
+                    mContext.getMainExecutor(), this);
             update();
         }
 
@@ -2199,24 +2243,6 @@
                   mExemptions = Collections.emptyList();
                 }
             }
-            int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, 0x200);
-            if (logSampleRate < 0 || logSampleRate > 0x10000) {
-                logSampleRate = -1;
-            }
-            if (logSampleRate != -1 && logSampleRate != mLogSampleRate) {
-                mLogSampleRate = logSampleRate;
-                ZYGOTE_PROCESS.setHiddenApiAccessLogSampleRate(mLogSampleRate);
-            }
-            int statslogSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.HIDDEN_API_ACCESS_STATSLOG_SAMPLING_RATE, 0);
-            if (statslogSampleRate < 0 || statslogSampleRate > 0x10000) {
-                statslogSampleRate = -1;
-            }
-            if (statslogSampleRate != -1 && statslogSampleRate != mStatslogSampleRate) {
-                mStatslogSampleRate = statslogSampleRate;
-                ZYGOTE_PROCESS.setHiddenApiAccessStatslogSampleRate(mStatslogSampleRate);
-            }
             mPolicy = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY);
         }
 
@@ -2264,7 +2290,8 @@
         mBatteryStatsService = null;
         mHandler = hasHandlerThread ? new MainHandler(handlerThread.getLooper()) : null;
         mHandlerThread = handlerThread;
-        mConstants = hasHandlerThread ? new ActivityManagerConstants(this, mHandler) : null;
+        mConstants = hasHandlerThread
+                ? new ActivityManagerConstants(mContext, this, mHandler) : null;
         final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */);
         mProcessList.init(this, activeUids);
         mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);
@@ -2312,7 +2339,7 @@
         mProcStartHandlerThread.start();
         mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
 
-        mConstants = new ActivityManagerConstants(this, mHandler);
+        mConstants = new ActivityManagerConstants(mContext, this, mHandler);
         final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */);
         mProcessList.init(this, activeUids);
         mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);
@@ -3104,7 +3131,7 @@
     }
 
     @GuardedBy("this")
-    ProcessChangeItem enqueueProcessChangeItemLocked(int uid, int pid) {
+    ProcessChangeItem enqueueProcessChangeItemLocked(int pid, int uid) {
         int i = mPendingProcessChanges.size()-1;
         ActivityManagerService.ProcessChangeItem item = null;
         while (i >= 0) {
@@ -5066,11 +5093,9 @@
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
-                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
-                } else {
-                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
-                }
+                final long delay = intent.getBooleanExtra(
+                        DumpHeapActivity.EXTRA_DELAY_DELETE, false) ? 5 * 60 * 1000 : 0;
+                mHandler.sendEmptyMessageDelayed(DELETE_DUMPHEAP_MSG, delay);
             }
         }, dumpheapFilter);
 
@@ -7940,6 +7965,30 @@
         }
     }
 
+    @Override
+    public void requestSystemServerHeapDump() {
+        if (!Build.IS_DEBUGGABLE) {
+            Slog.wtf(TAG, "requestSystemServerHeapDump called on a user build");
+            return;
+        }
+        if (Binder.getCallingUid() != SYSTEM_UID) {
+            // This also intentionally excludes secondary profiles from calling this.
+            throw new SecurityException(
+                    "Only the system process is allowed to request a system heap dump");
+        }
+        ProcessRecord pr;
+        synchronized (mPidsSelfLocked) {
+            pr = mPidsSelfLocked.get(myPid());
+        }
+        if (pr == null) {
+            Slog.w(TAG, "system process not in mPidsSelfLocked: " + myPid());
+            return;
+        }
+        synchronized (this) {
+            startHeapDumpLocked(pr, true);
+        }
+    }
+
     /**
      * @deprecated This method is only used by a few internal components and it will soon be
      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
@@ -8723,6 +8772,8 @@
                     com.android.internal.R.bool.config_customUserSwitchUi);
             mUserController.mMaxRunningUsers = res.getInteger(
                     com.android.internal.R.integer.config_multiuserMaxRunningUsers);
+            mUserController.mDelayUserDataLocking = res.getBoolean(
+                    com.android.internal.R.bool.config_multiuserDelayUserDataLocking);
 
             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
         }
@@ -8789,7 +8840,6 @@
         mAtmInternal.updateTopComponentForFactoryTest();
 
         retrieveSettings();
-        final int currentUserId = mUserController.getCurrentUserId();
         mUgmInternal.onSystemReady();
 
         final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
@@ -8803,6 +8853,16 @@
         }
 
         if (goingCallback != null) goingCallback.run();
+        // Check the current user here as a user can be started inside goingCallback.run() from
+        // other system services.
+        final int currentUserId = mUserController.getCurrentUserId();
+        Slog.i(TAG, "Current user:" + currentUserId);
+        if (currentUserId != UserHandle.USER_SYSTEM && !mUserController.isSystemUserStarted()) {
+            // User other than system user has started. Make sure that system user is already
+            // started before switching user.
+            throw new RuntimeException("System user not started while current user is:"
+                    + currentUserId);
+        }
         traceLog.traceBegin("ActivityManagerStartApps");
         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
                 Integer.toString(currentUserId), currentUserId);
@@ -10524,8 +10584,9 @@
             }
             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
-            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
-                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
+            pw.print("  mMemWatchDumpPid="); pw.println(mMemWatchDumpPid);
+            pw.print("  mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
+            pw.print("  mMemWatchIsUserInitiated="); pw.println(mMemWatchIsUserInitiated);
         }
         if (mTrackAllocationApp != null) {
             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
@@ -10823,6 +10884,9 @@
             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
             proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
+            proto.write(
+                    ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.IS_USER_INITIATED,
+                    mMemWatchIsUserInitiated);
             proto.end(dtoken);
 
             proto.end(token);
@@ -15271,18 +15335,20 @@
             final ProcessRecord callerApp = getRecordForAppLocked(caller);
             final int callingPid = Binder.getCallingPid();
             final int callingUid = Binder.getCallingUid();
+
             final long origId = Binder.clearCallingIdentity();
-            int res = broadcastIntentLocked(callerApp,
-                    callerApp != null ? callerApp.info.packageName : null,
-                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
-                    requiredPermissions, appOp, bOptions, serialized, sticky,
-                    callingPid, callingUid, callingUid, callingPid, userId);
-            Binder.restoreCallingIdentity(origId);
-            return res;
+            try {
+                return broadcastIntentLocked(callerApp,
+                        callerApp != null ? callerApp.info.packageName : null,
+                        intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
+                        requiredPermissions, appOp, bOptions, serialized, sticky,
+                        callingPid, callingUid, callingUid, callingPid, userId);
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
         }
     }
 
-
     int broadcastIntentInPackage(String packageName, int uid, int realCallingUid,
             int realCallingPid, Intent intent, String resolvedType, IIntentReceiver resultTo,
             int resultCode, String resultData, Bundle resultExtras,
@@ -15294,13 +15360,15 @@
             final long origId = Binder.clearCallingIdentity();
             String[] requiredPermissions = requiredPermission == null ? null
                     : new String[] {requiredPermission};
-            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
-                    resultTo, resultCode, resultData, resultExtras,
-                    requiredPermissions, OP_NONE, bOptions, serialized,
-                    sticky, -1, uid, realCallingUid, realCallingPid, userId,
-                    allowBackgroundActivityStarts);
-            Binder.restoreCallingIdentity(origId);
-            return res;
+            try {
+                return broadcastIntentLocked(null, packageName, intent, resolvedType,
+                        resultTo, resultCode, resultData, resultExtras,
+                        requiredPermissions, OP_NONE, bOptions, serialized,
+                        sticky, -1, uid, realCallingUid, realCallingPid, userId,
+                        allowBackgroundActivityStarts);
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
         }
     }
 
@@ -15920,14 +15988,7 @@
                 }
                 if (isDebuggable) {
                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
-                    final ProcessRecord myProc = proc;
-                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
-                    mMemWatchDumpProcName = proc.processName;
-                    mMemWatchDumpFile = heapdumpFile.toString();
-                    mMemWatchDumpPid = proc.pid;
-                    mMemWatchDumpUid = proc.uid;
-                    BackgroundThread.getHandler().post(
-                            new RecordPssRunnable(this, myProc, DumpHeapProvider.getJavaFile()));
+                    startHeapDumpLocked(proc, false);
                 } else {
                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
                             + ", but debugging not enabled");
@@ -15936,6 +15997,16 @@
         }
     }
 
+    private void startHeapDumpLocked(ProcessRecord proc, boolean isUserInitiated) {
+        final File heapdumpFile = DumpHeapProvider.getJavaFile();
+        mMemWatchDumpProcName = proc.processName;
+        mMemWatchDumpFile = heapdumpFile.toString();
+        mMemWatchDumpPid = proc.pid;
+        mMemWatchDumpUid = proc.uid;
+        mMemWatchIsUserInitiated = isUserInitiated;
+        BackgroundThread.getHandler().post(new RecordPssRunnable(this, proc, heapdumpFile));
+    }
+
     /**
      * Schedule PSS collection of a process.
      */
@@ -16331,12 +16402,10 @@
     @GuardedBy("this")
     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
             int fgServiceTypes, boolean oomAdj) {
-        proc.setHasForegroundServices(isForeground, fgServiceTypes);
 
-        final boolean hasFgServiceLocationType =
-                (fgServiceTypes & ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION) != 0;
         if (isForeground != proc.hasForegroundServices()
-                || proc.hasLocationForegroundServices() != hasFgServiceLocationType) {
+                || proc.getForegroundServiceTypes() != fgServiceTypes) {
+            proc.setHasForegroundServices(isForeground, fgServiceTypes);
             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
                     proc.info.uid);
             if (isForeground) {
@@ -16361,17 +16430,16 @@
                     }
                 }
             }
+
+            proc.setReportedForegroundServiceTypes(fgServiceTypes);
+            ProcessChangeItem item = enqueueProcessChangeItemLocked(proc.pid, proc.info.uid);
+            item.changes = ProcessChangeItem.CHANGE_FOREGROUND_SERVICES;
+            item.foregroundServiceTypes = fgServiceTypes;
+
             if (oomAdj) {
                 updateOomAdjLocked();
             }
         }
-
-        if (proc.getForegroundServiceTypes() != fgServiceTypes) {
-            proc.setReportedForegroundServiceTypes(fgServiceTypes);
-            ProcessChangeItem item = enqueueProcessChangeItemLocked(proc.info.uid, proc.pid);
-            item.changes = ProcessChangeItem.CHANGE_FOREGROUND_SERVICES;
-            item.foregroundServiceTypes = fgServiceTypes;
-        }
     }
 
     // TODO(b/111541062): This method is only used for updating OOM adjustments. We need to update
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index cc90182..d1379b6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -16,7 +16,7 @@
 
 package com.android.server.am;
 
-import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
+import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
 import static android.app.ActivityTaskManager.RESIZE_MODE_USER;
@@ -306,9 +306,7 @@
         mSamplingInterval = 0;
         mAutoStop = false;
         mStreaming = false;
-        mUserId = mInternal.mUserController.handleIncomingUser(Binder.getCallingPid(),
-            Binder.getCallingUid(), defUser, false, ALLOW_FULL_ONLY,
-            "ActivityManagerShellCommand", null);
+        mUserId = defUser;
         mDisplayId = INVALID_DISPLAY;
         mWindowingMode = WINDOWING_MODE_UNDEFINED;
         mActivityType = ACTIVITY_TYPE_UNDEFINED;
@@ -430,8 +428,12 @@
                 if (intent.getComponent() != null) {
                     packageName = intent.getComponent().getPackageName();
                 } else {
+                    // queryIntentActivities does not convert user id, so we convert it here first
+                    int userIdForQuery = mInternal.mUserController.handleIncomingUser(
+                            Binder.getCallingPid(), Binder.getCallingUid(), mUserId, false,
+                            ALLOW_NON_FULL, "ActivityManagerShellCommand", null);
                     List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0,
-                            mUserId).getList();
+                            userIdForQuery).getList();
                     if (activities == null || activities.size() <= 0) {
                         getErrPrintWriter().println("Error: Intent does not match any activities: "
                                 + intent);
diff --git a/services/core/java/com/android/server/am/AppCompactor.java b/services/core/java/com/android/server/am/AppCompactor.java
index f58fb95..ac10026 100644
--- a/services/core/java/com/android/server/am/AppCompactor.java
+++ b/services/core/java/com/android/server/am/AppCompactor.java
@@ -485,9 +485,10 @@
                         long zramFreeKbAfter = Debug.getZramFreeKb();
                         EventLog.writeEvent(EventLogTags.AM_COMPACT, pid, name, action,
                                 rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3],
-                                rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], time,
+                                rssAfter[0] - rssBefore[0], rssAfter[1] - rssBefore[1],
+                                rssAfter[2] - rssBefore[2], rssAfter[3] - rssBefore[3], time,
                                 lastCompactAction, lastCompactTime, msg.arg1, msg.arg2,
-                                zramFreeKbBefore, zramFreeKbAfter);
+                                zramFreeKbBefore, zramFreeKbAfter - zramFreeKbBefore);
                         // Note that as above not taking mPhenoTypeFlagLock here to avoid locking
                         // on every single compaction for a flag that will seldom change and the
                         // impact of reading the wrong value here is low.
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index ea23081..4bfbb78 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -460,10 +460,9 @@
                 // that request - we don't want the token to be swept from under our feet...
                 mHandler.removeCallbacksAndMessages(msgToken);
                 // ...then schedule the removal of the token after the extended timeout
+                final ProcessRecord app = r.curApp;
                 mHandler.postAtTime(() -> {
-                    if (r.curApp != null) {
-                        r.curApp.removeAllowBackgroundActivityStartsToken(r);
-                    }
+                    app.removeAllowBackgroundActivityStartsToken(r);
                 }, msgToken, (r.receiverTime + mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT));
             }
         }
diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java
index a1c941e..fe95542 100644
--- a/services/core/java/com/android/server/am/ConnectionRecord.java
+++ b/services/core/java/com/android/server/am/ConnectionRecord.java
@@ -109,6 +109,14 @@
         clientPackageName = _clientPackageName;
     }
 
+    public boolean hasFlag(final int flag) {
+        return (flags & flag) != 0;
+    }
+
+    public boolean notHasFlag(final int flag) {
+        return (flags & flag) == 0;
+    }
+
     public void startAssociationIfNeeded() {
         // If we don't already have an active association, create one...  but only if this
         // is an association between two different processes.
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 06d0152..cb587de 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -58,6 +58,8 @@
         sGlobalSettingToTypeMap.put(
                 Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, String.class);
         sGlobalSettingToTypeMap.put(
+                Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE, String.class);
+        sGlobalSettingToTypeMap.put(
                 Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE, String.class);
         sGlobalSettingToTypeMap.put(
                 Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS, String.class);
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index 4b12e43..e65a4e5 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -138,4 +138,4 @@
 30061 am_remove_task (Task ID|1|5), (Stack ID|1|5)
 
 # The task is being compacted
-30063 am_compact (Pid|1|5),(Process Name|3),(Action|3),(BeforeRssTotal|2|2),(BeforeRssFile|2|2),(BeforeRssAnon|2|2),(BeforeRssSwap|2|2),(AfterRssTotal|2|2),(AfterRssFile|2|2),(AfterRssAnon|2|2),(AfterRssSwap|2|2),(Time|2|3),(LastAction|1|2),(LastActionTimestamp|2|3),(setAdj|1|2),(procState|1|2),(BeforeZRAMFree|2|2),(AfterZRAMFree|2|2)
+30063 am_compact (Pid|1|5),(Process Name|3),(Action|3),(BeforeRssTotal|2|2),(BeforeRssFile|2|2),(BeforeRssAnon|2|2),(BeforeRssSwap|2|2),(DeltaRssTotal|2|2),(DeltaRssFile|2|2),(DeltaRssAnon|2|2),(DeltaRssSwap|2|2),(Time|2|3),(LastAction|1|2),(LastActionTimestamp|2|3),(setAdj|1|2),(procState|1|2),(BeforeZRAMFree|2|2),(DeltaZRAMFree|2|2)
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index c1b9a20..5d47c9d 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -16,10 +16,19 @@
 
 package com.android.server.am;
 
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
 import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
+import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
+import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
 import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_TOP;
+import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
 import static android.os.Process.SCHED_OTHER;
 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
 import static android.os.Process.THREAD_GROUP_DEFAULT;
@@ -53,12 +62,14 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.Debug;
+import android.os.IBinder;
 import android.os.PowerManagerInternal;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
@@ -411,7 +422,7 @@
                             app.kill("cached #" + numCached, true);
                         }
                         break;
-                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
+                    case PROCESS_STATE_CACHED_EMPTY:
                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
                                 && app.lastActivityTime < oldTime) {
                             app.kill("empty for "
@@ -716,7 +727,7 @@
         if (app.thread == null) {
             app.adjSeq = mAdjSeq;
             app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_BACKGROUND);
-            app.setCurProcState(ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+            app.setCurProcState(PROCESS_STATE_CACHED_EMPTY);
             app.curAdj = ProcessList.CACHED_APP_MAX_ADJ;
             app.setCurRawAdj(ProcessList.CACHED_APP_MAX_ADJ);
             app.completedAdjSeq = app.adjSeq;
@@ -771,7 +782,7 @@
                     app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP);
                 } else {
                     // screen off, restrict UI scheduling
-                    app.setCurProcState(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
+                    app.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
                     app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED);
                 }
             }
@@ -795,7 +806,7 @@
 
         boolean foregroundActivities = false;
         mTmpBroadcastQueue.clear();
-        if (PROCESS_STATE_CUR_TOP == ActivityManager.PROCESS_STATE_TOP && app == TOP_APP) {
+        if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == TOP_APP) {
             // The last app on the list is the foreground app.
             adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
@@ -818,7 +829,7 @@
             adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
             app.adjType = "instrumentation";
-            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+            procState = PROCESS_STATE_FOREGROUND_SERVICE;
             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app);
             }
@@ -842,7 +853,7 @@
             schedGroup = app.execServicesFg ?
                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
             app.adjType = "exec-service";
-            procState = ActivityManager.PROCESS_STATE_SERVICE;
+            procState = PROCESS_STATE_SERVICE;
             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app);
             }
@@ -862,7 +873,7 @@
             // At this point we don't actually know the adjustment.  Use the cached adj
             // value that the caller wants us to.
             adj = cachedAdj;
-            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+            procState = PROCESS_STATE_CACHED_EMPTY;
             app.cached = true;
             app.empty = true;
             app.adjType = "cch-empty";
@@ -897,23 +908,28 @@
         }
 
         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
-                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION) {
+                || procState > PROCESS_STATE_FOREGROUND_SERVICE_LOCATION) {
             if (app.hasForegroundServices()) {
                 // The user is aware of this app, so make it visible.
                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
-                procState = app.hasLocationForegroundServices()
-                        ? ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
-                        : ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+                if (app.hasLocationForegroundServices()) {
+                    procState = PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
+                    app.adjType = "fg-service-location";
+
+                } else {
+                    procState = PROCESS_STATE_FOREGROUND_SERVICE;
+                    app.adjType = "fg-service";
+                }
                 app.cached = false;
-                app.adjType = "fg-service";
                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
-                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app);
+                    reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + app.adjType + ": "
+                            + app + " ");
                 }
             } else if (app.hasOverlayUi()) {
                 // The process is display an overlay UI.
                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
-                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                procState = PROCESS_STATE_IMPORTANT_FOREGROUND;
                 app.cached = false;
                 app.adjType = "has-overlay-ui";
                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
@@ -928,7 +944,7 @@
         // services so that it can finish performing any persistence/processing of in-memory state.
         if (app.hasForegroundServices() && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
                 && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now
-                || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) {
+                || app.setProcState <= PROCESS_STATE_TOP)) {
             adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
             app.adjType = "fg-service-act";
             if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -937,13 +953,13 @@
         }
 
         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
-                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
+                || procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
             if (app.forcingToImportant != null) {
                 // This is currently used for toasts...  they are not interactive, and
                 // we don't want them to cause the app to become fully foreground (and
                 // thus out of background check), so we yes the best background level we can.
                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
-                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
+                procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
                 app.cached = false;
                 app.adjType = "force-imp";
                 app.adjSource = app.forcingToImportant;
@@ -1039,8 +1055,8 @@
             if (adj > ProcessList.BACKUP_APP_ADJ) {
                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
                 adj = ProcessList.BACKUP_APP_ADJ;
-                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
-                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
+                if (procState > PROCESS_STATE_TRANSIENT_BACKGROUND) {
+                    procState = PROCESS_STATE_TRANSIENT_BACKGROUND;
                 }
                 app.adjType = "backup";
                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1057,21 +1073,16 @@
             }
         }
 
-        boolean mayBeTop = false;
-        String mayBeTopType = null;
-        Object mayBeTopSource = null;
-        Object mayBeTopTarget = null;
-
         for (int is = app.services.size() - 1;
                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
-                        || procState > ActivityManager.PROCESS_STATE_TOP);
+                        || procState > PROCESS_STATE_TOP);
                 is--) {
             ServiceRecord s = app.services.valueAt(is);
             if (s.startRequested) {
                 app.hasStartedServices = true;
-                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
-                    procState = ActivityManager.PROCESS_STATE_SERVICE;
+                if (procState > PROCESS_STATE_SERVICE) {
+                    procState = PROCESS_STATE_SERVICE;
                     app.adjType = "started-services";
                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
@@ -1110,16 +1121,17 @@
                 }
             }
 
-            for (int conni = s.connections.size() - 1;
+            ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections();
+            for (int conni = serviceConnections.size() - 1;
                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
-                            || procState > ActivityManager.PROCESS_STATE_TOP);
+                            || procState > PROCESS_STATE_TOP);
                     conni--) {
-                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
+                ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni);
                 for (int i = 0;
                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
-                                || procState > ActivityManager.PROCESS_STATE_TOP);
+                                || procState > PROCESS_STATE_TOP);
                         i++) {
                     // XXX should compute this based on the max of
                     // all connected clients.
@@ -1145,7 +1157,7 @@
                             // If the other app is cached for any reason, for purposes here
                             // we are going to consider it empty.  The specific cached state
                             // doesn't propagate except under certain conditions.
-                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+                            clientProcState = PROCESS_STATE_CACHED_EMPTY;
                         }
                         String adjType = null;
                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
@@ -1216,6 +1228,7 @@
                                     newAdj = clientAdj;
                                 } else {
                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
+                                        // TODO: Is this too limiting for apps bound from TOP?
                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
                                     } else {
                                         newAdj = adj;
@@ -1244,55 +1257,50 @@
                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                                 }
                             }
-                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
-                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
-                                    // Special handling of clients who are in the top state.
-                                    // We *may* want to consider this process to be in the
-                                    // top state as well, but only if there is not another
-                                    // reason for it to be running.  Being on the top is a
-                                    // special state, meaning you are specifically running
-                                    // for the current top app.  If the process is already
-                                    // running in the background for some other reason, it
-                                    // is more important to continue considering it to be
-                                    // in the background state.
-                                    mayBeTop = true;
-                                    mayBeTopType = "service";
-                                    mayBeTopSource = cr.binding.client;
-                                    mayBeTopTarget = s.instanceName;
-                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+                            if (clientProcState < PROCESS_STATE_TOP) {
+                                // Special handling for above-top states (persistent
+                                // processes).  These should not bring the current process
+                                // into the top state, since they are not on top.  Instead
+                                // give them the best bound state after that.
+                                if ((cr.flags & Context.BIND_FOREGROUND_SERVICE) != 0) {
+                                    clientProcState =
+                                            PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+                                } else if (mService.mWakefulness
+                                        == PowerManagerInternal.WAKEFULNESS_AWAKE
+                                        && (cr.flags & Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
+                                                != 0) {
+                                    clientProcState =
+                                            PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                                 } else {
-                                    // Special handling for above-top states (persistent
-                                    // processes).  These should not bring the current process
-                                    // into the top state, since they are not on top.  Instead
-                                    // give them the best state after that.
-                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
-                                        clientProcState =
-                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
-                                    } else if (mService.mWakefulness
-                                            == PowerManagerInternal.WAKEFULNESS_AWAKE &&
-                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
-                                                    != 0) {
-                                        clientProcState =
-                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
-                                    } else {
-                                        clientProcState =
-                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
-                                    }
+                                    clientProcState =
+                                            PROCESS_STATE_IMPORTANT_FOREGROUND;
+                                }
+                            } else if (clientProcState == PROCESS_STATE_TOP) {
+                                if (cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
+                                    // Go at most to BOUND_TOP, unless requested to elevate
+                                    // to client's state.
+                                    clientProcState = PROCESS_STATE_BOUND_TOP;
+                                }
+                            } else if (clientProcState
+                                    <= PROCESS_STATE_FOREGROUND_SERVICE) {
+                                if (cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
+                                    clientProcState = PROCESS_STATE_FOREGROUND_SERVICE;
                                 }
                             }
                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
                             if (clientProcState <
-                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
+                                    PROCESS_STATE_TRANSIENT_BACKGROUND) {
                                 clientProcState =
-                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
+                                        PROCESS_STATE_TRANSIENT_BACKGROUND;
                             }
                         } else {
                             if (clientProcState <
-                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
+                                    PROCESS_STATE_IMPORTANT_BACKGROUND) {
                                 clientProcState =
-                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
+                                        PROCESS_STATE_IMPORTANT_BACKGROUND;
                             }
                         }
+
                         if (schedGroup < ProcessList.SCHED_GROUP_TOP_APP
                                 && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) {
                             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
@@ -1301,6 +1309,7 @@
                         if (!trackedProcState) {
                             cr.trackProcState(clientProcState, mAdjSeq, now);
                         }
+
                         if (procState > clientProcState) {
                             procState = clientProcState;
                             app.setCurRawProcState(procState);
@@ -1308,7 +1317,7 @@
                                 adjType = "service";
                             }
                         }
-                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+                        if (procState < PROCESS_STATE_IMPORTANT_BACKGROUND
                                 && (cr.flags & Context.BIND_SHOWING_UI) != 0) {
                             app.setPendingUiClean(true);
                         }
@@ -1363,13 +1372,13 @@
         for (int provi = app.pubProviders.size() - 1;
                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
-                        || procState > ActivityManager.PROCESS_STATE_TOP);
+                        || procState > PROCESS_STATE_TOP);
                 provi--) {
             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
             for (int i = cpr.connections.size() - 1;
                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
-                            || procState > ActivityManager.PROCESS_STATE_TOP);
+                            || procState > PROCESS_STATE_TOP);
                     i--) {
                 ContentProviderConnection conn = cpr.connections.get(i);
                 ProcessRecord client = conn.client;
@@ -1389,7 +1398,7 @@
                 if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
                     // If the other app is cached for any reason, for purposes here
                     // we are going to consider it empty.
-                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+                    clientProcState = PROCESS_STATE_CACHED_EMPTY;
                 }
                 String adjType = null;
                 if (adj > clientAdj) {
@@ -1404,34 +1413,18 @@
                     }
                     app.cached &= client.cached;
                 }
-                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
-                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
-                        // Special handling of clients who are in the top state.
-                        // We *may* want to consider this process to be in the
-                        // top state as well, but only if there is not another
-                        // reason for it to be running.  Being on the top is a
-                        // special state, meaning you are specifically running
-                        // for the current top app.  If the process is already
-                        // running in the background for some other reason, it
-                        // is more important to continue considering it to be
-                        // in the background state.
-                        mayBeTop = true;
-                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
-                        mayBeTopType = adjType = "provider-top";
-                        mayBeTopSource = client;
-                        mayBeTopTarget = cpr.name;
+
+                if (clientProcState <= PROCESS_STATE_FOREGROUND_SERVICE) {
+                    if (adjType == null) {
+                        adjType = "provider";
+                    }
+                    if (clientProcState == PROCESS_STATE_TOP) {
+                        clientProcState = PROCESS_STATE_BOUND_TOP;
                     } else {
-                        // Special handling for above-top states (persistent
-                        // processes).  These should not bring the current process
-                        // into the top state, since they are not on top.  Instead
-                        // give them the best state after that.
-                        clientProcState =
-                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
-                        if (adjType == null) {
-                            adjType = "provider";
-                        }
+                        clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
                     }
                 }
+
                 conn.trackProcState(clientProcState, mAdjSeq, now);
                 if (procState > clientProcState) {
                     procState = clientProcState;
@@ -1471,8 +1464,8 @@
                                 "Raise adj to external provider: " + app);
                     }
                 }
-                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
-                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                if (procState > PROCESS_STATE_IMPORTANT_FOREGROUND) {
+                    procState = PROCESS_STATE_IMPORTANT_FOREGROUND;
                     app.setCurRawProcState(procState);
                     if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                         reportOomAdjMessageLocked(TAG_OOM_ADJ,
@@ -1504,53 +1497,7 @@
             }
         }
 
-        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
-            // A client of one of our services or providers is in the top state.  We
-            // *may* want to be in the top state, but not if we are already running in
-            // the background for some other reason.  For the decision here, we are going
-            // to pick out a few specific states that we want to remain in when a client
-            // is top (states that tend to be longer-term) and otherwise allow it to go
-            // to the top state.
-            switch (procState) {
-                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
-                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
-                case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
-                    // Something else is keeping it at this level, just leave it.
-                    break;
-                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
-                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
-                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
-                case ActivityManager.PROCESS_STATE_SERVICE:
-                    // These all are longer-term states, so pull them up to the top
-                    // of the background states, but not all the way to the top state.
-                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
-                    app.adjType = mayBeTopType;
-                    app.adjSource = mayBeTopSource;
-                    app.adjTarget = mayBeTopTarget;
-                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
-                        reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
-                                + ": " + app + ", due to " + mayBeTopSource
-                                + " adj=" + adj + " procState="
-                                + ProcessList.makeProcStateString(procState));
-                    }
-                    break;
-                default:
-                    // Otherwise, top is a better choice, so take it.
-                    procState = ActivityManager.PROCESS_STATE_TOP;
-                    app.adjType = mayBeTopType;
-                    app.adjSource = mayBeTopSource;
-                    app.adjTarget = mayBeTopTarget;
-                    if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
-                        reportOomAdjMessageLocked(TAG_OOM_ADJ, "May be top raise to " + mayBeTopType
-                                + ": " + app + ", due to " + mayBeTopSource
-                                + " adj=" + adj + " procState="
-                                + ProcessList.makeProcStateString(procState));
-                    }
-                    break;
-            }
-        }
-
-        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
+        if (procState >= PROCESS_STATE_CACHED_EMPTY) {
             if (app.hasClientActivities()) {
                 // This is a cached process, but with client activities.  Mark it so.
                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
@@ -1604,8 +1551,8 @@
 
         // Put bound foreground services in a special sched group for additional
         // restrictions on screen off
-        if (procState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE &&
-                mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
+        if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE
+                && mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
             if (schedGroup > ProcessList.SCHED_GROUP_RESTRICTED) {
                 schedGroup = ProcessList.SCHED_GROUP_RESTRICTED;
             }
@@ -1902,8 +1849,8 @@
                         + " (" + app.getCurProcState() + ")" + ": " + app.adjType;
                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
             }
-            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
-            boolean curImportant = app.getCurProcState() < ActivityManager.PROCESS_STATE_SERVICE;
+            boolean setImportant = app.setProcState < PROCESS_STATE_SERVICE;
+            boolean curImportant = app.getCurProcState() < PROCESS_STATE_SERVICE;
             if (setImportant && !curImportant) {
                 // This app is no longer something we consider important enough to allow to use
                 // arbitrary amounts of battery power. Note its current CPU time to later know to
@@ -1966,10 +1913,11 @@
         // To avoid some abuse patterns, we are going to be careful about what we consider
         // to be an app interaction.  Being the top activity doesn't count while the display
         // is sleeping, nor do short foreground services.
-        if (app.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP) {
+        if (app.getCurProcState() <= PROCESS_STATE_TOP
+                || app.getCurProcState() == PROCESS_STATE_BOUND_TOP) {
             isInteraction = true;
             app.setFgInteractionTime(0);
-        } else if (app.getCurProcState() <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
+        } else if (app.getCurProcState() <= PROCESS_STATE_FOREGROUND_SERVICE) {
             if (app.getFgInteractionTime() == 0) {
                 app.setFgInteractionTime(nowElapsed);
                 isInteraction = false;
@@ -1979,7 +1927,7 @@
             }
         } else {
             isInteraction =
-                    app.getCurProcState() <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                    app.getCurProcState() <= PROCESS_STATE_IMPORTANT_FOREGROUND;
             app.setFgInteractionTime(0);
         }
         if (isInteraction
@@ -2001,8 +1949,8 @@
     }
 
     private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) {
-        if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP
-                && app.getCurProcState() > ActivityManager.PROCESS_STATE_TOP) {
+        if (app.setProcState <= PROCESS_STATE_TOP
+                && app.getCurProcState() > PROCESS_STATE_TOP) {
             app.lastTopTime = nowUptime;
         }
     }
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index d02fd73..f1f40d4 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -769,6 +769,9 @@
             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
                 procState = "FGSL";
                 break;
+            case ActivityManager.PROCESS_STATE_BOUND_TOP:
+                procState = "BTOP";
+                break;
             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
                 procState = "FGS ";
                 break;
@@ -836,6 +839,9 @@
             case ActivityManager.PROCESS_STATE_TOP:
                 return AppProtoEnums.PROCESS_STATE_TOP;
             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
+                return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
+            case ActivityManager.PROCESS_STATE_BOUND_TOP:
+                return AppProtoEnums.PROCESS_STATE_BOUND_TOP;
             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
                 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
@@ -966,6 +972,7 @@
         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP
         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
+        PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_BOUND_TOP
         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 17b244c..ce13cd8 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -259,6 +259,8 @@
     // A set of tokens that currently contribute to this process being temporarily whitelisted
     // to start activities even if it's not in the foreground
     final ArraySet<Binder> mAllowBackgroundActivityStartsTokens = new ArraySet<>();
+    // a set of UIDs of all bound clients
+    private ArraySet<Integer> mBoundClientUids = new ArraySet<>();
 
     String isolatedEntryPoint;  // Class to run on start if this is a special isolated process.
     String[] isolatedEntryPointArgs; // Arguments to pass to isolatedEntryPoint's main().
@@ -561,6 +563,13 @@
                 pw.print(prefix); pw.print("  - "); pw.println(receivers.valueAt(i));
             }
         }
+        if (mAllowBackgroundActivityStartsTokens.size() > 0) {
+            pw.print(prefix); pw.println("Background activity start whitelist tokens:");
+            for (int i = 0; i < mAllowBackgroundActivityStartsTokens.size(); i++) {
+                pw.print(prefix); pw.print("  - ");
+                pw.println(mAllowBackgroundActivityStartsTokens.valueAt(i));
+            }
+        }
     }
 
     ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
@@ -1186,6 +1195,53 @@
                 !mAllowBackgroundActivityStartsTokens.isEmpty());
     }
 
+    void addBoundClientUids(ArraySet<Integer> clientUids) {
+        mBoundClientUids.addAll(clientUids);
+        mWindowProcessController.setBoundClientUids(mBoundClientUids);
+    }
+
+    void updateBoundClientUids() {
+        if (services.isEmpty()) {
+            clearBoundClientUids();
+            return;
+        }
+        // grab a set of clientUids of all connections of all services
+        ArraySet<Integer> boundClientUids = new ArraySet<>();
+        final int K = services.size();
+        for (int j = 0; j < K; j++) {
+            ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns =
+                    services.valueAt(j).getConnections();
+            final int N = conns.size();
+            for (int conni = 0; conni < N; conni++) {
+                ArrayList<ConnectionRecord> c = conns.valueAt(conni);
+                for (int i = 0; i < c.size(); i++) {
+                    boundClientUids.add(c.get(i).clientUid);
+                }
+            }
+        }
+        mBoundClientUids = boundClientUids;
+        mWindowProcessController.setBoundClientUids(mBoundClientUids);
+    }
+
+    void addBoundClientUidsOfNewService(ServiceRecord sr) {
+        if (sr == null) {
+            return;
+        }
+        ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns = sr.getConnections();
+        for (int conni = conns.size() - 1; conni >= 0; conni--) {
+            ArrayList<ConnectionRecord> c = conns.valueAt(conni);
+            for (int i = 0; i < c.size(); i++) {
+                mBoundClientUids.add(c.get(i).clientUid);
+            }
+        }
+        mWindowProcessController.setBoundClientUids(mBoundClientUids);
+    }
+
+    void clearBoundClientUids() {
+        mBoundClientUids.clear();
+        mWindowProcessController.setBoundClientUids(mBoundClientUids);
+    }
+
     void setActiveInstrumentation(ActiveInstrumentation instr) {
         mInstr = instr;
         boolean isInstrumenting = instr != null;
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index eeaa7de..217fd6d 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -38,6 +38,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
@@ -88,7 +89,7 @@
     final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
             = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
                             // All active bindings to the service.
-    final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections
+    private final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections
             = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
                             // IBinder -> ConnectionRecord of all bound clients
 
@@ -542,6 +543,7 @@
             }
         } else if (app != null) {
             app.removeAllowBackgroundActivityStartsToken(this);
+            app.updateBoundClientUids();
         }
         app = _proc;
         if (pendingConnectionGroup > 0 && _proc != null) {
@@ -563,6 +565,33 @@
                 }
             }
         }
+        if (_proc != null) {
+            _proc.updateBoundClientUids();
+        }
+    }
+
+    ArrayMap<IBinder, ArrayList<ConnectionRecord>> getConnections() {
+        return connections;
+    }
+
+    void putConnection(IBinder binder, ArrayList<ConnectionRecord> clist) {
+        connections.put(binder, clist);
+        // if we have a process attached, add bound client uids of this connection to it
+        if (app != null) {
+            ArraySet<Integer> boundClientUids = new ArraySet<>();
+            for (int i = 0; i < clist.size(); i++) {
+                boundClientUids.add(clist.get(i).clientUid);
+            }
+            app.addBoundClientUids(boundClientUids);
+        }
+    }
+
+    void removeConnection(IBinder binder) {
+        connections.remove(binder);
+        // if we have a process attached, tell it to update the state of bound clients
+        if (app != null) {
+            app.updateBoundClientUids();
+        }
     }
 
     void updateHasBindingWhitelistingBgActivityStarts() {
diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING
index 117174a..f198464 100644
--- a/services/core/java/com/android/server/am/TEST_MAPPING
+++ b/services/core/java/com/android/server/am/TEST_MAPPING
@@ -27,6 +27,21 @@
           "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
+    },
+    {
+      "name": "FrameworksMockingServicesTests",
+      "file_patterns": ["AppCompactor\\.java"],
+      "options": [
+        {
+          "include-filter": "com.android.server.am."
+        },
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
     }
   ],
   "postsubmit": [
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 07c9cca..2bd9198 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -241,6 +241,20 @@
 
     volatile boolean mBootCompleted;
 
+    /**
+     * In this mode, user is always stopped when switched out but locking of user data is
+     * postponed until total number of unlocked users in the system reaches mMaxRunningUsers.
+     * Once total number of unlocked users reach mMaxRunningUsers, least recentely used user
+     * will be locked.
+     */
+    boolean mDelayUserDataLocking;
+    /**
+     * Keep track of last active users for mDelayUserDataLocking.
+     * The latest stopped user is placed in front while the least recently stopped user in back.
+     */
+    @GuardedBy("mLock")
+    private final ArrayList<Integer> mLastActiveUsers = new ArrayList<>();
+
     UserController(ActivityManagerService service) {
         this(new Injector(service));
     }
@@ -738,7 +752,9 @@
     void finishUserStopped(UserState uss) {
         final int userId = uss.mHandle.getIdentifier();
         final boolean stopped;
+        boolean lockUser = true;
         ArrayList<IStopUserCallback> callbacks;
+        int userIdToLock = userId;
         synchronized (mLock) {
             callbacks = new ArrayList<>(uss.mStopCallbacks);
             if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) {
@@ -749,9 +765,12 @@
                 mStartedUsers.remove(userId);
                 mUserLru.remove(Integer.valueOf(userId));
                 updateStartedUserArrayLU();
+                userIdToLock = updateUserToLockLU(userId);
+                if (userIdToLock == UserHandle.USER_NULL) {
+                    lockUser = false;
+                }
             }
         }
-
         if (stopped) {
             mInjector.getUserManagerInternal().removeUserState(userId);
             mInjector.activityManagerOnUserStopped(userId);
@@ -776,18 +795,22 @@
                 mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
             }
 
+            if (!lockUser) {
+                return;
+            }
+            final int userIdToLockF = userIdToLock;
             // Evict the user's credential encryption key. Performed on FgThread to make it
             // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking
             // to prevent data corruption.
             FgThread.getHandler().post(() -> {
                 synchronized (mLock) {
-                    if (mStartedUsers.get(userId) != null) {
+                    if (mStartedUsers.get(userIdToLockF) != null) {
                         Slog.w(TAG, "User was restarted, skipping key eviction");
                         return;
                     }
                 }
                 try {
-                    getStorageManager().lockUserKey(userId);
+                    mInjector.getStorageManager().lockUserKey(userIdToLockF);
                 } catch (RemoteException re) {
                     throw re.rethrowAsRuntimeException();
                 }
@@ -796,6 +819,39 @@
     }
 
     /**
+     * For mDelayUserDataLocking mode, storage once unlocked is kept unlocked.
+     * Total number of unlocked user storage is limited by mMaxRunningUsers.
+     * If there are more unlocked users, evict and lock the least recently stopped user and
+     * lock that user's data. Regardless of the mode, ephemeral user is always locked
+     * immediately.
+     *
+     * @return user id to lock. UserHandler.USER_NULL will be returned if no user should be locked.
+     */
+    @GuardedBy("mLock")
+    private int updateUserToLockLU(int userId) {
+        int userIdToLock = userId;
+        if (mDelayUserDataLocking && !getUserInfo(userId).isEphemeral()
+                && !hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, userId)) {
+            mLastActiveUsers.remove((Integer) userId); // arg should be object, not index
+            mLastActiveUsers.add(0, userId);
+            int totalUnlockedUsers = mStartedUsers.size() + mLastActiveUsers.size();
+            if (totalUnlockedUsers > mMaxRunningUsers) { // should lock a user
+                userIdToLock = mLastActiveUsers.get(mLastActiveUsers.size() - 1);
+                mLastActiveUsers.remove(mLastActiveUsers.size() - 1);
+                Slog.i(TAG, "finishUserStopped, stopping user:" + userId
+                        + " lock user:" + userIdToLock);
+            } else {
+                Slog.i(TAG, "finishUserStopped, user:" + userId
+                        + ",skip locking");
+                // do not lock
+                userIdToLock = UserHandle.USER_NULL;
+
+            }
+        }
+        return userIdToLock;
+    }
+
+    /**
      * Determines the list of users that should be stopped together with the specified
      * {@code userId}. The returned list includes {@code userId}.
      */
@@ -896,9 +952,6 @@
         }
     }
 
-    private IStorageManager getStorageManager() {
-        return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
-    }
     boolean startUser(final int userId, final boolean foreground) {
         return startUser(userId, foreground, null);
     }
@@ -956,15 +1009,26 @@
             final int oldUserId = getCurrentUserId();
             if (oldUserId == userId) {
                 final UserState state = getStartedUserState(userId);
-                if (state != null && state.state == STATE_RUNNING_UNLOCKED) {
-                    // We'll skip all later code, so we must tell listener it's already unlocked.
-                    try {
-                        unlockListener.onFinished(userId, null);
-                    } catch (RemoteException ignore) {
-                        // Ignore.
+                if (state == null) {
+                    Slog.wtf(TAG, "Current user has no UserState");
+                    // continue starting.
+                } else {
+                    if (userId == UserHandle.USER_SYSTEM && state.state == STATE_BOOTING) {
+                        // system user start explicitly requested. should continue starting as it
+                        // is not in running state.
+                    } else {
+                        if (state.state == STATE_RUNNING_UNLOCKED) {
+                            // We'll skip all later code, so we must tell listener it's already
+                            // unlocked.
+                            try {
+                                unlockListener.onFinished(userId, null);
+                            } catch (RemoteException ignore) {
+                                // Ignore.
+                            }
+                        }
+                        return true;
                     }
                 }
-                return true;
             }
 
             if (foreground) {
@@ -1188,7 +1252,7 @@
         UserState uss;
         if (!StorageManager.isUserKeyUnlocked(userId)) {
             final UserInfo userInfo = getUserInfo(userId);
-            final IStorageManager storageManager = getStorageManager();
+            final IStorageManager storageManager = mInjector.getStorageManager();
             try {
                 // We always want to unlock user storage, even user is not started yet
                 storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
@@ -1323,9 +1387,9 @@
         if (oldUserId == UserHandle.USER_SYSTEM) {
             return;
         }
-        // For now, only check for user restriction. Additional checks can be added here
+        // If running in background is disabled or mDelayUserDataLocking mode, stop the user.
         boolean disallowRunInBg = hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND,
-                oldUserId);
+                oldUserId) || mDelayUserDataLocking;
         if (!disallowRunInBg) {
             return;
         }
@@ -1743,6 +1807,24 @@
         return state.state != UserState.STATE_STOPPING && state.state != UserState.STATE_SHUTDOWN;
     }
 
+    /**
+     * Check if system user is already started. Unlike other user, system user is in STATE_BOOTING
+     * even if it is not explicitly started. So isUserRunning cannot give the right state
+     * to check if system user is started or not.
+     * @return true if system user is started.
+     */
+    boolean isSystemUserStarted() {
+        synchronized (mLock) {
+            UserState uss = mStartedUsers.get(UserHandle.USER_SYSTEM);
+            if (uss == null) {
+                return false;
+            }
+            return uss.state == UserState.STATE_RUNNING_LOCKED
+                || uss.state == UserState.STATE_RUNNING_UNLOCKING
+                || uss.state == UserState.STATE_RUNNING_UNLOCKED;
+        }
+    }
+
     UserInfo getCurrentUser() {
         if ((mInjector.checkCallingPermission(INTERACT_ACROSS_USERS)
                 != PackageManager.PERMISSION_GRANTED) && (
@@ -2004,6 +2086,8 @@
                     pw.println(mUserProfileGroupIds.valueAt(i));
                 }
             }
+            pw.println("  mCurrentUserId:" + mCurrentUserId);
+            pw.println("  mLastActiveUsers:" + mLastActiveUsers);
         }
     }
 
@@ -2297,5 +2381,9 @@
         protected boolean isCallerRecents(int callingUid) {
             return mService.mAtmInternal.isCallerRecents(callingUid);
         }
+
+        protected IStorageManager getStorageManager() {
+            return IStorageManager.Stub.asInterface(ServiceManager.getService("mount"));
+        }
     }
 }
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 2e5dd3b..c9e7cfa 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -153,6 +153,7 @@
         UID_STATE_TOP,                  // ActivityManager.PROCESS_STATE_TOP
         UID_STATE_FOREGROUND_SERVICE_LOCATION,
                                         // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
+        UID_STATE_FOREGROUND,           // ActivityManager.PROCESS_STATE_BOUND_TOP
         UID_STATE_FOREGROUND_SERVICE,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
         UID_STATE_FOREGROUND,           // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
         UID_STATE_FOREGROUND,           // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 1681c5b..bc78d1a 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -19,6 +19,7 @@
 import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
 import static android.provider.Settings.System.ADAPTIVE_SLEEP;
 import static android.service.attention.AttentionService.ATTENTION_FAILURE_CANCELLED;
+import static android.service.attention.AttentionService.ATTENTION_FAILURE_UNKNOWN;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -249,6 +250,7 @@
                 if (userState.mPendingAttentionCheck != null
                         && userState.mPendingAttentionCheck.mCallbackInternal.equals(
                         callbackInternal)) {
+                    userState.mPendingAttentionCheck.cancel(ATTENTION_FAILURE_UNKNOWN);
                     userState.mPendingAttentionCheck = null;
                 }
                 return;
@@ -624,7 +626,7 @@
             if (userState == null) {
                 return;
             }
-            cancel(userState, AttentionService.ATTENTION_FAILURE_UNKNOWN);
+            cancel(userState, ATTENTION_FAILURE_UNKNOWN);
 
             mContext.unbindService(userState.mConnection);
             userState.mConnection.cleanupService();
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 5ec8cfa..5f624ba 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -896,7 +896,7 @@
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
+            ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_CURRENT);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 93f7831..32781a9 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -640,6 +640,26 @@
         sAudioVolumeGroups = new AudioVolumeGroups();
 
         // Initialize volume
+        // Priority 1 - Android Property
+        // Priority 2 - Audio Policy Service
+        // Priority 3 - Default Value
+        if (sAudioProductStrategies.size() > 0) {
+            int numStreamTypes = AudioSystem.getNumStreamTypes();
+
+            for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
+                AudioAttributes attr =
+                        sAudioProductStrategies.getAudioAttributesForLegacyStreamType(streamType);
+                int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
+                if (maxVolume != -1) {
+                    MAX_STREAM_VOLUME[streamType] = maxVolume;
+                }
+                int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
+                if (minVolume != -1) {
+                    MIN_STREAM_VOLUME[streamType] = minVolume;
+                }
+            }
+        }
+
         int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
         if (maxCallVolume != -1) {
             MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
@@ -1468,6 +1488,11 @@
     }
 
     private int rescaleIndex(int index, int srcStream, int dstStream) {
+        int max = mStreamStates[srcStream].getMaxIndex();
+        if (max == 0) {
+            Log.e(TAG, "rescaleIndex : Max index should not be zero");
+            return mStreamStates[srcStream].getMinIndex();
+        }
         final int rescaled =
                 (index * mStreamStates[dstStream].getMaxIndex()
                         + mStreamStates[srcStream].getMaxIndex() / 2)
@@ -6360,9 +6385,20 @@
         boolean isLoopbackRenderPolicy = policyConfig.getMixes().stream().allMatch(
                 mix -> mix.getRouteFlags() == (mix.ROUTE_FLAG_RENDER | mix.ROUTE_FLAG_LOOP_BACK));
 
-        // Policy that do not modify the audio routing only need an audio projection
-        if (isLoopbackRenderPolicy && canProjectAudio(projection)) {
-            return true;
+        if (isLoopbackRenderPolicy) {
+            boolean allowPrivilegedPlaybackCapture = policyConfig.getMixes().stream().anyMatch(
+                    mix -> mix.getRule().allowPrivilegedPlaybackCapture());
+            if (allowPrivilegedPlaybackCapture
+                    && !(hasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)
+                    || hasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT))) {
+                // Opt-out can not be bypassed without a system permission
+                return false;
+            }
+
+            if (canProjectAudio(projection)) {
+                // Policy that do not modify the audio routing only need an audio projection
+                return true;
+            }
         }
 
         boolean hasPermissionModifyAudioRouting =
@@ -6373,6 +6409,9 @@
         }
         return false;
     }
+    private boolean hasPermission(String permission) {
+        return PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(permission);
+    }
 
     /** @return true if projection is a valid MediaProjection that can project audio. */
     private boolean canProjectAudio(IMediaProjection projection) {
diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
index b2c7ff3..87b272b 100644
--- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
@@ -69,6 +69,9 @@
                                                 AudioEffect.Descriptor[] effects,
                                                 int activeSource, String packName) {
         if (MediaRecorder.isSystemOnlyAudioSource(source)) {
+            // still want to log event, it just won't appear in recording configurations
+            sEventLogger.log(new RecordingEvent(event, uid, session, source, packName)
+                    .printLog(TAG));
             return;
         }
         String clientEffectName =  clientEffects.length == 0 ? "None" : clientEffects[0].name;
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index c60dd6c..d8e7b7d 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -657,6 +657,7 @@
         Slog.e(getTag(), "HAL died");
         mMetricsLogger.count(getMetrics().tagHalDied(), 1);
         mHALDeathCount++;
+        mCurrentUserId = UserHandle.USER_NULL;
         handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
                 0 /*vendorCode */);
 
diff --git a/services/core/java/com/android/server/biometrics/EnrollClient.java b/services/core/java/com/android/server/biometrics/EnrollClient.java
index d5e626a..e656d98 100644
--- a/services/core/java/com/android/server/biometrics/EnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/EnrollClient.java
@@ -36,6 +36,7 @@
     private final byte[] mCryptoToken;
     private final BiometricUtils mBiometricUtils;
     private final int[] mDisabledFeatures;
+    private long mEnrollmentStartTimeMs;
 
     public abstract boolean shouldVibrate();
 
@@ -61,6 +62,9 @@
             int remaining) {
         if (remaining == 0) {
             mBiometricUtils.addBiometricForUser(getContext(), getTargetUserId(), identifier);
+            logOnEnrolled(getTargetUserId(),
+                    System.currentTimeMillis() - mEnrollmentStartTimeMs,
+                    true /* enrollSuccessful */);
         }
         notifyUserActivity();
         return sendEnrollResult(identifier, remaining);
@@ -89,6 +93,7 @@
 
     @Override
     public int start() {
+        mEnrollmentStartTimeMs = System.currentTimeMillis();
         final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
         try {
             final ArrayList<Integer> disabledFeatures = new ArrayList<>();
@@ -127,10 +132,6 @@
         } catch (RemoteException e) {
             Slog.e(getLogTag(), "stopEnrollment failed", e);
         }
-        if (initiatedByClient) {
-            onError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_CANCELED,
-                    0 /* vendorCode */);
-        }
         mAlreadyCancelled = true;
         return 0;
     }
@@ -155,4 +156,17 @@
         return true; // Invalid for EnrollClient
     }
 
+    /**
+     * Called when we get notification from the biometric's HAL that an error has occurred with the
+     * current operation. Common to authenticate, enroll, enumerate and remove.
+     * @param error
+     * @return true if client should be removed
+     */
+    @Override
+    public boolean onError(long deviceId, int error, int vendorCode) {
+        logOnEnrolled(getTargetUserId(), System.currentTimeMillis() - mEnrollmentStartTimeMs,
+                false /* enrollSuccessful */);
+        return super.onError(deviceId, error, vendorCode);
+    }
+
 }
diff --git a/services/core/java/com/android/server/biometrics/LoggableMonitor.java b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
index 3b75b95..b0577cd 100644
--- a/services/core/java/com/android/server/biometrics/LoggableMonitor.java
+++ b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
@@ -150,4 +150,23 @@
                 authState,
                 latency);
     }
+
+    protected final void logOnEnrolled(int targetUserId, long latency, boolean enrollSuccessful) {
+        if (DEBUG) {
+            Slog.v(TAG, "Enrolled! Modality: " + statsModality()
+                    + ", User: " + targetUserId
+                    + ", Client: " + statsClient()
+                    + ", Latency: " + latency
+                    + ", Success: " + enrollSuccessful);
+        } else {
+            Slog.v(TAG, "Enroll latency: " + latency);
+        }
+
+        StatsLog.write(StatsLog.BIOMETRIC_ENROLLED,
+                statsModality(),
+                targetUserId,
+                latency,
+                enrollSuccessful);
+    }
+
 }
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index c385991..5e4bf33 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -39,12 +39,16 @@
 import android.hardware.face.IFaceService;
 import android.hardware.face.IFaceServiceReceiver;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Environment;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SELinux;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.service.restricted_image.RestrictedImageProto;
+import android.service.restricted_image.RestrictedImageSetProto;
+import android.service.restricted_image.RestrictedImagesDumpProto;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
@@ -281,7 +285,9 @@
 
             final long ident = Binder.clearCallingIdentity();
             try {
-                if (args.length > 0 && "--proto".equals(args[0])) {
+                if (args.length == 1 && "--restricted_image".equals(args[0])) {
+                    dumpRestrictedImage(fd);
+                } else if (args.length > 0 && "--proto".equals(args[0])) {
                     dumpProto(fd);
                 } else {
                     dumpInternal(pw);
@@ -377,6 +383,12 @@
         @Override // Binder call
         public void resetLockout(byte[] token) {
             checkPermission(MANAGE_BIOMETRIC);
+
+            if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
+                Slog.w(TAG, "Ignoring lockout reset, no templates enrolled");
+                return;
+            }
+
             try {
                 mDaemonWrapper.resetLockout(token);
             } catch (RemoteException e) {
@@ -1063,4 +1075,74 @@
         mPerformanceMap.clear();
         mCryptoPerformanceMap.clear();
     }
+
+    private void dumpRestrictedImage(FileDescriptor fd) {
+        // WARNING: CDD restricts image data from leaving TEE unencrypted on
+        //          production devices:
+        // [C-1-10] MUST not allow unencrypted access to identifiable biometric
+        //          data or any data derived from it (such as embeddings) to the
+        //         Application Processor outside the context of the TEE.
+        //  As such, this API should only be enabled for testing purposes on
+        //  engineering and userdebug builds.  All modules in the software stack
+        //  MUST enforce final build products do NOT have this functionality.
+        //  Additionally, the following check MUST NOT be removed.
+        if (!(Build.IS_ENG || Build.IS_USERDEBUG)) {
+            return;
+        }
+
+        final ProtoOutputStream proto = new ProtoOutputStream(fd);
+
+        final long setToken = proto.start(RestrictedImagesDumpProto.SETS);
+
+        // Name of the service
+        proto.write(RestrictedImageSetProto.CATEGORY, "face");
+
+        // Individual images
+        for (int i = 0; i < 5; i++) {
+            final long imageToken = proto.start(RestrictedImageSetProto.IMAGES);
+            proto.write(RestrictedImageProto.MIME_TYPE, "image/png");
+            proto.write(RestrictedImageProto.IMAGE_DATA, new byte[] {
+                    // png image data
+                    -119,   80,   78,   71,   13,   10,   26,   10,
+                       0,    0,    0,   13,   73,   72,   68,   82,
+                       0,    0,    0,  100,    0,    0,    0,  100,
+                       1,    3,    0,    0,    0,   74,   44,    7,
+                      23,    0,    0,    0,    4,  103,   65,   77,
+                      65,    0,    0,  -79, -113,   11,   -4,   97,
+                       5,    0,    0,    0,    1,  115,   82,   71,
+                      66,    0,  -82,  -50,   28,  -23,    0,    0,
+                       0,    6,   80,   76,   84,   69,   -1,   -1,
+                      -1,    0,    0,    0,   85,  -62,  -45,  126,
+                       0,    0,    0, -115,   73,   68,   65,   84,
+                      56,  -53,  -19,  -46,  -79,   17, -128,   32,
+                      12,    5,  -48,  120,   22, -106, -116,  -32,
+                      40,  -84,  101, -121,  -93,   57,   10,   35,
+                      88,   82,  112,  126,    3,  -60,  104,    6,
+                    -112,   70,  127,  -59,  -69,  -53,   29,   33,
+                    -127,  -24,   79,  -49,  -52,  -15,   41,   36,
+                      34, -105,   85,  124,  -14,   88,   27,    6,
+                      28,   68,    1,   82,   62,   22,  -95, -108,
+                      55,  -95,   40,   -9, -110,  -12,   98, -107,
+                      76,  -41, -105,  -62,  -50,  111,  -60,   46,
+                     -14,   -4,   24,  -89,   42, -103,   16,   63,
+                     -72,  -11,  -15,   48,  -62,  102,  -44,  102,
+                     -73,  -56,   56,  -21, -128,   92,  -70, -124,
+                     117,  -46,  -67,  -77,   82,   80,  121,  -44,
+                     -56,  116,   93,  -45,  -90,   -5,  -29,  -24,
+                     -83,  -75,   52,  -34,   55,  -22,  102,  -21,
+                    -105, -124,  -23,   71,   87,   -7,  -25,  -59,
+                    -100,  -73,  -92, -122,   -7, -109,  -49,  -80,
+                     -89,    0,    0,    0,    0,   73,   69,   78,
+                      68,  -82,   66,   96, -126
+            });
+            // proto.write(RestrictedImageProto.METADATA, flattened_protobuf);
+            proto.end(imageToken);
+        }
+
+        // Face service metadata
+        // proto.write(RestrictedImageSetProto.METADATA, flattened_protobuf);
+
+        proto.end(setToken);
+        proto.flush();
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index 164468e..3d9a47b 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -419,6 +419,12 @@
         @Override // Binder call
         public void resetTimeout(byte [] token) {
             checkPermission(RESET_FINGERPRINT_LOCKOUT);
+
+            if (!FingerprintService.this.hasEnrolledBiometrics(mCurrentUserId)) {
+                Slog.w(TAG, "Ignoring lockout reset, no templates enrolled");
+                return;
+            }
+
             // TODO: confirm security token when we move timeout management into the HAL layer.
             mHandler.post(mResetFailedAttemptsForCurrentUserRunnable);
         }
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
index b8810c8f..2df8982 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
@@ -24,6 +24,7 @@
 import android.hardware.radio.ITuner;
 import android.hardware.radio.ITunerCallback;
 import android.hardware.radio.RadioManager;
+import android.hardware.radio.RadioTuner;
 import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
 import android.os.IHwBinder.DeathRecipient;
@@ -49,9 +50,17 @@
     @GuardedBy("mLock")
     private final Map<String, Integer> mServiceNameToModuleIdMap = new HashMap<>();
 
+    // Map from module ID to RadioModule created by mServiceListener.onRegistration().
     @GuardedBy("mLock")
     private final Map<Integer, RadioModule> mModules = new HashMap<>();
 
+    // Map from module ID to TunerSession created by openSession().
+    //
+    // Because this service currently implements a 1 AIDL to 1 HAL policy, mTunerSessions is used to
+    // enforce the "aggresive open" policy mandated for IBroadcastRadio.openSession(). In the
+    // future, this solution will be replaced with a multiple-AIDL to 1 HAL implementation.
+    private final Map<Integer, TunerSession> mTunerSessions = new HashMap<>();
+
     private IServiceNotification.Stub mServiceListener = new IServiceNotification.Stub() {
         @Override
         public void onRegistration(String fqName, String serviceName, boolean preexisting) {
@@ -72,6 +81,7 @@
                 }
                 Slog.v(TAG, "loaded broadcast radio module " + moduleId + ": " + serviceName
                         + " (HAL 2.0)");
+                closeTunerSessionLocked(moduleId);
                 mModules.put(moduleId, module);
 
                 if (newService) {
@@ -96,6 +106,7 @@
             synchronized (mLock) {
                 int moduleId = (int) cookie;
                 mModules.remove(moduleId);
+                closeTunerSessionLocked(moduleId);
 
                 for (Map.Entry<String, Integer> entry : mServiceNameToModuleIdMap.entrySet()) {
                     if (entry.getValue() == moduleId) {
@@ -152,16 +163,20 @@
         RadioModule module = null;
         synchronized (mLock) {
             module = mModules.get(moduleId);
-        }
-        if (module == null) {
-            throw new IllegalArgumentException("Invalid module ID");
+            if (module == null) {
+                throw new IllegalArgumentException("Invalid module ID");
+            }
+            closeTunerSessionLocked(moduleId);
         }
 
-        TunerSession session = module.openSession(callback);
-        if (legacyConfig != null) {
-            session.setConfiguration(legacyConfig);
+        TunerSession tunerSession = module.openSession(callback);
+        synchronized (mLock) {
+            mTunerSessions.put(moduleId, tunerSession);
         }
-        return session;
+        if (legacyConfig != null) {
+            tunerSession.setConfiguration(legacyConfig);
+        }
+        return tunerSession;
     }
 
     public ICloseHandle addAnnouncementListener(@NonNull int[] enabledTypes,
@@ -183,4 +198,12 @@
         }
         return aggregator;
     }
+
+    private void closeTunerSessionLocked(int moduleId) {
+        TunerSession tunerSession = mTunerSessions.remove(moduleId);
+        if (tunerSession != null) {
+            Slog.d(TAG, "Closing previous TunerSession");
+            tunerSession.close(RadioTuner.ERROR_HARDWARE_FAILURE);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
index 9833507..05ca144 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
@@ -17,6 +17,7 @@
 package com.android.server.broadcastradio.hal2;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Bitmap;
 import android.hardware.broadcastradio.V2_0.ConfigFlag;
 import android.hardware.broadcastradio.V2_0.ITunerSession;
@@ -58,8 +59,22 @@
 
     @Override
     public void close() {
+        close(null);
+    }
+
+    /**
+     * Closes the TunerSession. If error is non-null, the client's onError() callback is invoked
+     * first with the specified error, see {@link
+     * android.hardware.radio.RadioTuner.Callback#onError}.
+     *
+     * @param error Optional error to send to client before session is closed.
+     */
+    public void close(@Nullable Integer error) {
         synchronized (mLock) {
             if (mIsClosed) return;
+            if (error != null) {
+                TunerCallback.dispatch(() -> mCallback.mClientCb.onError(error));
+            }
             mIsClosed = true;
         }
     }
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index d8bb635..1913635 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -30,13 +30,15 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.net.IDnsResolver;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkUtils;
 import android.net.Uri;
 import android.net.shared.PrivateDnsConfig;
 import android.os.Binder;
-import android.os.INetworkManagementService;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -229,7 +231,7 @@
 
     private final Context mContext;
     private final ContentResolver mContentResolver;
-    private final INetworkManagementService mNMS;
+    private final IDnsResolver mDnsResolver;
     private final MockableSystemProperties mSystemProperties;
     // TODO: Replace these Maps with SparseArrays.
     private final Map<Integer, PrivateDnsConfig> mPrivateDnsMap;
@@ -243,10 +245,10 @@
     private String mPrivateDnsMode;
     private String mPrivateDnsSpecifier;
 
-    public DnsManager(Context ctx, INetworkManagementService nms, MockableSystemProperties sp) {
+    public DnsManager(Context ctx, IDnsResolver dnsResolver, MockableSystemProperties sp) {
         mContext = ctx;
         mContentResolver = mContext.getContentResolver();
-        mNMS = nms;
+        mDnsResolver = dnsResolver;
         mSystemProperties = sp;
         mPrivateDnsMap = new HashMap<>();
         mPrivateDnsValidationMap = new HashMap<>();
@@ -260,6 +262,12 @@
     }
 
     public void removeNetwork(Network network) {
+        try {
+            mDnsResolver.clearResolverConfiguration(network.netId);
+        } catch (RemoteException | ServiceSpecificException e) {
+            Slog.e(TAG, "Error clearing DNS configuration: " + e);
+            return;
+        }
         mPrivateDnsMap.remove(network.netId);
         mPrivateDnsValidationMap.remove(network.netId);
     }
@@ -344,10 +352,12 @@
         Slog.d(TAG, String.format("setDnsConfigurationForNetwork(%d, %s, %s, %s, %s, %s)",
                 netId, Arrays.toString(assignedServers), Arrays.toString(domainStrs),
                 Arrays.toString(params), tlsHostname, Arrays.toString(tlsServers)));
+        final String[] tlsFingerprints = new String[0];
         try {
-            mNMS.setDnsConfigurationForNetwork(
-                    netId, assignedServers, domainStrs, params, tlsHostname, tlsServers);
-        } catch (Exception e) {
+            mDnsResolver.setResolverConfiguration(
+                    netId, assignedServers, domainStrs, params,
+                    tlsHostname, tlsServers, tlsFingerprints);
+        } catch (RemoteException | ServiceSpecificException e) {
             Slog.e(TAG, "Error setting DNS configuration: " + e);
             return;
         }
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index ce887eb..35f7ea3 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -132,6 +132,7 @@
         private static final int NOT_STARTED = 1;
         private static final int STARTING = 2;
         private static final int STARTED = 3;
+        private static final int STOPPING = 4;
         private int mStartedState = NOT_STARTED;
 
         KeepaliveInfo(@NonNull ISocketKeepaliveCallback callback,
@@ -154,12 +155,19 @@
             // keepalives are sent cannot be reused by another app even if the fd gets closed by
             // the user. A null is acceptable here for backward compatibility of PacketKeepalive
             // API.
-            // TODO: don't accept null fd after legacy packetKeepalive API is removed.
             try {
                 if (fd != null) {
                     mFd = Os.dup(fd);
                 }  else {
-                    Log.d(TAG, "uid/pid " + mUid + "/" + mPid + " calls with null fd");
+                    Log.d(TAG, toString() + " calls with null fd");
+                    if (!mPrivileged) {
+                        throw new SecurityException(
+                                "null fd is not allowed for unprivileged access.");
+                    }
+                    if (mType == TYPE_TCP) {
+                        throw new IllegalArgumentException(
+                                "null fd is not allowed for tcp socket keepalives.");
+                    }
                     mFd = null;
                 }
             } catch (ErrnoException e) {
@@ -307,6 +315,7 @@
                 }
             }
             if (NOT_STARTED != mStartedState) {
+                mStartedState = STOPPING;
                 Log.d(TAG, "Stopping keepalive " + mSlot + " on " + mNai.name());
                 if (mType == TYPE_NATT) {
                     mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot);
@@ -449,8 +458,8 @@
             ki = mKeepalives.get(nai).get(slot);
         } catch(NullPointerException e) {}
         if (ki == null) {
-            Log.e(TAG, "Event " + message.what + " for unknown keepalive " + slot + " on "
-                    + nai.name());
+            Log.e(TAG, "Event " + message.what + "," + slot + "," + reason
+                    + " for unknown keepalive " + slot + " on " + nai.name());
             return;
         }
 
@@ -469,27 +478,30 @@
         // messages in order.
         // TODO : clarify this code and get rid of mStartedState. Using a StateMachine is an
         // option.
-        if (reason == SUCCESS && KeepaliveInfo.STARTING == ki.mStartedState) {
-            // Keepalive successfully started.
-            if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
-            ki.mStartedState = KeepaliveInfo.STARTED;
-            try {
-                ki.mCallback.onStarted(slot);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Discarded onStarted(" + slot + ") callback");
-            }
-        } else {
-            // Keepalive successfully stopped, or error.
-            ki.mStartedState = KeepaliveInfo.NOT_STARTED;
-            if (reason == SUCCESS) {
-                // The message indicated success stopping : don't call handleStopKeepalive.
-                if (DBG) Log.d(TAG, "Successfully stopped keepalive " + slot + " on " + nai.name());
+        if (KeepaliveInfo.STARTING == ki.mStartedState) {
+            if (SUCCESS == reason) {
+                // Keepalive successfully started.
+                if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
+                ki.mStartedState = KeepaliveInfo.STARTED;
+                try {
+                    ki.mCallback.onStarted(slot);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Discarded onStarted(" + slot + ") callback");
+                }
             } else {
-                // The message indicated some error trying to start or during the course of
-                // keepalive : do call handleStopKeepalive.
+                Log.d(TAG, "Failed to start keepalive " + slot + " on " + nai.name()
+                        + ": " + reason);
+                // The message indicated some error trying to start: do call handleStopKeepalive.
                 handleStopKeepalive(nai, slot, reason);
-                if (DBG) Log.d(TAG, "Keepalive " + slot + " on " + nai.name() + " error " + reason);
             }
+        } else if (KeepaliveInfo.STOPPING == ki.mStartedState) {
+            // The message indicated result of stopping : don't call handleStopKeepalive.
+            Log.d(TAG, "Stopped keepalive " + slot + " on " + nai.name()
+                    + " stopped: " + reason);
+            ki.mStartedState = KeepaliveInfo.NOT_STARTED;
+        } else {
+            Log.wtf(TAG, "Event " + message.what + "," + slot + "," + reason
+                    + " for keepalive in wrong state: " + ki.toString());
         }
     }
 
@@ -531,7 +543,8 @@
         try {
             ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
                     KeepaliveInfo.TYPE_NATT, fd);
-        } catch (InvalidSocketException e) {
+        } catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
+            Log.e(TAG, "Fail to construct keepalive", e);
             notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
             return;
         }
@@ -570,7 +583,8 @@
         try {
             ki = new KeepaliveInfo(cb, nai, packet, intervalSeconds,
                     KeepaliveInfo.TYPE_TCP, fd);
-        } catch (InvalidSocketException e) {
+        } catch (InvalidSocketException | IllegalArgumentException | SecurityException e) {
+            Log.e(TAG, "Fail to construct keepalive e=" + e);
             notifyErrorCallback(cb, ERROR_INVALID_SOCKET);
             return;
         }
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 262ba7a..66bd27c 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -17,6 +17,7 @@
 package com.android.server.connectivity;
 
 import android.net.ConnectivityManager;
+import android.net.IDnsResolver;
 import android.net.INetd;
 import android.net.InetAddresses;
 import android.net.InterfaceConfiguration;
@@ -65,6 +66,7 @@
         NetworkInfo.State.SUSPENDED,
     };
 
+    private final IDnsResolver mDnsResolver;
     private final INetd mNetd;
     private final INetworkManagementService mNMService;
 
@@ -84,7 +86,9 @@
     private Inet6Address mIPv6Address;
     private State mState = State.IDLE;
 
-    public Nat464Xlat(NetworkAgentInfo nai, INetd netd, INetworkManagementService nmService) {
+    public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
+            INetworkManagementService nmService) {
+        mDnsResolver = dnsResolver;
         mNetd = netd;
         mNMService = nmService;
         mNetwork = nai;
@@ -269,7 +273,7 @@
 
     private void startPrefixDiscovery() {
         try {
-            mNetd.resolverStartPrefix64Discovery(getNetId());
+            mDnsResolver.startPrefix64Discovery(getNetId());
             mState = State.DISCOVERING;
         } catch (RemoteException | ServiceSpecificException e) {
             Slog.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e);
@@ -278,7 +282,7 @@
 
     private void stopPrefixDiscovery() {
         try {
-            mNetd.resolverStopPrefix64Discovery(getNetId());
+            mDnsResolver.stopPrefix64Discovery(getNetId());
         } catch (RemoteException | ServiceSpecificException e) {
             Slog.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e);
         }
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 8f2825c..cfa9131 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -17,6 +17,7 @@
 package com.android.server.connectivity;
 
 import android.content.Context;
+import android.net.IDnsResolver;
 import android.net.INetd;
 import android.net.INetworkMonitor;
 import android.net.LinkProperties;
@@ -29,6 +30,7 @@
 import android.os.Handler;
 import android.os.INetworkManagementService;
 import android.os.Messenger;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.Log;
 import android.util.SparseArray;
@@ -120,7 +122,8 @@
     // This Network object is always valid.
     public final Network network;
     public LinkProperties linkProperties;
-    // This should only be modified via ConnectivityService.updateCapabilities().
+    // This should only be modified by ConnectivityService, via setNetworkCapabilities().
+    // TODO: make this private with a getter.
     public NetworkCapabilities networkCapabilities;
     public final NetworkMisc networkMisc;
     // Indicates if netd has been told to create this Network. From this point on the appropriate
@@ -255,7 +258,7 @@
     public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
             LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
             NetworkMisc misc, ConnectivityService connService, INetd netd,
-            INetworkManagementService nms, int factorySerialNumber) {
+            IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber) {
         this.messenger = messenger;
         asyncChannel = ac;
         network = net;
@@ -263,7 +266,7 @@
         linkProperties = lp;
         networkCapabilities = nc;
         currentScore = score;
-        clatd = new Nat464Xlat(this, netd, nms);
+        clatd = new Nat464Xlat(this, netd, dnsResolver, nms);
         mConnService = connService;
         mContext = context;
         mHandler = handler;
@@ -278,6 +281,25 @@
         mNetworkMonitor = networkMonitor;
     }
 
+    /**
+     * Set the NetworkCapabilities on this NetworkAgentInfo. Also attempts to notify NetworkMonitor
+     * of the new capabilities, if NetworkMonitor has been created.
+     *
+     * <p>If {@link NetworkMonitor#notifyNetworkCapabilitiesChanged(NetworkCapabilities)} fails,
+     * the exception is logged but not reported to callers.
+     */
+    public void setNetworkCapabilities(NetworkCapabilities nc) {
+        networkCapabilities = nc;
+        final INetworkMonitor nm = mNetworkMonitor;
+        if (nm != null) {
+            try {
+                nm.notifyNetworkCapabilitiesChanged(nc);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error notifying NetworkMonitor of updated NetworkCapabilities", e);
+            }
+        }
+    }
+
     public ConnectivityService connService() {
         return mConnService;
     }
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 828a1e5..ac3d6de 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -19,6 +19,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
 
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -26,9 +27,12 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.net.NetworkSpecifier;
+import android.net.StringNetworkSpecifier;
 import android.net.wifi.WifiInfo;
 import android.os.UserHandle;
 import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Slog;
@@ -195,7 +199,20 @@
                     title = r.getString(R.string.network_available_sign_in, 0);
                     // TODO: Change this to pull from NetworkInfo once a printable
                     // name has been added to it
-                    details = mTelephonyManager.getNetworkOperatorName();
+                    NetworkSpecifier specifier = nai.networkCapabilities.getNetworkSpecifier();
+                    int subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+                    if (specifier instanceof StringNetworkSpecifier) {
+                        try {
+                            subId = Integer.parseInt(
+                                    ((StringNetworkSpecifier) specifier).specifier);
+                        } catch (NumberFormatException e) {
+                            Slog.e(TAG, "NumberFormatException on "
+                                    + ((StringNetworkSpecifier) specifier).specifier);
+                        }
+                    }
+
+                    details = mTelephonyManager.createForSubscriptionId(subId)
+                            .getNetworkOperatorName();
                     break;
                 default:
                     title = r.getString(R.string.network_available_sign_in, 0);
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 123564e..da1360d 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -22,6 +22,7 @@
 import static android.Manifest.permission.INTERNET;
 import static android.Manifest.permission.NETWORK_STACK;
 import static android.Manifest.permission.UPDATE_DEVICE_STATS;
+import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.MATCH_ANY_USER;
 import static android.os.Process.INVALID_UID;
@@ -36,19 +37,20 @@
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.UserInfo;
 import android.net.INetd;
-import android.net.util.NetdService;
 import android.os.Build;
 import android.os.INetworkManagementService;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.ArraySet;
 import android.util.Log;
-import android.util.Slog;
+import android.util.SparseArray;
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.LocalServices;
+import com.android.server.SystemConfig;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -74,7 +76,8 @@
     private final Context mContext;
     private final PackageManager mPackageManager;
     private final UserManager mUserManager;
-    private final INetworkManagementService mNetd;
+    private final INetworkManagementService mNMS;
+    private final INetd mNetd;
 
     // Values are User IDs.
     private final Set<Integer> mUsers = new HashSet<>();
@@ -83,49 +86,44 @@
     private final Map<Integer, Boolean> mApps = new HashMap<>();
 
     private class PackageListObserver implements PackageManagerInternal.PackageListObserver {
-        @Override
-        public void onPackageAdded(String packageName, int uid) {
-            final PackageInfo app = getPackageInfo(packageName);
-            if (app == null) {
-                Slog.wtf(TAG, "Failed to get information of installed package: " + packageName);
-                return;
-            }
-            if (uid == INVALID_UID) {
-                Slog.wtf(TAG, "Failed to get the uid of installed package: " + packageName
-                        + "uid: " + uid);
-                return;
-            }
-            if (app.requestedPermissions == null) {
-                return;
-            }
-            sendPackagePermissionsForUid(uid,
-                    getNetdPermissionMask(app.requestedPermissions));
-        }
 
-        @Override
-        public void onPackageRemoved(String packageName, int uid) {
+        private int getPermissionForUid(int uid) {
             int permission = 0;
-            // If there are still packages remain under the same uid, check the permission of the
-            // remaining packages. We only remove the permission for a given uid when all packages
-            // for that uid no longer have that permission.
+            // Check all the packages for this UID. The UID has the permission if any of the
+            // packages in it has the permission.
             String[] packages = mPackageManager.getPackagesForUid(uid);
             if (packages != null && packages.length > 0) {
                 for (String name : packages) {
                     final PackageInfo app = getPackageInfo(name);
                     if (app != null && app.requestedPermissions != null) {
-                        permission |= getNetdPermissionMask(app.requestedPermissions);
+                        permission |= getNetdPermissionMask(app.requestedPermissions,
+                              app.requestedPermissionsFlags);
                     }
                 }
+            } else {
+                // The last package of this uid is removed from device. Clean the package up.
+                permission = INetd.PERMISSION_UNINSTALLED;
             }
-            sendPackagePermissionsForUid(uid, permission);
+            return permission;
+        }
+
+        @Override
+        public void onPackageAdded(String packageName, int uid) {
+            sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
+        }
+
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            sendPackagePermissionsForUid(uid, getPermissionForUid(uid));
         }
     }
 
-    public PermissionMonitor(Context context, INetworkManagementService netd) {
+    public PermissionMonitor(Context context, INetworkManagementService nms, INetd netdService) {
         mContext = context;
         mPackageManager = context.getPackageManager();
         mUserManager = UserManager.get(context);
-        mNetd = netd;
+        mNMS = nms;
+        mNetd = netdService;
     }
 
     // Intended to be called only once at startup, after the system is ready. Installs a broadcast
@@ -167,12 +165,9 @@
             }
 
             //TODO: unify the management of the permissions into one codepath.
-            if (app.requestedPermissions != null) {
-                int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions);
-                if (otherNetdPerms != 0) {
-                    netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
-                }
-            }
+            int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions,
+                    app.requestedPermissionsFlags);
+            netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
         }
 
         List<UserInfo> users = mUserManager.getUsers(true);  // exclude dying users
@@ -182,6 +177,23 @@
             }
         }
 
+        final SparseArray<ArraySet<String>> systemPermission =
+                SystemConfig.getInstance().getSystemPermissions();
+        for (int i = 0; i < systemPermission.size(); i++) {
+            ArraySet<String> perms = systemPermission.valueAt(i);
+            int uid = systemPermission.keyAt(i);
+            int netdPermission = 0;
+            // Get the uids of native services that have UPDATE_DEVICE_STATS permission.
+            if (perms != null) {
+                netdPermission |= perms.contains(UPDATE_DEVICE_STATS)
+                        ? INetd.PERMISSION_UPDATE_DEVICE_STATS : 0;
+            }
+            // For internet permission, the native services have their own selinux domains and
+            // sepolicy will control the socket creation during run time. netd cannot block the
+            // socket creation based on the permission information here.
+            netdPermission |= INetd.PERMISSION_INTERNET;
+            netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
+        }
         log("Users: " + mUsers.size() + ", Apps: " + mApps.size());
         update(mUsers, mApps, true);
         sendPackagePermissionsToNetd(netdPermsUids);
@@ -277,11 +289,11 @@
         }
         try {
             if (add) {
-                mNetd.setPermission("NETWORK", toIntArray(network));
-                mNetd.setPermission("SYSTEM", toIntArray(system));
+                mNMS.setPermission("NETWORK", toIntArray(network));
+                mNMS.setPermission("SYSTEM", toIntArray(system));
             } else {
-                mNetd.clearPermission(toIntArray(network));
-                mNetd.clearPermission(toIntArray(system));
+                mNMS.clearPermission(toIntArray(network));
+                mNMS.clearPermission(toIntArray(system));
             }
         } catch (RemoteException e) {
             loge("Exception when updating permissions: " + e);
@@ -403,13 +415,17 @@
         }
     }
 
-    private static int getNetdPermissionMask(String[] requestedPermissions) {
+    private static int getNetdPermissionMask(String[] requestedPermissions,
+                                             int[] requestedPermissionsFlags) {
         int permissions = 0;
-        for (String permissionName : requestedPermissions) {
-            if (permissionName.equals(INTERNET)) {
+        if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions;
+        for (int i = 0; i < requestedPermissions.length; i++) {
+            if (requestedPermissions[i].equals(INTERNET)
+                    && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
                 permissions |= INetd.PERMISSION_INTERNET;
             }
-            if (permissionName.equals(UPDATE_DEVICE_STATS)) {
+            if (requestedPermissions[i].equals(UPDATE_DEVICE_STATS)
+                    && ((requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED) != 0)) {
                 permissions |= INetd.PERMISSION_UPDATE_DEVICE_STATS;
             }
         }
@@ -435,7 +451,8 @@
      *
      * @hide
      */
-    private void sendPackagePermissionsForUid(int uid, int permissions) {
+    @VisibleForTesting
+    void sendPackagePermissionsForUid(int uid, int permissions) {
         SparseIntArray netdPermissionsAppIds = new SparseIntArray();
         netdPermissionsAppIds.put(uid, permissions);
         sendPackagePermissionsToNetd(netdPermissionsAppIds);
@@ -450,15 +467,13 @@
      *
      * @hide
      */
-    private void sendPackagePermissionsToNetd(SparseIntArray netdPermissionsAppIds) {
-        INetd netdService = NetdService.getInstance();
-        if (netdService == null) {
-            Log.e(TAG, "Failed to get the netd service");
-            return;
-        }
+    @VisibleForTesting
+    void sendPackagePermissionsToNetd(SparseIntArray netdPermissionsAppIds) {
+
         ArrayList<Integer> allPermissionAppIds = new ArrayList<>();
         ArrayList<Integer> internetPermissionAppIds = new ArrayList<>();
         ArrayList<Integer> updateStatsPermissionAppIds = new ArrayList<>();
+        ArrayList<Integer> noPermissionAppIds = new ArrayList<>();
         ArrayList<Integer> uninstalledAppIds = new ArrayList<>();
         for (int i = 0; i < netdPermissionsAppIds.size(); i++) {
             int permissions = netdPermissionsAppIds.valueAt(i);
@@ -473,8 +488,10 @@
                     updateStatsPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
                     break;
                 case INetd.NO_PERMISSIONS:
-                    uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i));
+                    noPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
                     break;
+                case INetd.PERMISSION_UNINSTALLED:
+                    uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i));
                 default:
                     Log.e(TAG, "unknown permission type: " + permissions + "for uid: "
                             + netdPermissionsAppIds.keyAt(i));
@@ -483,20 +500,24 @@
         try {
             // TODO: add a lock inside netd to protect IPC trafficSetNetPermForUids()
             if (allPermissionAppIds.size() != 0) {
-                netdService.trafficSetNetPermForUids(
+                mNetd.trafficSetNetPermForUids(
                         INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
                         ArrayUtils.convertToIntArray(allPermissionAppIds));
             }
             if (internetPermissionAppIds.size() != 0) {
-                netdService.trafficSetNetPermForUids(INetd.PERMISSION_INTERNET,
+                mNetd.trafficSetNetPermForUids(INetd.PERMISSION_INTERNET,
                         ArrayUtils.convertToIntArray(internetPermissionAppIds));
             }
             if (updateStatsPermissionAppIds.size() != 0) {
-                netdService.trafficSetNetPermForUids(INetd.PERMISSION_UPDATE_DEVICE_STATS,
+                mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UPDATE_DEVICE_STATS,
                         ArrayUtils.convertToIntArray(updateStatsPermissionAppIds));
             }
+            if (noPermissionAppIds.size() != 0) {
+                mNetd.trafficSetNetPermForUids(INetd.NO_PERMISSIONS,
+                        ArrayUtils.convertToIntArray(noPermissionAppIds));
+            }
             if (uninstalledAppIds.size() != 0) {
-                netdService.trafficSetNetPermForUids(INetd.NO_PERMISSIONS,
+                mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UNINSTALLED,
                         ArrayUtils.convertToIntArray(uninstalledAppIds));
             }
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 37fe3d0..b140c1b 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -82,7 +82,6 @@
 import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Parcel;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -230,8 +229,15 @@
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
-        mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM,
-                mLog, systemProperties);
+        // EntitlementManager will send EVENT_UPSTREAM_PERMISSION_CHANGED when cellular upstream
+        // permission is changed according to entitlement check result.
+        mEntitlementMgr = mDeps.getEntitlementManager(mContext, mTetherMasterSM, mLog,
+                TetherMasterSM.EVENT_UPSTREAM_PERMISSION_CHANGED, systemProperties);
+        mEntitlementMgr.setOnUiEntitlementFailedListener((int downstream) -> {
+            mLog.log("OBSERVED UiEnitlementFailed");
+            stopTethering(downstream);
+        });
+
         mCarrierConfigChange = new VersionedBroadcastListener(
                 "CarrierConfigChangeListener", mContext, mHandler, filter,
                 (Intent ignored) -> {
@@ -363,55 +369,28 @@
     }
 
     public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
-        mEntitlementMgr.startTethering(type);
-        if (!mEntitlementMgr.isTetherProvisioningRequired()) {
-            enableTetheringInternal(type, true, receiver);
-            return;
-        }
-
-        final ResultReceiver proxyReceiver = getProxyReceiver(type, receiver);
-        if (showProvisioningUi) {
-            mEntitlementMgr.runUiTetherProvisioningAndEnable(type, proxyReceiver);
-        } else {
-            mEntitlementMgr.runSilentTetherProvisioningAndEnable(type, proxyReceiver);
-        }
+        mEntitlementMgr.startProvisioningIfNeeded(type, showProvisioningUi);
+        enableTetheringInternal(type, true /* enabled */, receiver);
     }
 
     public void stopTethering(int type) {
-        enableTetheringInternal(type, false, null);
-        mEntitlementMgr.stopTethering(type);
-        if (mEntitlementMgr.isTetherProvisioningRequired()) {
-            // There are lurking bugs where the notion of "provisioning required" or
-            // "tethering supported" may change without notifying tethering properly, then
-            // tethering can't shutdown correctly.
-            // TODO: cancel re-check all the time
-            if (mDeps.isTetheringSupported()) {
-                mEntitlementMgr.cancelTetherProvisioningRechecks(type);
-            }
-        }
+        enableTetheringInternal(type, false /* disabled */, null);
+        mEntitlementMgr.stopProvisioningIfNeeded(type);
     }
 
     /**
-     * Enables or disables tethering for the given type. This should only be called once
-     * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks
-     * for the specified interface.
+     * Enables or disables tethering for the given type. If provisioning is required, it will
+     * schedule provisioning rechecks for the specified interface.
      */
     private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {
-        boolean isProvisioningRequired = enable && mEntitlementMgr.isTetherProvisioningRequired();
         int result;
         switch (type) {
             case TETHERING_WIFI:
                 result = setWifiTethering(enable);
-                if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) {
-                    mEntitlementMgr.scheduleProvisioningRechecks(type);
-                }
                 sendTetherResult(receiver, result);
                 break;
             case TETHERING_USB:
                 result = setUsbTethering(enable);
-                if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) {
-                    mEntitlementMgr.scheduleProvisioningRechecks(type);
-                }
                 sendTetherResult(receiver, result);
                 break;
             case TETHERING_BLUETOOTH:
@@ -430,21 +409,25 @@
     }
 
     private int setWifiTethering(final boolean enable) {
-        int rval = TETHER_ERROR_MASTER_ERROR;
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mPublicSync) {
-                mWifiTetherRequested = enable;
                 final WifiManager mgr = getWifiManager();
+                if (mgr == null) {
+                    mLog.e("setWifiTethering: failed to get WifiManager!");
+                    return TETHER_ERROR_SERVICE_UNAVAIL;
+                }
                 if ((enable && mgr.startSoftAp(null /* use existing wifi config */)) ||
                     (!enable && mgr.stopSoftAp())) {
-                    rval = TETHER_ERROR_NO_ERROR;
+                    mWifiTetherRequested = enable;
+                    return TETHER_ERROR_NO_ERROR;
                 }
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
-        return rval;
+
+        return TETHER_ERROR_MASTER_ERROR;
     }
 
     private void setBluetoothTethering(final boolean enable, final ResultReceiver receiver) {
@@ -469,46 +452,11 @@
                         ? TETHER_ERROR_NO_ERROR
                         : TETHER_ERROR_MASTER_ERROR;
                 sendTetherResult(receiver, result);
-                if (enable && mEntitlementMgr.isTetherProvisioningRequired()) {
-                    mEntitlementMgr.scheduleProvisioningRechecks(TETHERING_BLUETOOTH);
-                }
                 adapter.closeProfileProxy(BluetoothProfile.PAN, proxy);
             }
         }, BluetoothProfile.PAN);
     }
 
-    /**
-     * Creates a proxy {@link ResultReceiver} which enables tethering if the provisioning result
-     * is successful before firing back up to the wrapped receiver.
-     *
-     * @param type The type of tethering being enabled.
-     * @param receiver A ResultReceiver which will be called back with an int resultCode.
-     * @return The proxy receiver.
-     */
-    private ResultReceiver getProxyReceiver(final int type, final ResultReceiver receiver) {
-        ResultReceiver rr = new ResultReceiver(null) {
-            @Override
-            protected void onReceiveResult(int resultCode, Bundle resultData) {
-                // If provisioning is successful, enable tethering, otherwise just send the error.
-                if (resultCode == TETHER_ERROR_NO_ERROR) {
-                    enableTetheringInternal(type, true, receiver);
-                } else {
-                    sendTetherResult(receiver, resultCode);
-                }
-                mEntitlementMgr.updateEntitlementCacheValue(type, resultCode);
-            }
-        };
-
-        // The following is necessary to avoid unmarshalling issues when sending the receiver
-        // across processes.
-        Parcel parcel = Parcel.obtain();
-        rr.writeToParcel(parcel,0);
-        parcel.setDataPosition(0);
-        ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-        return receiverForSending;
-    }
-
     public int tether(String iface) {
         return tether(iface, IpServer.STATE_TETHERED);
     }
@@ -787,6 +735,7 @@
                 if (!usbConnected && mRndisEnabled) {
                     // Turn off tethering if it was enabled and there is a disconnect.
                     tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB);
+                    mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_USB);
                 } else if (usbConfigured && rndisEnabled) {
                     // Tether if rndis is enabled and usb is configured.
                     tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB);
@@ -813,6 +762,7 @@
                     case WifiManager.WIFI_AP_STATE_FAILED:
                     default:
                         disableWifiIpServingLocked(ifname, curState);
+                        mEntitlementMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
                         break;
                 }
             }
@@ -996,6 +946,11 @@
     public int setUsbTethering(boolean enable) {
         if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
         UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
+        if (usbManager == null) {
+            mLog.e("setUsbTethering: failed to get UsbManager!");
+            return TETHER_ERROR_SERVICE_UNAVAIL;
+        }
+
         synchronized (mPublicSync) {
             usbManager.setCurrentFunctions(enable ? UsbManager.FUNCTION_RNDIS
                     : UsbManager.FUNCTION_NONE);
@@ -1090,6 +1045,8 @@
         // we treated the error and want now to clear it
         static final int CMD_CLEAR_ERROR                        = BASE_MASTER + 6;
         static final int EVENT_IFACE_UPDATE_LINKPROPERTIES      = BASE_MASTER + 7;
+        // Events from EntitlementManager to choose upstream again.
+        static final int EVENT_UPSTREAM_PERMISSION_CHANGED      = BASE_MASTER + 8;
 
         private final State mInitialState;
         private final State mTetherModeAliveState;
@@ -1504,6 +1461,7 @@
                         }
                         break;
                     }
+                    case EVENT_UPSTREAM_PERMISSION_CHANGED:
                     case CMD_UPSTREAM_CHANGED:
                         updateUpstreamWanted();
                         if (!mUpstreamWanted) break;
@@ -1694,7 +1652,8 @@
     }
 
     public void systemReady() {
-        mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest());
+        mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest(),
+                mEntitlementMgr);
     }
 
     /** Get the latest value of the tethering entitlement check. */
@@ -1755,6 +1714,11 @@
         cfg.dump(pw);
         pw.decreaseIndent();
 
+        pw.println("Entitlement:");
+        pw.increaseIndent();
+        mEntitlementMgr.dump(pw);
+        pw.decreaseIndent();
+
         synchronized (mPublicSync) {
             pw.println("Tether state:");
             pw.increaseIndent();
diff --git a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
index 70ab389..b0bbd72 100644
--- a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
+++ b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
@@ -18,9 +18,11 @@
 
 import static android.net.ConnectivityManager.EXTRA_ADD_TETHER_TYPE;
 import static android.net.ConnectivityManager.EXTRA_PROVISION_CALLBACK;
-import static android.net.ConnectivityManager.EXTRA_REM_TETHER_TYPE;
 import static android.net.ConnectivityManager.EXTRA_RUN_PROVISION;
-import static android.net.ConnectivityManager.EXTRA_SET_ALARM;
+import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
+import static android.net.ConnectivityManager.TETHERING_INVALID;
+import static android.net.ConnectivityManager.TETHERING_USB;
+import static android.net.ConnectivityManager.TETHERING_WIFI;
 import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN;
 import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
 import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
@@ -28,66 +30,117 @@
 import static com.android.internal.R.string.config_wifi_tether_enable;
 
 import android.annotation.Nullable;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.res.Resources;
 import android.net.util.SharedLog;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.os.Parcel;
 import android.os.PersistableBundle;
 import android.os.ResultReceiver;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
 import android.util.ArraySet;
-import android.util.Log;
 import android.util.SparseIntArray;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.StateMachine;
 import com.android.server.connectivity.MockableSystemProperties;
 
+import java.io.PrintWriter;
+
 /**
- * This class encapsulates entitlement/provisioning mechanics
- * provisioning check only applies to the use of the mobile network as an upstream
+ * Re-check tethering provisioning for enabled downstream tether types.
+ * Reference ConnectivityManager.TETHERING_{@code *} for each tether type.
  *
+ * All methods of this class must be accessed from the thread of tethering
+ * state machine.
  * @hide
  */
 public class EntitlementManager {
     private static final String TAG = EntitlementManager.class.getSimpleName();
     private static final boolean DBG = false;
 
+    @VisibleForTesting
+    protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
+    private static final String ACTION_PROVISIONING_ALARM =
+            "com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM";
+
     // {@link ComponentName} of the Service used to run tether provisioning.
     private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(
             Resources.getSystem().getString(config_wifi_tether_enable));
-    protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
+    private static final int MS_PER_HOUR = 60 * 60 * 1000;
+    private static final int EVENT_START_PROVISIONING = 0;
+    private static final int EVENT_STOP_PROVISIONING = 1;
+    private static final int EVENT_UPSTREAM_CHANGED = 2;
+    private static final int EVENT_MAYBE_RUN_PROVISIONING = 3;
+    private static final int EVENT_GET_ENTITLEMENT_VALUE = 4;
+
 
     // The ArraySet contains enabled downstream types, ex:
     // {@link ConnectivityManager.TETHERING_WIFI}
     // {@link ConnectivityManager.TETHERING_USB}
     // {@link ConnectivityManager.TETHERING_BLUETOOTH}
-    @GuardedBy("mCurrentTethers")
     private final ArraySet<Integer> mCurrentTethers;
     private final Context mContext;
+    private final int mPermissionChangeMessageCode;
     private final MockableSystemProperties mSystemProperties;
     private final SharedLog mLog;
-    private final Handler mMasterHandler;
     private final SparseIntArray mEntitlementCacheValue;
-    @Nullable
-    private TetheringConfiguration mConfig;
+    private final EntitlementHandler mHandler;
+    private @Nullable TetheringConfiguration mConfig;
+    private final StateMachine mTetherMasterSM;
+    // Key: ConnectivityManager.TETHERING_*(downstream).
+    // Value: ConnectivityManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result).
+    private final SparseIntArray mCellularPermitted;
+    private PendingIntent mProvisioningRecheckAlarm;
+    private boolean mCellularUpstreamPermitted = true;
+    private boolean mUsingCellularAsUpstream = false;
+    private boolean mNeedReRunProvisioningUi = false;
+    private OnUiEntitlementFailedListener mListener;
 
     public EntitlementManager(Context ctx, StateMachine tetherMasterSM, SharedLog log,
-            MockableSystemProperties systemProperties) {
+            int permissionChangeMessageCode, MockableSystemProperties systemProperties) {
+
         mContext = ctx;
         mLog = log.forSubComponent(TAG);
         mCurrentTethers = new ArraySet<Integer>();
+        mCellularPermitted = new SparseIntArray();
         mSystemProperties = systemProperties;
         mEntitlementCacheValue = new SparseIntArray();
-        mMasterHandler = tetherMasterSM.getHandler();
+        mTetherMasterSM = tetherMasterSM;
+        mPermissionChangeMessageCode = permissionChangeMessageCode;
+        final Handler masterHandler = tetherMasterSM.getHandler();
+        // Create entitlement's own handler which is associated with TetherMaster thread
+        // let all entitlement processes run in the same thread.
+        mHandler = new EntitlementHandler(masterHandler.getLooper());
+        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PROVISIONING_ALARM),
+                null, mHandler);
+    }
+
+    public void setOnUiEntitlementFailedListener(final OnUiEntitlementFailedListener listener) {
+        mListener = listener;
+    }
+
+    /** Callback fired when UI entitlement failed. */
+    public interface OnUiEntitlementFailedListener {
+        /**
+         * Ui entitlement check fails in |downstream|.
+         *
+         * @param downstream  tethering type from ConnectivityManager.TETHERING_{@code *}.
+         */
+        void onUiEntitlementFailed(int downstream);
     }
 
     /**
@@ -99,24 +152,118 @@
     }
 
     /**
-     * Tell EntitlementManager that a given type of tethering has been enabled
-     *
-     * @param type Tethering type
+     * Check if cellular upstream is permitted.
      */
-    public void startTethering(int type) {
-        synchronized (mCurrentTethers) {
-            mCurrentTethers.add(type);
+    public boolean isCellularUpstreamPermitted() {
+        return mCellularUpstreamPermitted;
+    }
+
+    /**
+     * This is called when tethering starts.
+     * Launch provisioning app if upstream is cellular.
+     *
+     * @param downstreamType tethering type from ConnectivityManager.TETHERING_{@code *}
+     * @param showProvisioningUi a boolean indicating whether to show the
+     *        provisioning app UI if there is one.
+     */
+    public void startProvisioningIfNeeded(int downstreamType, boolean showProvisioningUi) {
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_START_PROVISIONING,
+                downstreamType, encodeBool(showProvisioningUi)));
+    }
+
+    private void handleStartProvisioningIfNeeded(int type, boolean showProvisioningUi) {
+        if (!isValidDownstreamType(type)) return;
+
+        if (!mCurrentTethers.contains(type)) mCurrentTethers.add(type);
+
+        if (isTetherProvisioningRequired()) {
+            // If provisioning is required and the result is not available yet,
+            // cellular upstream should not be allowed.
+            if (mCellularPermitted.size() == 0) {
+                mCellularUpstreamPermitted = false;
+            }
+            // If upstream is not cellular, provisioning app would not be launched
+            // till upstream change to cellular.
+            if (mUsingCellularAsUpstream) {
+                if (showProvisioningUi) {
+                    runUiTetherProvisioning(type);
+                } else {
+                    runSilentTetherProvisioning(type);
+                }
+                mNeedReRunProvisioningUi = false;
+            } else {
+                mNeedReRunProvisioningUi |= showProvisioningUi;
+            }
+        } else {
+            mCellularUpstreamPermitted = true;
         }
     }
 
     /**
      * Tell EntitlementManager that a given type of tethering has been disabled
      *
-     * @param type Tethering type
+     * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
      */
-    public void stopTethering(int type) {
-        synchronized (mCurrentTethers) {
-            mCurrentTethers.remove(type);
+    public void stopProvisioningIfNeeded(int type) {
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_STOP_PROVISIONING, type, 0));
+    }
+
+    private void handleStopProvisioningIfNeeded(int type) {
+        if (!isValidDownstreamType(type)) return;
+
+        mCurrentTethers.remove(type);
+        // There are lurking bugs where the notion of "provisioning required" or
+        // "tethering supported" may change without without tethering being notified properly.
+        // Remove the mapping all the time no matter provisioning is required or not.
+        removeDownstreamMapping(type);
+    }
+
+    /**
+     * Notify EntitlementManager if upstream is cellular or not.
+     *
+     * @param isCellular whether tethering upstream is cellular.
+     */
+    public void notifyUpstream(boolean isCellular) {
+        mHandler.sendMessage(mHandler.obtainMessage(
+                EVENT_UPSTREAM_CHANGED, encodeBool(isCellular), 0));
+    }
+
+    private void handleNotifyUpstream(boolean isCellular) {
+        if (DBG) {
+            mLog.i("notifyUpstream: " + isCellular
+                    + ", mCellularUpstreamPermitted: " + mCellularUpstreamPermitted
+                    + ", mNeedReRunProvisioningUi: " + mNeedReRunProvisioningUi);
+        }
+        mUsingCellularAsUpstream = isCellular;
+
+        if (mUsingCellularAsUpstream) {
+            handleMaybeRunProvisioning();
+        }
+    }
+
+    /** Run provisioning if needed */
+    public void maybeRunProvisioning() {
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_MAYBE_RUN_PROVISIONING));
+    }
+
+    private void handleMaybeRunProvisioning() {
+        if (mCurrentTethers.size() == 0 || !isTetherProvisioningRequired()) {
+            return;
+        }
+
+        // Whenever any entitlement value changes, all downstreams will re-evaluate whether they
+        // are allowed. Therefore even if the silent check here ends in a failure and the UI later
+        // yields success, then the downstream that got a failure will re-evaluate as a result of
+        // the change and get the new correct value.
+        for (Integer downstream : mCurrentTethers) {
+            if (mCellularPermitted.indexOfKey(downstream) < 0) {
+                if (mNeedReRunProvisioningUi) {
+                    mNeedReRunProvisioningUi = false;
+                    runUiTetherProvisioning(downstream);
+                } else {
+                    runSilentTetherProvisioning(downstream);
+                }
+            }
         }
     }
 
@@ -138,23 +285,32 @@
     }
 
     /**
-     * Re-check tethering provisioning for enabled downstream tether types.
+     * Re-check tethering provisioning for all enabled tether types.
      * Reference ConnectivityManager.TETHERING_{@code *} for each tether type.
+     *
+     * Note: this method is only called from TetherMaster on the handler thread.
+     * If there are new callers from different threads, the logic should move to
+     * masterHandler to avoid race conditions.
      */
     public void reevaluateSimCardProvisioning() {
-        synchronized (mEntitlementCacheValue) {
-            mEntitlementCacheValue.clear();
+        if (DBG) mLog.i("reevaluateSimCardProvisioning");
+
+        if (!mHandler.getLooper().isCurrentThread()) {
+            // Except for test, this log should not appear in normal flow.
+            mLog.log("reevaluateSimCardProvisioning() don't run in TetherMaster thread");
+        }
+        mEntitlementCacheValue.clear();
+        mCellularPermitted.clear();
+
+        // TODO: refine provisioning check to isTetherProvisioningRequired() ??
+        if (!mConfig.hasMobileHotspotProvisionApp()
+                || carrierConfigAffirmsEntitlementCheckNotRequired()) {
+            evaluateCellularPermission();
+            return;
         }
 
-        if (!mConfig.hasMobileHotspotProvisionApp()) return;
-        if (carrierConfigAffirmsEntitlementCheckNotRequired()) return;
-
-        final ArraySet<Integer> reevaluateType;
-        synchronized (mCurrentTethers) {
-            reevaluateType = new ArraySet<Integer>(mCurrentTethers);
-        }
-        for (Integer type : reevaluateType) {
-            startProvisionIntent(type);
+        if (mUsingCellularAsUpstream) {
+            handleMaybeRunProvisioning();
         }
     }
 
@@ -189,7 +345,16 @@
         return !isEntitlementCheckRequired;
     }
 
-    public void runSilentTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
+    /**
+     * Run no UI tethering provisioning check.
+     * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
+     */
+    protected void runSilentTetherProvisioning(int type) {
+        if (DBG) mLog.i("runSilentTetherProvisioning: " + type);
+        // For silent provisioning, settings would stop tethering when entitlement fail.
+        ResultReceiver receiver = buildProxyReceiver(type,
+                false/* notifyFail */, null);
+
         Intent intent = new Intent();
         intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
         intent.putExtra(EXTRA_RUN_PROVISION, true);
@@ -203,12 +368,21 @@
         }
     }
 
-    public void runUiTetherProvisioningAndEnable(int type, ResultReceiver receiver) {
+    /**
+     * Run the UI-enabled tethering provisioning check.
+     * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
+     */
+    @VisibleForTesting
+    protected void runUiTetherProvisioning(int type) {
+        ResultReceiver receiver = buildProxyReceiver(type,
+                true/* notifyFail */, null);
         runUiTetherProvisioning(type, receiver);
     }
 
     @VisibleForTesting
     protected void runUiTetherProvisioning(int type, ResultReceiver receiver) {
+        if (DBG) mLog.i("runUiTetherProvisioning: " + type);
+
         Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING);
         intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
         intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
@@ -221,56 +395,208 @@
         }
     }
 
-    // Used by the SIM card change observation code.
-    // TODO: De-duplicate with above code, where possible.
-    private void startProvisionIntent(int tetherType) {
-        final Intent startProvIntent = new Intent();
-        startProvIntent.putExtra(EXTRA_ADD_TETHER_TYPE, tetherType);
-        startProvIntent.putExtra(EXTRA_RUN_PROVISION, true);
-        startProvIntent.setComponent(TETHER_SERVICE);
-        mContext.startServiceAsUser(startProvIntent, UserHandle.CURRENT);
-    }
+    // Not needed to check if this don't run on the handler thread because it's private.
+    private void scheduleProvisioningRechecks() {
+        if (mProvisioningRecheckAlarm == null) {
+            final int period = mConfig.provisioningCheckPeriod;
+            if (period <= 0) return;
 
-    public void scheduleProvisioningRechecks(int type) {
-        Intent intent = new Intent();
-        intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
-        intent.putExtra(EXTRA_SET_ALARM, true);
-        intent.setComponent(TETHER_SERVICE);
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            mContext.startServiceAsUser(intent, UserHandle.CURRENT);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
+            Intent intent = new Intent(ACTION_PROVISIONING_ALARM);
+            mProvisioningRecheckAlarm = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+            AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
+                    Context.ALARM_SERVICE);
+            long periodMs = period * MS_PER_HOUR;
+            long firstAlarmTime = SystemClock.elapsedRealtime() + periodMs;
+            alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME, firstAlarmTime, periodMs,
+                    mProvisioningRecheckAlarm);
         }
     }
 
-    public void cancelTetherProvisioningRechecks(int type) {
-        Intent intent = new Intent();
-        intent.putExtra(EXTRA_REM_TETHER_TYPE, type);
-        intent.setComponent(TETHER_SERVICE);
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            mContext.startServiceAsUser(intent, UserHandle.CURRENT);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
+    private void cancelTetherProvisioningRechecks() {
+        if (mProvisioningRecheckAlarm != null) {
+            AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(
+                    Context.ALARM_SERVICE);
+            alarmManager.cancel(mProvisioningRecheckAlarm);
+            mProvisioningRecheckAlarm = null;
         }
     }
 
-    private ResultReceiver buildProxyReceiver(int type, final ResultReceiver receiver) {
-        ResultReceiver rr = new ResultReceiver(mMasterHandler) {
+    private void evaluateCellularPermission() {
+        final boolean oldPermitted = mCellularUpstreamPermitted;
+        mCellularUpstreamPermitted = (!isTetherProvisioningRequired()
+                || mCellularPermitted.indexOfValue(TETHER_ERROR_NO_ERROR) > -1);
+
+        if (DBG) {
+            mLog.i("Cellular permission change from " + oldPermitted
+                    + " to " + mCellularUpstreamPermitted);
+        }
+
+        if (mCellularUpstreamPermitted != oldPermitted) {
+            mLog.log("Cellular permission change: " + mCellularUpstreamPermitted);
+            mTetherMasterSM.sendMessage(mPermissionChangeMessageCode);
+        }
+        // Only schedule periodic re-check when tether is provisioned
+        // and the result is ok.
+        if (mCellularUpstreamPermitted && mCellularPermitted.size() > 0) {
+            scheduleProvisioningRechecks();
+        } else {
+            cancelTetherProvisioningRechecks();
+        }
+    }
+
+    /**
+     * Add the mapping between provisioning result and tethering type.
+     * Notify UpstreamNetworkMonitor if Cellular permission changes.
+     *
+     * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
+     * @param resultCode Provisioning result
+     */
+    protected void addDownstreamMapping(int type, int resultCode) {
+        mLog.i("addDownstreamMapping: " + type + ", result: " + resultCode
+                + " ,TetherTypeRequested: " + mCurrentTethers.contains(type));
+        if (!mCurrentTethers.contains(type)) return;
+
+        mCellularPermitted.put(type, resultCode);
+        evaluateCellularPermission();
+    }
+
+    /**
+     * Remove the mapping for input tethering type.
+     * @param type tethering type from ConnectivityManager.TETHERING_{@code *}
+     */
+    protected void removeDownstreamMapping(int type) {
+        mLog.i("removeDownstreamMapping: " + type);
+        mCellularPermitted.delete(type);
+        evaluateCellularPermission();
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (ACTION_PROVISIONING_ALARM.equals(intent.getAction())) {
+                mLog.log("Received provisioning alarm");
+                reevaluateSimCardProvisioning();
+            }
+        }
+    };
+
+    private class EntitlementHandler extends Handler {
+        EntitlementHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_START_PROVISIONING:
+                    handleStartProvisioningIfNeeded(msg.arg1, toBool(msg.arg2));
+                    break;
+                case EVENT_STOP_PROVISIONING:
+                    handleStopProvisioningIfNeeded(msg.arg1);
+                    break;
+                case EVENT_UPSTREAM_CHANGED:
+                    handleNotifyUpstream(toBool(msg.arg1));
+                    break;
+                case EVENT_MAYBE_RUN_PROVISIONING:
+                    handleMaybeRunProvisioning();
+                    break;
+                case EVENT_GET_ENTITLEMENT_VALUE:
+                    handleGetLatestTetheringEntitlementValue(msg.arg1, (ResultReceiver) msg.obj,
+                            toBool(msg.arg2));
+                    break;
+                default:
+                    mLog.log("Unknown event: " + msg.what);
+                    break;
+            }
+        }
+    }
+
+    private static boolean toBool(int encodedBoolean) {
+        return encodedBoolean != 0;
+    }
+
+    private static int encodeBool(boolean b) {
+        return b ? 1 : 0;
+    }
+
+    private static boolean isValidDownstreamType(int type) {
+        switch (type) {
+            case TETHERING_BLUETOOTH:
+            case TETHERING_USB:
+            case TETHERING_WIFI:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Dump the infromation of EntitlementManager.
+     * @param pw {@link PrintWriter} is used to print formatted
+     */
+    public void dump(PrintWriter pw) {
+        pw.print("mCellularUpstreamPermitted: ");
+        pw.println(mCellularUpstreamPermitted);
+        for (Integer type : mCurrentTethers) {
+            pw.print("Type: ");
+            pw.print(typeString(type));
+            if (mCellularPermitted.indexOfKey(type) > -1) {
+                pw.print(", Value: ");
+                pw.println(errorString(mCellularPermitted.get(type)));
+            } else {
+                pw.println(", Value: empty");
+            }
+        }
+    }
+
+    private static String typeString(int type) {
+        switch (type) {
+            case TETHERING_BLUETOOTH: return "TETHERING_BLUETOOTH";
+            case TETHERING_INVALID: return "TETHERING_INVALID";
+            case TETHERING_USB: return "TETHERING_USB";
+            case TETHERING_WIFI: return "TETHERING_WIFI";
+            default:
+                return String.format("TETHERING UNKNOWN TYPE (%d)", type);
+        }
+    }
+
+    private static String errorString(int value) {
+        switch (value) {
+            case TETHER_ERROR_ENTITLEMENT_UNKONWN: return "TETHER_ERROR_ENTITLEMENT_UNKONWN";
+            case TETHER_ERROR_NO_ERROR: return "TETHER_ERROR_NO_ERROR";
+            case TETHER_ERROR_PROVISION_FAILED: return "TETHER_ERROR_PROVISION_FAILED";
+            default:
+                return String.format("UNKNOWN ERROR (%d)", value);
+        }
+    }
+
+    private ResultReceiver buildProxyReceiver(int type, boolean notifyFail,
+            final ResultReceiver receiver) {
+        ResultReceiver rr = new ResultReceiver(mHandler) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
                 int updatedCacheValue = updateEntitlementCacheValue(type, resultCode);
-                receiver.send(updatedCacheValue, null);
+                addDownstreamMapping(type, updatedCacheValue);
+                if (updatedCacheValue == TETHER_ERROR_PROVISION_FAILED && notifyFail) {
+                    mListener.onUiEntitlementFailed(type);
+                }
+                if (receiver != null) receiver.send(updatedCacheValue, null);
             }
         };
 
         return writeToParcel(rr);
     }
 
+    // Instances of ResultReceiver need to be public classes for remote processes to be able
+    // to load them (otherwise, ClassNotFoundException). For private classes, this method
+    // performs a trick : round-trip parceling any instance of ResultReceiver will return a
+    // vanilla instance of ResultReceiver sharing the binder token with the original receiver.
+    // The binder token has a reference to the original instance of the private class and will
+    // still call its methods, and can be sent over. However it cannot be used for anything
+    // else than sending over a Binder call.
+    // While round-trip parceling is not great, there is currently no other way of generating
+    // a vanilla instance of ResultReceiver because all its fields are private.
     private ResultReceiver writeToParcel(final ResultReceiver receiver) {
-        // This is necessary to avoid unmarshalling issues when sending the receiver
-        // across processes.
         Parcel parcel = Parcel.obtain();
         receiver.writeToParcel(parcel, 0);
         parcel.setDataPosition(0);
@@ -286,38 +612,41 @@
      * @param resultCode last entitlement value
      * @return the last updated entitlement value
      */
-    public int updateEntitlementCacheValue(int type, int resultCode) {
+    private int updateEntitlementCacheValue(int type, int resultCode) {
         if (DBG) {
-            Log.d(TAG, "updateEntitlementCacheValue: " + type + ", result: " + resultCode);
+            mLog.i("updateEntitlementCacheValue: " + type + ", result: " + resultCode);
         }
-        synchronized (mEntitlementCacheValue) {
-            if (resultCode == TETHER_ERROR_NO_ERROR) {
-                mEntitlementCacheValue.put(type, resultCode);
-                return resultCode;
-            } else {
-                mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISION_FAILED);
-                return TETHER_ERROR_PROVISION_FAILED;
-            }
+        if (resultCode == TETHER_ERROR_NO_ERROR) {
+            mEntitlementCacheValue.put(type, resultCode);
+            return resultCode;
+        } else {
+            mEntitlementCacheValue.put(type, TETHER_ERROR_PROVISION_FAILED);
+            return TETHER_ERROR_PROVISION_FAILED;
         }
     }
 
     /** Get the last value of the tethering entitlement check. */
     public void getLatestTetheringEntitlementResult(int downstream, ResultReceiver receiver,
             boolean showEntitlementUi) {
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_GET_ENTITLEMENT_VALUE,
+                downstream, encodeBool(showEntitlementUi), receiver));
+
+    }
+
+    private void handleGetLatestTetheringEntitlementValue(int downstream, ResultReceiver receiver,
+            boolean showEntitlementUi) {
+
         if (!isTetherProvisioningRequired()) {
             receiver.send(TETHER_ERROR_NO_ERROR, null);
             return;
         }
 
-        final int cacheValue;
-        synchronized (mEntitlementCacheValue) {
-            cacheValue = mEntitlementCacheValue.get(
+        final int cacheValue = mEntitlementCacheValue.get(
                 downstream, TETHER_ERROR_ENTITLEMENT_UNKONWN);
-        }
         if (cacheValue == TETHER_ERROR_NO_ERROR || !showEntitlementUi) {
             receiver.send(cacheValue, null);
         } else {
-            ResultReceiver proxy = buildProxyReceiver(downstream, receiver);
+            ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver);
             runUiTetherProvisioning(downstream, proxy);
         }
     }
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
index 935b795..8427b6e 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -30,6 +30,7 @@
 import static com.android.internal.R.array.config_tether_usb_regexs;
 import static com.android.internal.R.array.config_tether_wifi_regexs;
 import static com.android.internal.R.bool.config_tether_upstream_automatic;
+import static com.android.internal.R.integer.config_mobile_hotspot_provision_check_period;
 import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui;
 
 import android.content.ContentResolver;
@@ -94,6 +95,7 @@
 
     public final String[] provisioningApp;
     public final String provisioningAppNoUi;
+    public final int provisioningCheckPeriod;
 
     public final int subId;
 
@@ -121,6 +123,9 @@
 
         provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app);
         provisioningAppNoUi = getProvisioningAppNoUi(res);
+        provisioningCheckPeriod = getResourceInteger(res,
+                config_mobile_hotspot_provision_check_period,
+                0 /* No periodic re-check */);
 
         configLog.log(toString());
     }
@@ -311,6 +316,14 @@
         }
     }
 
+    private static int getResourceInteger(Resources res, int resId, int defaultValue) {
+        try {
+            return res.getInteger(resId);
+        } catch (Resources.NotFoundException e404) {
+            return defaultValue;
+        }
+    }
+
     private static boolean getEnableLegacyDhcpServer(Context ctx) {
         final ContentResolver cr = ctx.getContentResolver();
         final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
index 173d786..a0aad7c 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
@@ -83,8 +83,8 @@
      * Get a reference to the EntitlementManager to be used by tethering.
      */
     public EntitlementManager getEntitlementManager(Context ctx, StateMachine target,
-            SharedLog log, MockableSystemProperties systemProperties) {
-        return new EntitlementManager(ctx, target, log, systemProperties);
+            SharedLog log, int what, MockableSystemProperties systemProperties) {
+        return new EntitlementManager(ctx, target, log, what, systemProperties);
     }
 
     /**
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 3ac311b..3a9e21f 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -16,36 +16,32 @@
 
 package com.android.server.connectivity.tethering;
 
-import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.ConnectivityManager.TYPE_NONE;
 import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
 import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
+import static android.net.ConnectivityManager.TYPE_NONE;
+import static android.net.ConnectivityManager.getNetworkTypeName;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 
 import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Process;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.IpPrefix;
-import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.NetworkState;
-import android.net.util.NetworkConstants;
 import android.net.util.PrefixUtils;
 import android.net.util.SharedLog;
+import android.os.Handler;
+import android.os.Process;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.StateMachine;
 
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
@@ -97,10 +93,13 @@
     private final HashMap<Network, NetworkState> mNetworkMap = new HashMap<>();
     private HashSet<IpPrefix> mLocalPrefixes;
     private ConnectivityManager mCM;
+    private EntitlementManager mEntitlementMgr;
     private NetworkCallback mListenAllCallback;
     private NetworkCallback mDefaultNetworkCallback;
     private NetworkCallback mMobileNetworkCallback;
     private boolean mDunRequired;
+    // Whether the current default upstream is mobile or not.
+    private boolean mIsDefaultCellularUpstream;
     // The current system default network (not really used yet).
     private Network mDefaultInternetNetwork;
     // The current upstream network used for tethering.
@@ -113,6 +112,7 @@
         mLog = log.forSubComponent(TAG);
         mWhat = what;
         mLocalPrefixes = new HashSet<>();
+        mIsDefaultCellularUpstream = false;
     }
 
     @VisibleForTesting
@@ -122,7 +122,15 @@
         mCM = cm;
     }
 
-    public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest) {
+    /**
+     * Tracking the system default network. This method should be called when system is ready.
+     *
+     * @param defaultNetworkRequest should be the same as ConnectivityService default request
+     * @param entitle a EntitlementManager object to communicate between EntitlementManager and
+     * UpstreamNetworkMonitor
+     */
+    public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest,
+            EntitlementManager entitle) {
         // This is not really a "request", just a way of tracking the system default network.
         // It's guaranteed not to actually bring up any networks because it's the same request
         // as the ConnectivityService default request, and thus shares fate with it. We can't
@@ -133,6 +141,9 @@
             mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_DEFAULT_INTERNET);
             cm().requestNetwork(trackDefaultRequest, mDefaultNetworkCallback, mHandler);
         }
+        if (mEntitlementMgr == null) {
+            mEntitlementMgr = entitle;
+        }
     }
 
     public void startObserveAllNetworks() {
@@ -168,11 +179,15 @@
     }
 
     public void registerMobileNetworkRequest() {
+        if (!isCellularUpstreamPermitted()) {
+            mLog.i("registerMobileNetworkRequest() is not permitted");
+            releaseMobileNetworkRequest();
+            return;
+        }
         if (mMobileNetworkCallback != null) {
             mLog.e("registerMobileNetworkRequest() already registered");
             return;
         }
-
         // The following use of the legacy type system cannot be removed until
         // after upstream selection no longer finds networks by legacy type.
         // See also http://b/34364553 .
@@ -206,29 +221,32 @@
     // becomes available and useful we (a) file a request to keep it up as
     // necessary and (b) change all upstream tracking state accordingly (by
     // passing LinkProperties up to Tethering).
-    //
-    // Next TODO: return NetworkState instead of just the type.
     public NetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
         final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
-                mNetworkMap.values(), preferredTypes);
+                mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted());
 
         mLog.log("preferred upstream type: " + getNetworkTypeName(typeStatePair.type));
 
         switch (typeStatePair.type) {
             case TYPE_MOBILE_DUN:
             case TYPE_MOBILE_HIPRI:
+                // Tethering just selected mobile upstream in spite of the default network being
+                // not mobile. This can happen because of the priority list.
+                // Notify EntitlementManager to check permission for using mobile upstream.
+                if (!mIsDefaultCellularUpstream) {
+                    mEntitlementMgr.maybeRunProvisioning();
+                }
                 // If we're on DUN, put our own grab on it.
                 registerMobileNetworkRequest();
                 break;
             case TYPE_NONE:
+                // If we found NONE and mobile upstream is permitted we don't want to do this
+                // as we want any previous requests to keep trying to bring up something we can use.
+                if (!isCellularUpstreamPermitted()) releaseMobileNetworkRequest();
                 break;
             default:
-                /* If we've found an active upstream connection that's not DUN/HIPRI
-                 * we should stop any outstanding DUN/HIPRI requests.
-                 *
-                 * If we found NONE we don't want to do this as we want any previous
-                 * requests to keep trying to bring up something we can use.
-                 */
+                // If we've found an active upstream connection that's not DUN/HIPRI
+                // we should stop any outstanding DUN/HIPRI requests.
                 releaseMobileNetworkRequest();
                 break;
         }
@@ -241,10 +259,12 @@
         final NetworkState dfltState = (mDefaultInternetNetwork != null)
                 ? mNetworkMap.get(mDefaultInternetNetwork)
                 : null;
-        if (!mDunRequired) return dfltState;
-
         if (isNetworkUsableAndNotCellular(dfltState)) return dfltState;
 
+        if (!isCellularUpstreamPermitted()) return null;
+
+        if (!mDunRequired) return dfltState;
+
         // Find a DUN network. Note that code in Tethering causes a DUN request
         // to be filed, but this might be moved into this class in future.
         return findFirstDunNetwork(mNetworkMap.values());
@@ -258,6 +278,15 @@
         return (Set<IpPrefix>) mLocalPrefixes.clone();
     }
 
+    private boolean isCellularUpstreamPermitted() {
+        if (mEntitlementMgr != null) {
+            return mEntitlementMgr.isCellularUpstreamPermitted();
+        } else {
+            // This flow should only happens in testing.
+            return true;
+        }
+    }
+
     private void handleAvailable(Network network) {
         if (mNetworkMap.containsKey(network)) return;
 
@@ -388,8 +417,14 @@
         public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) {
             if (mCallbackType == CALLBACK_DEFAULT_INTERNET) {
                 mDefaultInternetNetwork = network;
+                final boolean newIsCellular = isCellular(newNc);
+                if (mIsDefaultCellularUpstream != newIsCellular) {
+                    mIsDefaultCellularUpstream = newIsCellular;
+                    mEntitlementMgr.notifyUpstream(newIsCellular);
+                }
                 return;
             }
+
             handleNetCap(network, newNc);
         }
 
@@ -424,8 +459,11 @@
         public void onLost(Network network) {
             if (mCallbackType == CALLBACK_DEFAULT_INTERNET) {
                 mDefaultInternetNetwork = null;
+                mIsDefaultCellularUpstream = false;
+                mEntitlementMgr.notifyUpstream(false);
                 return;
             }
+
             handleLost(network);
             // Any non-LISTEN_ALL callback will necessarily concern a network that will
             // also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback.
@@ -454,7 +492,8 @@
     }
 
     private static TypeStatePair findFirstAvailableUpstreamByType(
-            Iterable<NetworkState> netStates, Iterable<Integer> preferredTypes) {
+            Iterable<NetworkState> netStates, Iterable<Integer> preferredTypes,
+            boolean isCellularUpstreamPermitted) {
         final TypeStatePair result = new TypeStatePair();
 
         for (int type : preferredTypes) {
@@ -466,6 +505,10 @@
                        ConnectivityManager.getNetworkTypeName(type));
                 continue;
             }
+            if (!isCellularUpstreamPermitted && isCellular(nc)) {
+                continue;
+            }
+
             nc.setSingleUid(Process.myUid());
 
             for (NetworkState value : netStates) {
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 4e4b15f..ba4dcdb 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -1317,7 +1317,9 @@
         final int procState = ami.getUidProcessState(callingUid);
         final boolean isUidActive = ami.isUidActive(callingUid);
 
-        if (procState <= ActivityManager.PROCESS_STATE_TOP) {
+        // Providers bound by a TOP app will get PROCESS_STATE_BOUND_TOP, so include those as well
+        if (procState <= ActivityManager.PROCESS_STATE_TOP
+                || procState == ActivityManager.PROCESS_STATE_BOUND_TOP) {
             return ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP;
         }
         if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND || isUidActive) {
diff --git a/services/core/java/com/android/server/contentcapture/ContentCaptureManagerInternal.java b/services/core/java/com/android/server/contentcapture/ContentCaptureManagerInternal.java
index fa7d3fc..ad04b7d 100644
--- a/services/core/java/com/android/server/contentcapture/ContentCaptureManagerInternal.java
+++ b/services/core/java/com/android/server/contentcapture/ContentCaptureManagerInternal.java
@@ -49,6 +49,9 @@
     /**
      * Gets the content capture options for the given user and package, or {@code null} if the
      * package is not whitelisted by the service.
+     *
+     * <p><b>NOTE: </b>this method is called by the {@code ActivityManager} service and hence cannot
+     * hold the main service lock.
      */
     @Nullable
     public abstract ContentCaptureOptions getOptionsForPackage(@UserIdInt int userId,
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 45505c7..4f81c03 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -24,7 +24,6 @@
 import static android.hardware.display.ColorDisplayManager.COLOR_MODE_NATURAL;
 import static android.hardware.display.ColorDisplayManager.COLOR_MODE_SATURATED;
 
-import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE;
 import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
 
 import android.Manifest;
@@ -45,7 +44,6 @@
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
-import android.graphics.ColorSpace;
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.ColorDisplayManager.AutoMode;
 import android.hardware.display.ColorDisplayManager.ColorMode;
@@ -55,7 +53,6 @@
 import android.opengl.Matrix;
 import android.os.Binder;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemProperties;
@@ -65,7 +62,6 @@
 import android.util.MathUtils;
 import android.util.Slog;
 import android.view.SurfaceControl;
-import android.view.SurfaceControl.DisplayPrimaries;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.AnimationUtils;
 
@@ -98,7 +94,7 @@
     /**
      * The identity matrix, used if one of the given matrices is {@code null}.
      */
-    private static final float[] MATRIX_IDENTITY = new float[16];
+    static final float[] MATRIX_IDENTITY = new float[16];
 
     static {
         Matrix.setIdentityM(MATRIX_IDENTITY, 0);
@@ -1187,245 +1183,6 @@
         }
     }
 
-    final class DisplayWhiteBalanceTintController extends TintController {
-
-        // Three chromaticity coordinates per color: X, Y, and Z
-        private static final int NUM_VALUES_PER_PRIMARY = 3;
-        // Four colors: red, green, blue, and white
-        private static final int NUM_DISPLAY_PRIMARIES_VALS = 4 * NUM_VALUES_PER_PRIMARY;
-
-        private final Object mLock = new Object();
-        @VisibleForTesting
-        int mTemperatureMin;
-        @VisibleForTesting
-        int mTemperatureMax;
-        private int mTemperatureDefault;
-        private float[] mDisplayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
-        @VisibleForTesting
-        ColorSpace.Rgb mDisplayColorSpaceRGB;
-        private float[] mChromaticAdaptationMatrix;
-        @VisibleForTesting
-        int mCurrentColorTemperature;
-        private float[] mCurrentColorTemperatureXYZ;
-        private boolean mSetUp = false;
-        private float[] mMatrixDisplayWhiteBalance = new float[16];
-        private Boolean mIsAvailable;
-
-        @Override
-        public void setUp(Context context, boolean needsLinear) {
-            mSetUp = false;
-            final Resources res = context.getResources();
-
-            ColorSpace.Rgb displayColorSpaceRGB = getDisplayColorSpaceFromSurfaceControl();
-            if (displayColorSpaceRGB == null) {
-                Slog.w(TAG, "Failed to get display color space from SurfaceControl, trying res");
-                displayColorSpaceRGB = getDisplayColorSpaceFromResources(res);
-                if (displayColorSpaceRGB == null) {
-                    Slog.e(TAG, "Failed to get display color space from resources");
-                    return;
-                }
-            }
-
-            final String[] nominalWhiteValues = res.getStringArray(
-                    R.array.config_displayWhiteBalanceDisplayNominalWhite);
-            float[] displayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
-            for (int i = 0; i < nominalWhiteValues.length; i++) {
-                displayNominalWhiteXYZ[i] = Float.parseFloat(nominalWhiteValues[i]);
-            }
-
-            final int colorTemperatureMin = res.getInteger(
-                    R.integer.config_displayWhiteBalanceColorTemperatureMin);
-            if (colorTemperatureMin <= 0) {
-                Slog.e(TAG, "Display white balance minimum temperature must be greater than 0");
-                return;
-            }
-
-            final int colorTemperatureMax = res.getInteger(
-                    R.integer.config_displayWhiteBalanceColorTemperatureMax);
-            if (colorTemperatureMax < colorTemperatureMin) {
-                Slog.e(TAG, "Display white balance max temp must be greater or equal to min");
-                return;
-            }
-
-            final int colorTemperature = res.getInteger(
-                    R.integer.config_displayWhiteBalanceColorTemperatureDefault);
-
-            synchronized (mLock) {
-                mDisplayColorSpaceRGB = displayColorSpaceRGB;
-                mDisplayNominalWhiteXYZ = displayNominalWhiteXYZ;
-                mTemperatureMin = colorTemperatureMin;
-                mTemperatureMax = colorTemperatureMax;
-                mTemperatureDefault = colorTemperature;
-                mSetUp = true;
-            }
-
-            setMatrix(mTemperatureDefault);
-        }
-
-        @Override
-        public float[] getMatrix() {
-            return mSetUp && isActivated() ? mMatrixDisplayWhiteBalance : MATRIX_IDENTITY;
-        }
-
-        @Override
-        public void setMatrix(int cct) {
-            if (!mSetUp) {
-                Slog.w(TAG, "Can't set display white balance temperature: uninitialized");
-                return;
-            }
-
-            if (cct < mTemperatureMin) {
-                Slog.w(TAG, "Requested display color temperature is below allowed minimum");
-                cct = mTemperatureMin;
-            } else if (cct > mTemperatureMax) {
-                Slog.w(TAG, "Requested display color temperature is above allowed maximum");
-                cct = mTemperatureMax;
-            }
-
-            Slog.d(TAG, "setDisplayWhiteBalanceTemperatureMatrix: cct = " + cct);
-
-            synchronized (mLock) {
-                mCurrentColorTemperature = cct;
-
-                // Adapt the display's nominal white point to match the requested CCT value
-                mCurrentColorTemperatureXYZ = ColorSpace.cctToXyz(cct);
-
-                mChromaticAdaptationMatrix =
-                        ColorSpace.chromaticAdaptation(ColorSpace.Adaptation.BRADFORD,
-                                mDisplayNominalWhiteXYZ, mCurrentColorTemperatureXYZ);
-
-                // Convert the adaptation matrix to RGB space
-                float[] result = ColorSpace.mul3x3(mChromaticAdaptationMatrix,
-                        mDisplayColorSpaceRGB.getTransform());
-                result = ColorSpace.mul3x3(mDisplayColorSpaceRGB.getInverseTransform(), result);
-
-                // Normalize the transform matrix to peak white value in RGB space
-                final float adaptedMaxR = result[0] + result[3] + result[6];
-                final float adaptedMaxG = result[1] + result[4] + result[7];
-                final float adaptedMaxB = result[2] + result[5] + result[8];
-                final float denum = Math.max(Math.max(adaptedMaxR, adaptedMaxG), adaptedMaxB);
-                for (int i = 0; i < result.length; i++) {
-                    result[i] /= denum;
-                }
-
-                Matrix.setIdentityM(mMatrixDisplayWhiteBalance, 0);
-                java.lang.System.arraycopy(result, 0, mMatrixDisplayWhiteBalance, 0, 3);
-                java.lang.System.arraycopy(result, 3, mMatrixDisplayWhiteBalance, 4, 3);
-                java.lang.System.arraycopy(result, 6, mMatrixDisplayWhiteBalance, 8, 3);
-            }
-        }
-
-        @Override
-        public int getLevel() {
-            return LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE;
-        }
-
-        @Override
-        public boolean isAvailable(Context context) {
-            if (mIsAvailable == null) {
-                mIsAvailable = ColorDisplayManager.isDisplayWhiteBalanceAvailable(context);
-            }
-            return mIsAvailable;
-        }
-
-        /**
-         * Format a given matrix into a string.
-         *
-         * @param matrix the matrix to format
-         * @param cols number of columns in the matrix
-         */
-        private String matrixToString(float[] matrix, int cols) {
-            if (matrix == null || cols <= 0) {
-                Slog.e(TAG, "Invalid arguments when formatting matrix to string");
-                return "";
-            }
-
-            StringBuilder sb = new StringBuilder("");
-            for (int i = 0; i < matrix.length; i++) {
-                if (i % cols == 0) {
-                    sb.append("\n      ");
-                }
-                sb.append(String.format("%9.6f ", matrix[i]));
-            }
-            return sb.toString();
-        }
-
-        @Override
-        public void dump(PrintWriter pw) {
-            synchronized (mLock) {
-                pw.println("    mSetUp = " + mSetUp);
-                if (!mSetUp) {
-                    return;
-                }
-
-                pw.println("    mTemperatureMin = " + mTemperatureMin);
-                pw.println("    mTemperatureMax = " + mTemperatureMax);
-                pw.println("    mTemperatureDefault = " + mTemperatureDefault);
-                pw.println("    mCurrentColorTemperature = " + mCurrentColorTemperature);
-                pw.println("    mCurrentColorTemperatureXYZ = "
-                        + matrixToString(mCurrentColorTemperatureXYZ, 3));
-                pw.println("    mDisplayColorSpaceRGB RGB-to-XYZ = "
-                        + matrixToString(mDisplayColorSpaceRGB.getTransform(), 3));
-                pw.println("    mChromaticAdaptationMatrix = "
-                        + matrixToString(mChromaticAdaptationMatrix, 3));
-                pw.println("    mDisplayColorSpaceRGB XYZ-to-RGB = "
-                        + matrixToString(mDisplayColorSpaceRGB.getInverseTransform(), 3));
-                pw.println("    mMatrixDisplayWhiteBalance = "
-                        + matrixToString(mMatrixDisplayWhiteBalance, 4));
-            }
-        }
-
-        private ColorSpace.Rgb makeRgbColorSpaceFromXYZ(float[] redGreenBlueXYZ, float[] whiteXYZ) {
-            return new ColorSpace.Rgb(
-                    "Display Color Space",
-                    redGreenBlueXYZ,
-                    whiteXYZ,
-                    2.2f // gamma, unused for display white balance
-            );
-        }
-
-        private ColorSpace.Rgb getDisplayColorSpaceFromSurfaceControl() {
-            final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
-            if (displayToken == null) {
-                return null;
-            }
-
-            DisplayPrimaries primaries = SurfaceControl.getDisplayNativePrimaries(displayToken);
-            if (primaries == null || primaries.red == null || primaries.green == null
-                    || primaries.blue == null || primaries.white == null) {
-                return null;
-            }
-
-            return makeRgbColorSpaceFromXYZ(
-                    new float[]{
-                            primaries.red.X, primaries.red.Y, primaries.red.Z,
-                            primaries.green.X, primaries.green.Y, primaries.green.Z,
-                            primaries.blue.X, primaries.blue.Y, primaries.blue.Z,
-                    },
-                    new float[]{primaries.white.X, primaries.white.Y, primaries.white.Z}
-            );
-        }
-
-        private ColorSpace.Rgb getDisplayColorSpaceFromResources(Resources res) {
-            final String[] displayPrimariesValues = res.getStringArray(
-                    R.array.config_displayWhiteBalanceDisplayPrimaries);
-            float[] displayRedGreenBlueXYZ =
-                    new float[NUM_DISPLAY_PRIMARIES_VALS - NUM_VALUES_PER_PRIMARY];
-            float[] displayWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
-
-            for (int i = 0; i < displayRedGreenBlueXYZ.length; i++) {
-                displayRedGreenBlueXYZ[i] = Float.parseFloat(displayPrimariesValues[i]);
-            }
-
-            for (int i = 0; i < displayWhiteXYZ.length; i++) {
-                displayWhiteXYZ[i] = Float.parseFloat(
-                        displayPrimariesValues[displayRedGreenBlueXYZ.length + i]);
-            }
-
-            return makeRgbColorSpaceFromXYZ(displayRedGreenBlueXYZ, displayWhiteXYZ);
-        }
-    }
-
     /**
      * Local service that allows color transforms to be enabled from other system services.
      */
diff --git a/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
new file mode 100644
index 0000000..97c9c79
--- /dev/null
+++ b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.color;
+
+import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.ColorSpace;
+import android.hardware.display.ColorDisplayManager;
+import android.opengl.Matrix;
+import android.os.IBinder;
+import android.util.Slog;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.DisplayPrimaries;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+
+final class DisplayWhiteBalanceTintController extends TintController {
+
+    // Three chromaticity coordinates per color: X, Y, and Z
+    private static final int NUM_VALUES_PER_PRIMARY = 3;
+    // Four colors: red, green, blue, and white
+    private static final int NUM_DISPLAY_PRIMARIES_VALS = 4 * NUM_VALUES_PER_PRIMARY;
+
+    private final Object mLock = new Object();
+    @VisibleForTesting
+    int mTemperatureMin;
+    @VisibleForTesting
+    int mTemperatureMax;
+    private int mTemperatureDefault;
+    private float[] mDisplayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
+    @VisibleForTesting
+    ColorSpace.Rgb mDisplayColorSpaceRGB;
+    private float[] mChromaticAdaptationMatrix;
+    @VisibleForTesting
+    int mCurrentColorTemperature;
+    private float[] mCurrentColorTemperatureXYZ;
+    private boolean mSetUp = false;
+    private float[] mMatrixDisplayWhiteBalance = new float[16];
+    private Boolean mIsAvailable;
+
+    @Override
+    public void setUp(Context context, boolean needsLinear) {
+        mSetUp = false;
+        final Resources res = context.getResources();
+
+        ColorSpace.Rgb displayColorSpaceRGB = getDisplayColorSpaceFromSurfaceControl();
+        if (displayColorSpaceRGB == null) {
+            Slog.w(ColorDisplayService.TAG,
+                    "Failed to get display color space from SurfaceControl, trying res");
+            displayColorSpaceRGB = getDisplayColorSpaceFromResources(res);
+            if (displayColorSpaceRGB == null) {
+                Slog.e(ColorDisplayService.TAG, "Failed to get display color space from resources");
+                return;
+            }
+        }
+
+        final String[] nominalWhiteValues = res.getStringArray(
+                R.array.config_displayWhiteBalanceDisplayNominalWhite);
+        float[] displayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
+        for (int i = 0; i < nominalWhiteValues.length; i++) {
+            displayNominalWhiteXYZ[i] = Float.parseFloat(nominalWhiteValues[i]);
+        }
+
+        final int colorTemperatureMin = res.getInteger(
+                R.integer.config_displayWhiteBalanceColorTemperatureMin);
+        if (colorTemperatureMin <= 0) {
+            Slog.e(ColorDisplayService.TAG,
+                    "Display white balance minimum temperature must be greater than 0");
+            return;
+        }
+
+        final int colorTemperatureMax = res.getInteger(
+                R.integer.config_displayWhiteBalanceColorTemperatureMax);
+        if (colorTemperatureMax < colorTemperatureMin) {
+            Slog.e(ColorDisplayService.TAG,
+                    "Display white balance max temp must be greater or equal to min");
+            return;
+        }
+
+        final int colorTemperature = res.getInteger(
+                R.integer.config_displayWhiteBalanceColorTemperatureDefault);
+
+        synchronized (mLock) {
+            mDisplayColorSpaceRGB = displayColorSpaceRGB;
+            mDisplayNominalWhiteXYZ = displayNominalWhiteXYZ;
+            mTemperatureMin = colorTemperatureMin;
+            mTemperatureMax = colorTemperatureMax;
+            mTemperatureDefault = colorTemperature;
+            mSetUp = true;
+        }
+
+        setMatrix(mTemperatureDefault);
+    }
+
+    @Override
+    public float[] getMatrix() {
+        return mSetUp && isActivated() ? mMatrixDisplayWhiteBalance
+                : ColorDisplayService.MATRIX_IDENTITY;
+    }
+
+    @Override
+    public void setMatrix(int cct) {
+        if (!mSetUp) {
+            Slog.w(ColorDisplayService.TAG,
+                    "Can't set display white balance temperature: uninitialized");
+            return;
+        }
+
+        if (cct < mTemperatureMin) {
+            Slog.w(ColorDisplayService.TAG,
+                    "Requested display color temperature is below allowed minimum");
+            cct = mTemperatureMin;
+        } else if (cct > mTemperatureMax) {
+            Slog.w(ColorDisplayService.TAG,
+                    "Requested display color temperature is above allowed maximum");
+            cct = mTemperatureMax;
+        }
+
+        Slog.d(ColorDisplayService.TAG, "setDisplayWhiteBalanceTemperatureMatrix: cct = " + cct);
+
+        synchronized (mLock) {
+            mCurrentColorTemperature = cct;
+
+            // Adapt the display's nominal white point to match the requested CCT value
+            mCurrentColorTemperatureXYZ = ColorSpace.cctToXyz(cct);
+
+            mChromaticAdaptationMatrix =
+                    ColorSpace.chromaticAdaptation(ColorSpace.Adaptation.BRADFORD,
+                            mDisplayNominalWhiteXYZ, mCurrentColorTemperatureXYZ);
+
+            // Convert the adaptation matrix to RGB space
+            float[] result = ColorSpace.mul3x3(mChromaticAdaptationMatrix,
+                    mDisplayColorSpaceRGB.getTransform());
+            result = ColorSpace.mul3x3(mDisplayColorSpaceRGB.getInverseTransform(), result);
+
+            // Normalize the transform matrix to peak white value in RGB space
+            final float adaptedMaxR = result[0] + result[3] + result[6];
+            final float adaptedMaxG = result[1] + result[4] + result[7];
+            final float adaptedMaxB = result[2] + result[5] + result[8];
+            final float denum = Math.max(Math.max(adaptedMaxR, adaptedMaxG), adaptedMaxB);
+            for (int i = 0; i < result.length; i++) {
+                result[i] /= denum;
+            }
+
+            Matrix.setIdentityM(mMatrixDisplayWhiteBalance, 0);
+            java.lang.System.arraycopy(result, 0, mMatrixDisplayWhiteBalance, 0, 3);
+            java.lang.System.arraycopy(result, 3, mMatrixDisplayWhiteBalance, 4, 3);
+            java.lang.System.arraycopy(result, 6, mMatrixDisplayWhiteBalance, 8, 3);
+        }
+    }
+
+    @Override
+    public int getLevel() {
+        return LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE;
+    }
+
+    @Override
+    public boolean isAvailable(Context context) {
+        if (mIsAvailable == null) {
+            mIsAvailable = ColorDisplayManager.isDisplayWhiteBalanceAvailable(context);
+        }
+        return mIsAvailable;
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        synchronized (mLock) {
+            pw.println("    mSetUp = " + mSetUp);
+            if (!mSetUp) {
+                return;
+            }
+
+            pw.println("    mTemperatureMin = " + mTemperatureMin);
+            pw.println("    mTemperatureMax = " + mTemperatureMax);
+            pw.println("    mTemperatureDefault = " + mTemperatureDefault);
+            pw.println("    mCurrentColorTemperature = " + mCurrentColorTemperature);
+            pw.println("    mCurrentColorTemperatureXYZ = "
+                    + matrixToString(mCurrentColorTemperatureXYZ, 3));
+            pw.println("    mDisplayColorSpaceRGB RGB-to-XYZ = "
+                    + matrixToString(mDisplayColorSpaceRGB.getTransform(), 3));
+            pw.println("    mChromaticAdaptationMatrix = "
+                    + matrixToString(mChromaticAdaptationMatrix, 3));
+            pw.println("    mDisplayColorSpaceRGB XYZ-to-RGB = "
+                    + matrixToString(mDisplayColorSpaceRGB.getInverseTransform(), 3));
+            pw.println("    mMatrixDisplayWhiteBalance = "
+                    + matrixToString(mMatrixDisplayWhiteBalance, 4));
+        }
+    }
+
+    /**
+     * Format a given matrix into a string.
+     *
+     * @param matrix the matrix to format
+     * @param columns number of columns in the matrix
+     */
+    private String matrixToString(float[] matrix, int columns) {
+        if (matrix == null || columns <= 0) {
+            Slog.e(ColorDisplayService.TAG, "Invalid arguments when formatting matrix to string");
+            return "";
+        }
+
+        final StringBuilder sb = new StringBuilder("");
+        for (int i = 0; i < matrix.length; i++) {
+            if (i % columns == 0) {
+                sb.append("\n      ");
+            }
+            sb.append(String.format("%9.6f", matrix[i]));
+        }
+        return sb.toString();
+    }
+
+    private ColorSpace.Rgb makeRgbColorSpaceFromXYZ(float[] redGreenBlueXYZ, float[] whiteXYZ) {
+        return new ColorSpace.Rgb(
+                "Display Color Space",
+                redGreenBlueXYZ,
+                whiteXYZ,
+                2.2f // gamma, unused for display white balance
+        );
+    }
+
+    private ColorSpace.Rgb getDisplayColorSpaceFromSurfaceControl() {
+        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
+        if (displayToken == null) {
+            return null;
+        }
+
+        DisplayPrimaries primaries = SurfaceControl.getDisplayNativePrimaries(displayToken);
+        if (primaries == null || primaries.red == null || primaries.green == null
+                || primaries.blue == null || primaries.white == null) {
+            return null;
+        }
+
+        return makeRgbColorSpaceFromXYZ(
+                new float[]{
+                        primaries.red.X, primaries.red.Y, primaries.red.Z,
+                        primaries.green.X, primaries.green.Y, primaries.green.Z,
+                        primaries.blue.X, primaries.blue.Y, primaries.blue.Z,
+                },
+                new float[]{primaries.white.X, primaries.white.Y, primaries.white.Z}
+        );
+    }
+
+    private ColorSpace.Rgb getDisplayColorSpaceFromResources(Resources res) {
+        final String[] displayPrimariesValues = res.getStringArray(
+                R.array.config_displayWhiteBalanceDisplayPrimaries);
+        float[] displayRedGreenBlueXYZ =
+                new float[NUM_DISPLAY_PRIMARIES_VALS - NUM_VALUES_PER_PRIMARY];
+        float[] displayWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
+
+        for (int i = 0; i < displayRedGreenBlueXYZ.length; i++) {
+            displayRedGreenBlueXYZ[i] = Float.parseFloat(displayPrimariesValues[i]);
+        }
+
+        for (int i = 0; i < displayWhiteXYZ.length; i++) {
+            displayWhiteXYZ[i] = Float.parseFloat(
+                    displayPrimariesValues[displayRedGreenBlueXYZ.length + i]);
+        }
+
+        return makeRgbColorSpaceFromXYZ(displayRedGreenBlueXYZ, displayWhiteXYZ);
+    }
+}
diff --git a/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java b/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java
index 71fdcc7..a3d758d 100644
--- a/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java
+++ b/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java
@@ -26,7 +26,7 @@
 import java.util.Arrays;
 
 /** Control the color transform for global device saturation. */
-public class GlobalSaturationTintController extends TintController {
+final class GlobalSaturationTintController extends TintController {
 
     private final float[] mMatrixGlobalSaturation = new float[16];
 
diff --git a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
index df0dc77..b4c7dd3 100755
--- a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
+++ b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
@@ -335,7 +335,6 @@
         current.mDeviceType = params[2] & 0xFF;
         current.mDisplayName = HdmiUtils.getDefaultDeviceName(current.mDeviceType);
 
-        // TODO(amyjojo): check if non-TV device needs to update cec switch info.
         // This is to manager CEC device separately in case they don't have address.
         if (mIsTvDevice) {
             tv().updateCecSwitchInfo(current.mLogicalAddress, current.mDeviceType,
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 2026957..9e2fd4e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -74,7 +74,15 @@
     @GuardedBy("mLock")
     private boolean mSystemAudioControlFeatureEnabled;
 
-    private boolean mTvSystemAudioModeSupport;
+    /**
+     * Indicates if the TV that the current device is connected to supports System Audio Mode or not
+     *
+     * <p>If the current device has no information on this, keep mTvSystemAudioModeSupport null
+     *
+     * <p>The boolean will be reset to null every time when the current device goes to standby
+     * or loses its physical address.
+     */
+    private Boolean mTvSystemAudioModeSupport = null;
 
     // Whether ARC is available or not. "true" means that ARC is established between TV and
     // AVR as audio receiver.
@@ -314,14 +322,14 @@
         super.disableDevice(initiatedByCec, callback);
         assertRunOnServiceThread();
         mService.unregisterTvInputCallback(mTvInputCallback);
-        // TODO(amyjojo): check disableDevice and onStandby behaviors per spec
+        // TODO(b/129088603): check disableDevice and onStandby behaviors per spec
     }
 
     @Override
     @ServiceThreadOnly
     protected void onStandby(boolean initiatedByCec, int standbyAction) {
         assertRunOnServiceThread();
-        mTvSystemAudioModeSupport = false;
+        mTvSystemAudioModeSupport = null;
         // Record the last state of System Audio Control before going to standby
         synchronized (mLock) {
             mService.writeStringSystemProperty(
@@ -465,15 +473,6 @@
 
     @Override
     @ServiceThreadOnly
-    protected boolean handleReportAudioStatus(HdmiCecMessage message) {
-        assertRunOnServiceThread();
-        // TODO(amyjojo): implement report audio status handler
-        HdmiLogger.debug(TAG + "Stub handleReportAudioStatus");
-        return true;
-    }
-
-    @Override
-    @ServiceThreadOnly
     protected boolean handleInitiateArc(HdmiCecMessage message) {
         assertRunOnServiceThread();
         // TODO(amyjojo): implement initiate arc handler
@@ -970,7 +969,10 @@
     @ServiceThreadOnly
     void doManualPortSwitching(int portId, IHdmiControlCallback callback) {
         assertRunOnServiceThread();
-        // TODO: validate port ID
+        if (!mService.isValidPortId(portId)) {
+            invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
+            return;
+        }
         if (portId == getLocalActivePort()) {
             invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS);
             return;
@@ -1035,12 +1037,11 @@
      * <p>The result of the query may be cached until Audio device type is put in standby or loses
      * its physical address.
      */
-    // TODO(amyjojo): making mTvSystemAudioModeSupport null originally and fix the logic.
     void queryTvSystemAudioModeSupport(TvSystemAudioModeSupportedCallback callback) {
-        if (!mTvSystemAudioModeSupport) {
+        if (mTvSystemAudioModeSupport == null) {
             addAndStartAction(new DetectTvSystemAudioModeSupportAction(this, callback));
         } else {
-            callback.onResult(true);
+            callback.onResult(mTvSystemAudioModeSupport);
         }
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index f5adb01..3398d36 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1764,7 +1764,7 @@
         }
 
         @Override
-        // TODO(AMYJOJO): add a result callback
+        // TODO(b/128427908): add a result callback
         public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) {
             enforceAccessPermission();
             runOnServiceThread(new Runnable() {
diff --git a/services/core/java/com/android/server/incident/IncidentCompanionService.java b/services/core/java/com/android/server/incident/IncidentCompanionService.java
index 6f2bfc3..9989c1a 100644
--- a/services/core/java/com/android/server/incident/IncidentCompanionService.java
+++ b/services/core/java/com/android/server/incident/IncidentCompanionService.java
@@ -16,10 +16,26 @@
 
 package com.android.server.incident;
 
+import android.app.ActivityManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
 import android.os.Binder;
+import android.os.Build;
+import android.os.IBinder;
 import android.os.IIncidentAuthListener;
 import android.os.IIncidentCompanion;
+import android.os.IIncidentManager;
+import android.os.IncidentManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
 
 import com.android.internal.util.DumpUtils;
 import com.android.server.SystemService;
@@ -36,6 +52,20 @@
     static final String TAG = "IncidentCompanionService";
 
     /**
+     * Dump argument for proxying restricted image dumps to the services
+     * listed in the config.
+     */
+    private static String[] RESTRICTED_IMAGE_DUMP_ARGS = new String[] { "--restricted_image" };
+
+    /**
+     * The two permissions, for sendBroadcastAsUserMultiplePermissions.
+     */
+    private static final String[] DUMP_AND_USAGE_STATS_PERMISSIONS = new String[] {
+        android.Manifest.permission.DUMP,
+        android.Manifest.permission.PACKAGE_USAGE_STATS
+    };
+
+    /**
      * Tracker for reports pending approval.
      */
     private PendingReports mPendingReports;
@@ -45,16 +75,21 @@
      */
     private final class BinderService extends IIncidentCompanion.Stub {
         /**
-         * ONEWAY binder call to initiate authorizing the report.
+         * ONEWAY binder call to initiate authorizing the report. If you don't need
+         * IncidentCompanionService to check whether the calling UID matches then
+         * pass 0 for callingUid.  Either way, the caller must have DUMP and USAGE_STATS
+         * permissions to retrieve the data, so it ends up being about the same.
          */
         @Override
-        public void authorizeReport(int callingUid, final String callingPackage, int flags,
-                final IIncidentAuthListener listener) {
+        public void authorizeReport(int callingUid, final String callingPackage,
+                final String receiverClass, final String reportId,
+                final int flags, final IIncidentAuthListener listener) {
             enforceRequestAuthorizationPermission();
 
             final long ident = Binder.clearCallingIdentity();
             try {
-                mPendingReports.authorizeReport(callingUid, callingPackage, flags, listener);
+                mPendingReports.authorizeReport(callingUid, callingPackage,
+                        receiverClass, reportId, flags, listener);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -82,6 +117,38 @@
         }
 
         /**
+         * ONEWAY implementation to send broadcast from incidentd, which is native.
+         */
+        @Override
+        public void sendReportReadyBroadcast(String pkg, String cls) {
+            enforceRequestAuthorizationPermission();
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                final Context context = getContext();
+
+                final int primaryUser = getAndValidateUser(context);
+                if (primaryUser == UserHandle.USER_NULL) {
+                    return;
+                }
+
+                final Intent intent = new Intent(Intent.ACTION_INCIDENT_REPORT_READY);
+                intent.setComponent(new ComponentName(pkg, cls));
+
+                Log.d(TAG, "sendReportReadyBroadcast sending primaryUser=" + primaryUser
+                        + " userHandle=" + UserHandle.getUserHandleForUid(primaryUser)
+                        + " intent=" + intent);
+
+                // Send it to the primary user.  Only they can do incident reports.
+                context.sendBroadcastAsUserMultiplePermissions(intent,
+                        UserHandle.getUserHandleForUid(primaryUser),
+                        DUMP_AND_USAGE_STATS_PERMISSIONS);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        /**
          * SYNCHRONOUS binder call to get the list of reports that are pending confirmation
          * by the user.
          */
@@ -122,14 +189,122 @@
         }
 
         /**
-         * Implementation of adb shell dumpsys debugreportcompanion.
+         * SYNCHRONOUS binder call to get the list of incident reports waiting for a receiver.
+         */
+        @Override
+        public List<String> getIncidentReportList(String pkg, String cls) throws RemoteException {
+            enforceAccessReportsPermissions(null);
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return getIIncidentManager().getIncidentReportList(pkg, cls);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        /**
+         * SYNCHRONOUS binder call to commit an incident report
+         */
+        @Override
+        public void deleteIncidentReports(String pkg, String cls, String id)
+                throws RemoteException {
+            if (pkg == null || cls == null || id == null
+                    || pkg.length() == 0 || cls.length() == 0 || id.length() == 0) {
+                throw new RuntimeException("Invalid pkg, cls or id");
+            }
+            enforceAccessReportsPermissions(pkg);
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                getIIncidentManager().deleteIncidentReports(pkg, cls, id);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        /**
+         * SYNCHRONOUS binder call to delete all incident reports for a package.
+         */
+        @Override
+        public void deleteAllIncidentReports(String pkg) throws RemoteException {
+            if (pkg == null || pkg.length() == 0) {
+                throw new RuntimeException("Invalid pkg");
+            }
+            enforceAccessReportsPermissions(pkg);
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                getIIncidentManager().deleteAllIncidentReports(pkg);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        /**
+         * SYNCHRONOUS binder call to get the IncidentReport object.
+         */
+        @Override
+        public IncidentManager.IncidentReport getIncidentReport(String pkg, String cls, String id)
+                throws RemoteException {
+            if (pkg == null || cls == null || id == null
+                    || pkg.length() == 0 || cls.length() == 0 || id.length() == 0) {
+                throw new RuntimeException("Invalid pkg, cls or id");
+            }
+            enforceAccessReportsPermissions(pkg);
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return getIIncidentManager().getIncidentReport(pkg, cls, id);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        /**
+         * SYNCHRONOUS implementation of adb shell dumpsys debugreportcompanion.
          */
         @Override
         protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
             if (!DumpUtils.checkDumpPermission(getContext(), TAG, writer)) {
                 return;
             }
-            mPendingReports.dump(fd, writer, args);
+
+            if (args.length == 1 && "--restricted_image".equals(args[0])) {
+                // Does NOT clearCallingIdentity
+                dumpRestrictedImages(fd);
+            } else {
+                // Regular dump
+                mPendingReports.dump(fd, writer, args);
+            }
+        }
+
+        /**
+         * Proxy for the restricted images section.
+         */
+        private void dumpRestrictedImages(FileDescriptor fd) {
+            // Only supported on eng or userdebug.
+            if (!(Build.IS_ENG || Build.IS_USERDEBUG)) {
+                return;
+            }
+
+            final Resources res = getContext().getResources();
+            final String[] services = res.getStringArray(
+                    com.android.internal.R.array.config_restrictedImagesServices);
+            final int servicesCount = services.length;
+            for (int i = 0; i < servicesCount; i++) {
+                final String name = services[i];
+                Log.d(TAG, "Looking up service " + name);
+                final IBinder service = ServiceManager.getService(name);
+                if (service != null) {
+                    Log.d(TAG, "Calling dump on service: " + name);
+                    try {
+                        service.dump(fd, RESTRICTED_IMAGE_DUMP_ARGS);
+                    } catch (RemoteException ex) {
+                        Log.w(TAG, "dump --restricted_image of " + name + " threw", ex);
+                    }
+                }
+            }
         }
 
         /**
@@ -150,6 +325,51 @@
                     android.Manifest.permission.APPROVE_INCIDENT_REPORTS, null);
         }
 
+        /**
+         * Enforce that the calling process either has APPROVE_INCIDENT_REPORTS or
+         * (DUMP and PACKAGE_USAGE_STATS). This lets the approver get, because showing
+         * information about the report is a prerequisite for letting the user decide.
+         *
+         * If pkg is null, it is not checked, so make sure that you check it for null first
+         * if you do need the packages to match.
+         *
+         * Inside the binder interface class because we want to do all of the authorization
+         * here, before calling out to the helper objects.
+         */
+        private void enforceAccessReportsPermissions(String pkg) {
+            if (getContext().checkCallingPermission(
+                        android.Manifest.permission.APPROVE_INCIDENT_REPORTS)
+                    != PackageManager.PERMISSION_GRANTED) {
+                getContext().enforceCallingOrSelfPermission(
+                        android.Manifest.permission.DUMP, null);
+                getContext().enforceCallingOrSelfPermission(
+                        android.Manifest.permission.PACKAGE_USAGE_STATS, null);
+                if (pkg != null) {
+                    enforceCallerIsSameApp(pkg);
+                }
+            }
+        }
+
+        /**
+         * Throw a SecurityException if the incoming binder call is not from pkg.
+         */
+        private void enforceCallerIsSameApp(String pkg) throws SecurityException {
+            try {
+                final int uid = Binder.getCallingUid();
+                final int userId = UserHandle.getCallingUserId();
+                final ApplicationInfo ai = getContext().getPackageManager()
+                        .getApplicationInfoAsUser(pkg, 0, userId);
+                if (ai == null) {
+                    throw new SecurityException("Unknown package " + pkg);
+                }
+                if (!UserHandle.isSameApp(ai.uid, uid)) {
+                    throw new SecurityException("Calling uid " + uid + " gave package "
+                            + pkg + " which is owned by uid " + ai.uid);
+                }
+            } catch (PackageManager.NameNotFoundException re) {
+                throw new SecurityException("Unknown package " + pkg + "\n" + re);
+            }
+        }
     }
 
     /**
@@ -182,5 +402,52 @@
                 break;
         }
     }
+
+    /**
+     * Looks up incidentd every time, so we don't need a complex handshake between
+     * incidentd and IncidentCompanionService.
+     */
+    private IIncidentManager getIIncidentManager() throws RemoteException {
+        return IIncidentManager.Stub.asInterface(
+                ServiceManager.getService(Context.INCIDENT_SERVICE));
+    }
+
+    /**
+     * Check whether the current user is the primary user, and return the user id if they are.
+     * Returns UserHandle.USER_NULL if not valid.
+     */
+    public static int getAndValidateUser(Context context) {
+        // Current user
+        UserInfo currentUser;
+        try {
+            currentUser = ActivityManager.getService().getCurrentUser();
+        } catch (RemoteException ex) {
+            // We're already inside the system process.
+            throw new RuntimeException(ex);
+        }
+
+        // Primary user
+        final UserManager um = UserManager.get(context);
+        final UserInfo primaryUser = um.getPrimaryUser();
+
+        // Check that we're using the right user.
+        if (currentUser == null) {
+            Log.w(TAG, "No current user.  Nobody to approve the report."
+                    + " The report will be denied.");
+            return UserHandle.USER_NULL;
+        }
+        if (primaryUser == null) {
+            Log.w(TAG, "No primary user.  Nobody to approve the report."
+                    + " The report will be denied.");
+            return UserHandle.USER_NULL;
+        }
+        if (primaryUser.id != currentUser.id) {
+            Log.w(TAG, "Only the primary user can approve bugreports, but they are not"
+                    + " the current user. The report will be denied.");
+            return UserHandle.USER_NULL;
+        }
+
+        return primaryUser.id;
+    }
 }
 
diff --git a/services/core/java/com/android/server/incident/PendingReports.java b/services/core/java/com/android/server/incident/PendingReports.java
index 519ed41..a749d26 100644
--- a/services/core/java/com/android/server/incident/PendingReports.java
+++ b/services/core/java/com/android/server/incident/PendingReports.java
@@ -16,14 +16,12 @@
 
 package com.android.server.incident;
 
-import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.IIncidentAuthListener;
@@ -31,7 +29,6 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.util.Log;
 
 import java.io.FileDescriptor;
@@ -76,24 +73,29 @@
         public IIncidentAuthListener listener;
         public long addedRealtime;
         public long addedWalltime;
+        public String receiverClass;
+        public String reportId;
 
         /**
          * Construct a PendingReportRec, with an auto-incremented id.
          */
-        PendingReportRec(String callingPackage, int flags, IIncidentAuthListener listener) {
+        PendingReportRec(String callingPackage, String receiverClass, String reportId, int flags,
+                IIncidentAuthListener listener) {
             this.id = mNextPendingId++;
             this.callingPackage = callingPackage;
             this.flags = flags;
             this.listener = listener;
             this.addedRealtime = SystemClock.elapsedRealtime();
             this.addedWalltime = System.currentTimeMillis();
+            this.receiverClass = receiverClass;
+            this.reportId = reportId;
         }
 
         /**
          * Get the Uri that contains the flattened data.
          */
         Uri getUri() {
-            return (new Uri.Builder())
+            final Uri.Builder builder = (new Uri.Builder())
                     .scheme(IncidentManager.URI_SCHEME)
                     .authority(IncidentManager.URI_AUTHORITY)
                     .path(IncidentManager.URI_PATH)
@@ -101,8 +103,15 @@
                     .appendQueryParameter(IncidentManager.URI_PARAM_CALLING_PACKAGE, callingPackage)
                     .appendQueryParameter(IncidentManager.URI_PARAM_FLAGS, Integer.toString(flags))
                     .appendQueryParameter(IncidentManager.URI_PARAM_TIMESTAMP,
-                            Long.toString(addedWalltime))
-                    .build();
+                            Long.toString(addedWalltime));
+            if (receiverClass != null && receiverClass.length() > 0) {
+                builder.appendQueryParameter(IncidentManager.URI_PARAM_RECEIVER_CLASS,
+                        receiverClass);
+            }
+            if (reportId != null && reportId.length() > 0) {
+                builder.appendQueryParameter(IncidentManager.URI_PARAM_REPORT_ID, reportId);
+            }
+            return builder.build();
         }
     }
 
@@ -121,13 +130,15 @@
      * <p>
      * The security checks are handled by IncidentCompanionService.
      */
-    public void authorizeReport(int callingUid, final String callingPackage, final int flags,
+    public void authorizeReport(int callingUid, final String callingPackage,
+            final String receiverClass, final String reportId, final int flags,
             final IIncidentAuthListener listener) {
         // Starting the system server is complicated, and rather than try to
         // have a complicated lifecycle that we share with dumpstated and incidentd,
         // we will accept the request, and then display it whenever it becomes possible to.
         mRequestQueue.enqueue(listener.asBinder(), true, () -> {
-            authorizeReportImpl(callingUid, callingPackage, flags, listener);
+            authorizeReportImpl(callingUid, callingPackage, receiverClass, reportId,
+                    flags, listener);
         });
     }
 
@@ -248,10 +259,11 @@
     /**
      * Start the confirmation process.
      */
-    private void authorizeReportImpl(int callingUid, final String callingPackage, int flags,
-            final IIncidentAuthListener listener) {
+    private void authorizeReportImpl(int callingUid, final String callingPackage,
+            final String receiverClass, final String reportId,
+            int flags, final IIncidentAuthListener listener) {
         // Enforce that the calling package pertains to the callingUid.
-        if (!isPackageInUid(callingUid, callingPackage)) {
+        if (callingUid != 0 && !isPackageInUid(callingUid, callingPackage)) {
             Log.w(TAG, "Calling uid " + callingUid + " doesn't match package "
                     + callingPackage);
             denyReportBeforeAddingRec(listener, callingPackage);
@@ -277,7 +289,7 @@
         // Save the record for when the PermissionController comes back to authorize it.
         PendingReportRec rec = null;
         synchronized (mLock) {
-            rec = new PendingReportRec(callingPackage, flags, listener);
+            rec = new PendingReportRec(callingPackage, receiverClass, reportId, flags, listener);
             mPending.add(rec);
         }
 
@@ -406,37 +418,7 @@
      * Returns UserHandle.USER_NULL if not valid.
      */
     private int getAndValidateUser() {
-        // Current user
-        UserInfo currentUser;
-        try {
-            currentUser = ActivityManager.getService().getCurrentUser();
-        } catch (RemoteException ex) {
-            // We're already inside the system process.
-            throw new RuntimeException(ex);
-        }
-
-        // Primary user
-        final UserManager um = UserManager.get(mContext);
-        final UserInfo primaryUser = um.getPrimaryUser();
-
-        // Check that we're using the right user.
-        if (currentUser == null) {
-            Log.w(TAG, "No current user.  Nobody to approve the report."
-                    + " The report will be denied.");
-            return UserHandle.USER_NULL;
-        }
-        if (primaryUser == null) {
-            Log.w(TAG, "No primary user.  Nobody to approve the report."
-                    + " The report will be denied.");
-            return UserHandle.USER_NULL;
-        }
-        if (primaryUser.id != currentUser.id) {
-            Log.w(TAG, "Only the primary user can approve bugreports, but they are not"
-                    + " the current user. The report will be denied.");
-            return UserHandle.USER_NULL;
-        }
-
-        return primaryUser.id;
+        return IncidentCompanionService.getAndValidateUser(mContext);
     }
 
     /**
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index ed894ee..098b0e9 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -181,9 +181,8 @@
 
         mServiceNameResolver = serviceNameResolver;
         if (mServiceNameResolver != null) {
-            mServiceNameResolver
-                    .setOnTemporaryServiceNameChangedCallback(
-                            (u, s) -> updateCachedServiceLocked(u));
+            mServiceNameResolver.setOnTemporaryServiceNameChangedCallback(
+                    (u, s, t) -> onServiceNameChanged(u, s, t));
 
         }
         if (disallowProperty == null) {
@@ -582,6 +581,23 @@
     }
 
     /**
+     * Called when the service name changed (typically when using temporary services).
+     *
+     * <p>By default, it calls {@link #updateCachedServiceLocked(int)}; subclasses must either call
+     * that same method, or {@code super.onServiceNameChanged()}.
+     *
+     * @param userId user handle.
+     * @param serviceName the new service name.
+     * @param isTemporary whether the new service is temporary.
+     */
+    protected void onServiceNameChanged(@UserIdInt int userId, @Nullable String serviceName,
+            boolean isTemporary) {
+        synchronized (mLock) {
+            updateCachedServiceLocked(userId);
+        }
+    }
+
+    /**
      * Visits all services in the cache.
      */
     @GuardedBy("mLock")
@@ -600,6 +616,23 @@
         mServicesCache.clear();
     }
 
+    /**
+     * Asserts that the given package name is owned by the UID making this call.
+     *
+     * @throws SecurityException when it's not...
+     */
+    protected final void assertCalledByPackageOwner(@NonNull String packageName) {
+        Preconditions.checkNotNull(packageName);
+        final int uid = Binder.getCallingUid();
+        final String[] packages = getContext().getPackageManager().getPackagesForUid(uid);
+        if (packages != null) {
+            for (String candidate : packages) {
+                if (packageName.equals(candidate)) return; // Found it
+            }
+        }
+        throw new SecurityException("UID " + uid + " does not own " + packageName);
+    }
+
     // TODO(b/117779333): support proto
     protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
         boolean realDebug = debug;
diff --git a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
index ac07e9d..c52921e 100644
--- a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
@@ -113,6 +113,13 @@
     }
 
     /**
+     * Gets whether the service is disabled by {@link UserManager} restrictions.
+     */
+    protected final boolean isDisabledByUserRestrictionsLocked() {
+        return mDisabled;
+    }
+
+    /**
      * Updates the state of this service.
      *
      * <p>Typically called when the service {@link Settings} property or {@link UserManager}
@@ -136,7 +143,9 @@
                     + ", disabled=" + disabled + ", mDisabled=" + mDisabled);
         }
 
-        mSetupComplete = isSetupCompletedLocked();
+        final String setupComplete = Settings.Secure.getStringForUser(
+                getContext().getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
+        mSetupComplete = "1".equals(setupComplete);
         mDisabled = disabled;
 
         updateServiceInfoLocked();
@@ -235,6 +244,15 @@
     }
 
     /**
+     * Gets the {@link ServiceInfo} of the remote service this service binds to, or {@code null}
+     * if the service is disabled.
+     */
+    @Nullable
+    public final ServiceInfo getServiceInfo() {
+        return mServiceInfo;
+    }
+
+    /**
      * Gets the {@link ComponentName} of the remote service this service binds to, or {@code null}
      * if the service is disabled.
      */
@@ -311,9 +329,7 @@
      * Gets whether the device already finished setup.
      */
     protected final boolean isSetupCompletedLocked() {
-        final String setupComplete = Settings.Secure.getStringForUser(
-                getContext().getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
-        return "1".equals(setupComplete);
+        return mSetupComplete;
     }
 
     /**
diff --git a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
index d204813..35d5956 100644
--- a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
+++ b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
@@ -155,7 +155,8 @@
             }
             mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs;
             mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs);
-            notifyTemporaryServiceNameChangedLocked(userId, componentName);
+            notifyTemporaryServiceNameChangedLocked(userId, componentName,
+                    /* isTemporary= */ true);
         }
     }
 
@@ -169,7 +170,8 @@
                 mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE);
                 mTemporaryHandler = null;
             }
-            notifyTemporaryServiceNameChangedLocked(userId, /* newTemporaryName= */ null);
+            notifyTemporaryServiceNameChangedLocked(userId, /* newTemporaryName= */ null,
+                    /* isTemporary= */ false);
         }
     }
 
@@ -235,9 +237,9 @@
     }
 
     private void notifyTemporaryServiceNameChangedLocked(@UserIdInt int userId,
-            @Nullable String newTemporaryName) {
+            @Nullable String newTemporaryName, boolean isTemporary) {
         if (mOnSetCallback != null) {
-            mOnSetCallback.onNameResolved(userId, newTemporaryName);
+            mOnSetCallback.onNameResolved(userId, newTemporaryName, isTemporary);
         }
     }
 }
diff --git a/services/core/java/com/android/server/infra/ServiceNameResolver.java b/services/core/java/com/android/server/infra/ServiceNameResolver.java
index 8c348ebb..e20c459 100644
--- a/services/core/java/com/android/server/infra/ServiceNameResolver.java
+++ b/services/core/java/com/android/server/infra/ServiceNameResolver.java
@@ -39,7 +39,8 @@
         /**
          * The name change callback.
          */
-        void onNameResolved(@UserIdInt int userId, @Nullable String serviceName);
+        void onNameResolved(@UserIdInt int userId, @Nullable String serviceName,
+                boolean isTemporary);
     }
 
     /**
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 622c49e..cec4d69 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -69,11 +69,13 @@
 import android.view.Display;
 import android.view.IInputFilter;
 import android.view.IInputFilterHost;
+import android.view.IInputMonitorHost;
 import android.view.IWindow;
 import android.view.InputApplicationHandle;
 import android.view.InputChannel;
 import android.view.InputDevice;
 import android.view.InputEvent;
+import android.view.InputMonitor;
 import android.view.InputWindowHandle;
 import android.view.KeyEvent;
 import android.view.PointerIcon;
@@ -202,7 +204,10 @@
             int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists);
     private static native void nativeRegisterInputChannel(long ptr, InputChannel inputChannel,
             int displayId);
+    private static native void nativeRegisterInputMonitor(long ptr, InputChannel inputChannel,
+            int displayId, boolean isGestureMonitor);
     private static native void nativeUnregisterInputChannel(long ptr, InputChannel inputChannel);
+    private static native void nativePilferPointers(long ptr, IBinder token);
     private static native void nativeSetInputFilterEnabled(long ptr, boolean enable);
     private static native int nativeInjectInputEvent(long ptr, InputEvent event,
             int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
@@ -489,12 +494,43 @@
         }
 
         InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
-        nativeRegisterInputChannel(mPtr, inputChannels[0], displayId);
+        // Give the output channel a token just for identity purposes.
+        inputChannels[0].setToken(new Binder());
+        nativeRegisterInputMonitor(mPtr, inputChannels[0], displayId, false /*isGestureMonitor*/);
         inputChannels[0].dispose(); // don't need to retain the Java object reference
         return inputChannels[1];
     }
 
     /**
+     * Creates an input monitor that will receive pointer events for the purposes of system-wide
+     * gesture interpretation.
+     *
+     * @param inputChannelName The input channel name.
+     * @param displayId Target display id.
+     * @return The input channel.
+     */
+    @Override // Binder call
+    public InputMonitor monitorGestureInput(String inputChannelName, int displayId) {
+        if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT,
+                "monitorInputRegion()")) {
+            throw new SecurityException("Requires MONITOR_INPUT permission");
+        }
+
+        Objects.requireNonNull(inputChannelName, "inputChannelName must not be null.");
+
+        if (displayId < Display.DEFAULT_DISPLAY) {
+            throw new IllegalArgumentException("displayId must >= 0.");
+        }
+
+
+        InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
+        InputMonitorHost host = new InputMonitorHost(inputChannels[0]);
+        inputChannels[0].setToken(host.asBinder());
+        nativeRegisterInputMonitor(mPtr, inputChannels[0], displayId, true /*isGestureMonitor*/);
+        return new InputMonitor(inputChannelName, inputChannels[1], host);
+    }
+
+    /**
      * Registers an input channel so that it can be used as an input event target.
      * @param inputChannel The input channel to register.
      * @param inputWindowHandle The handle of the input window associated with the
@@ -1809,6 +1845,11 @@
     }
 
     // Native callback.
+    private void onPointerDownOutsideFocus(IBinder touchedToken) {
+        mWindowManagerCallbacks.onPointerDownOutsideFocus(touchedToken);
+    }
+
+    // Native callback.
     private int getVirtualKeyQuietTimeMillis() {
         return mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
@@ -2020,6 +2061,14 @@
         public int getPointerLayer();
 
         public int getPointerDisplayId();
+
+        /**
+         * Notifies window manager that a {@link android.view.MotionEvent#ACTION_DOWN} pointer event
+         * occurred on a window that did not have focus.
+         *
+         * @param touchedToken The token for the window that received the input event.
+         */
+        void onPointerDownOutsideFocus(IBinder touchedToken);
     }
 
     /**
@@ -2092,6 +2141,28 @@
         }
     }
 
+    /**
+     * Interface for the system to handle request from InputMonitors.
+     */
+    private final class InputMonitorHost extends IInputMonitorHost.Stub {
+        private final InputChannel mInputChannel;
+
+        InputMonitorHost(InputChannel channel) {
+            mInputChannel = channel;
+        }
+
+        @Override
+        public void pilferPointers() {
+            nativePilferPointers(mPtr, asBinder());
+        }
+
+        @Override
+        public void dispose() {
+            nativeUnregisterInputChannel(mPtr, mInputChannel);
+            mInputChannel.dispose();
+        }
+    }
+
     private static final class KeyboardLayoutDescriptor {
         public String packageName;
         public String receiverName;
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 6255306..64c23af 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -40,6 +40,7 @@
 import android.util.SparseArray;
 import android.util.Xml;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.BitUtils;
@@ -85,9 +86,10 @@
     private static final boolean DEBUG = JobSchedulerService.DEBUG;
 
     /** Threshold to adjust how often we want to write to the db. */
-    private static final int MAX_OPS_BEFORE_WRITE = 1;
+    private static final long JOB_PERSIST_DELAY = 2000L;
 
     final Object mLock;
+    final Object mWriteScheduleLock;    // used solely for invariants around write scheduling
     final JobSet mJobSet; // per-caller-uid and per-source-uid tracking
     final Context mContext;
 
@@ -95,7 +97,11 @@
     private final long mXmlTimestamp;
     private boolean mRtcGood;
 
-    private int mDirtyOperations;
+    @GuardedBy("mWriteScheduleLock")
+    private boolean mWriteScheduled;
+
+    @GuardedBy("mWriteScheduleLock")
+    private boolean mWriteInProgress;
 
     private static final Object sSingletonLock = new Object();
     private final AtomicFile mJobsFile;
@@ -131,8 +137,8 @@
      */
     private JobStore(Context context, Object lock, File dataDir) {
         mLock = lock;
+        mWriteScheduleLock = new Object();
         mContext = context;
-        mDirtyOperations = 0;
 
         File systemDir = new File(dataDir, "system");
         File jobDir = new File(systemDir, "job");
@@ -322,13 +328,14 @@
      * track incremental changes.
      */
     private void maybeWriteStatusToDiskAsync() {
-        mDirtyOperations++;
-        if (mDirtyOperations >= MAX_OPS_BEFORE_WRITE) {
-            if (DEBUG) {
-                Slog.v(TAG, "Writing jobs to disk.");
+        synchronized (mWriteScheduleLock) {
+            if (!mWriteScheduled) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Scheduling persist of jobs to disk.");
+                }
+                mIoHandler.postDelayed(mWriteRunnable, JOB_PERSIST_DELAY);
+                mWriteScheduled = mWriteInProgress = true;
             }
-            mIoHandler.removeCallbacks(mWriteRunnable);
-            mIoHandler.post(mWriteRunnable);
         }
     }
 
@@ -338,6 +345,34 @@
     }
 
     /**
+     * Wait for any pending write to the persistent store to clear
+     * @param maxWaitMillis Maximum time from present to wait
+     * @return {@code true} if I/O cleared as expected, {@code false} if the wait
+     *     timed out before the pending write completed.
+     */
+    @VisibleForTesting
+    public boolean waitForWriteToCompleteForTesting(long maxWaitMillis) {
+        final long start = SystemClock.uptimeMillis();
+        final long end = start + maxWaitMillis;
+        synchronized (mWriteScheduleLock) {
+            while (mWriteInProgress) {
+                final long now = SystemClock.uptimeMillis();
+                if (now >= end) {
+                    // still not done and we've hit the end; failure
+                    return false;
+                }
+                try {
+                    mWriteScheduleLock.wait(now - start + maxWaitMillis);
+                } catch (InterruptedException e) {
+                    // Spurious; keep waiting
+                    break;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
      * Runnable that writes {@link #mJobSet} out to xml.
      * NOTE: This Runnable locks on mLock
      */
@@ -346,6 +381,16 @@
         public void run() {
             final long startElapsed = sElapsedRealtimeClock.millis();
             final List<JobStatus> storeCopy = new ArrayList<JobStatus>();
+            // Intentionally allow new scheduling of a write operation *before* we clone
+            // the job set.  If we reset it to false after cloning, there's a window in
+            // which no new write will be scheduled but mLock is not held, i.e. a new
+            // job might appear and fail to be recognized as needing a persist.  The
+            // potential cost is one redundant write of an identical set of jobs in the
+            // rare case of that specific race, but by doing it this way we avoid quite
+            // a bit of lock contention.
+            synchronized (mWriteScheduleLock) {
+                mWriteScheduled = false;
+            }
             synchronized (mLock) {
                 // Clone the jobs so we can release the lock before writing.
                 mJobSet.forEachJob(null, (job) -> {
@@ -359,6 +404,10 @@
                 Slog.v(TAG, "Finished writing, took " + (sElapsedRealtimeClock.millis()
                         - startElapsed) + "ms");
             }
+            synchronized (mWriteScheduleLock) {
+                mWriteInProgress = false;
+                mWriteScheduleLock.notifyAll();
+            }
         }
 
         private void writeJobsMapImpl(List<JobStatus> jobList) {
@@ -402,7 +451,6 @@
                 FileOutputStream fos = mJobsFile.startWrite(startTime);
                 fos.write(baos.toByteArray());
                 mJobsFile.finishWrite(fos);
-                mDirtyOperations = 0;
             } catch (IOException e) {
                 if (DEBUG) {
                     Slog.v(TAG, "Error writing out job data.", e);
@@ -979,38 +1027,6 @@
                     : JobStatus.NO_LATEST_RUNTIME;
             return Pair.create(earliestRunTimeRtc, latestRunTimeRtc);
         }
-
-        /**
-         * Convenience function to read out and convert deadline and delay from xml into elapsed real
-         * time.
-         * @return A {@link android.util.Pair}, where the first value is the earliest elapsed runtime
-         * and the second is the latest elapsed runtime.
-         */
-        private Pair<Long, Long> buildExecutionTimesFromXml(XmlPullParser parser)
-                throws NumberFormatException {
-            // Pull out execution time data.
-            final long nowWallclock = sSystemClock.millis();
-            final long nowElapsed = sElapsedRealtimeClock.millis();
-
-            long earliestRunTimeElapsed = JobStatus.NO_EARLIEST_RUNTIME;
-            long latestRunTimeElapsed = JobStatus.NO_LATEST_RUNTIME;
-            String val = parser.getAttributeValue(null, "deadline");
-            if (val != null) {
-                long latestRuntimeWallclock = Long.parseLong(val);
-                long maxDelayElapsed =
-                        Math.max(latestRuntimeWallclock - nowWallclock, 0);
-                latestRunTimeElapsed = nowElapsed + maxDelayElapsed;
-            }
-            val = parser.getAttributeValue(null, "delay");
-            if (val != null) {
-                long earliestRuntimeWallclock = Long.parseLong(val);
-                long minDelayElapsed =
-                        Math.max(earliestRuntimeWallclock - nowWallclock, 0);
-                earliestRunTimeElapsed = nowElapsed + minDelayElapsed;
-
-            }
-            return Pair.create(earliestRunTimeElapsed, latestRunTimeElapsed);
-        }
     }
 
     static final class JobSet {
diff --git a/services/core/java/com/android/server/job/controllers/QuotaController.java b/services/core/java/com/android/server/job/controllers/QuotaController.java
index 5a0b991..1820acf 100644
--- a/services/core/java/com/android/server/job/controllers/QuotaController.java
+++ b/services/core/java/com/android/server/job/controllers/QuotaController.java
@@ -769,6 +769,91 @@
                 mMaxExecutionTimeMs - stats.executionTimeInMaxPeriodMs);
     }
 
+    /**
+     * Returns the amount of time, in milliseconds, until the package would have reached its
+     * duration quota, assuming it has a job counting towards its quota the entire time. This takes
+     * into account any {@link TimingSession}s that may roll out of the window as the job is
+     * running.
+     */
+    @VisibleForTesting
+    long getTimeUntilQuotaConsumedLocked(final int userId, @NonNull final String packageName) {
+        final long nowElapsed = sElapsedRealtimeClock.millis();
+        final int standbyBucket = JobSchedulerService.standbyBucketForPackage(
+                packageName, userId, nowElapsed);
+        if (standbyBucket == NEVER_INDEX) {
+            return 0;
+        }
+        List<TimingSession> sessions = mTimingSessions.get(userId, packageName);
+        if (sessions == null || sessions.size() == 0) {
+            return mAllowedTimePerPeriodMs;
+        }
+
+        final ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket);
+        final long startWindowElapsed = nowElapsed - stats.windowSizeMs;
+        final long startMaxElapsed = nowElapsed - MAX_PERIOD_MS;
+        final long allowedTimeRemainingMs = mAllowedTimePerPeriodMs - stats.executionTimeInWindowMs;
+        final long maxExecutionTimeRemainingMs =
+                mMaxExecutionTimeMs - stats.executionTimeInMaxPeriodMs;
+
+        // Regular ACTIVE case. Since the bucket size equals the allowed time, the app jobs can
+        // essentially run until they reach the maximum limit.
+        if (stats.windowSizeMs == mAllowedTimePerPeriodMs) {
+            return calculateTimeUntilQuotaConsumedLocked(
+                    sessions, startMaxElapsed, maxExecutionTimeRemainingMs);
+        }
+
+        // Need to check both max time and period time in case one is less than the other.
+        // For example, max time remaining could be less than bucket time remaining, but sessions
+        // contributing to the max time remaining could phase out enough that we'd want to use the
+        // bucket value.
+        return Math.min(
+                calculateTimeUntilQuotaConsumedLocked(
+                        sessions, startMaxElapsed, maxExecutionTimeRemainingMs),
+                calculateTimeUntilQuotaConsumedLocked(
+                        sessions, startWindowElapsed, allowedTimeRemainingMs));
+    }
+
+    /**
+     * Calculates how much time it will take, in milliseconds, until the quota is fully consumed.
+     *
+     * @param windowStartElapsed The start of the window, in the elapsed realtime timebase.
+     * @param deadSpaceMs        How much time can be allowed to count towards the quota
+     */
+    private long calculateTimeUntilQuotaConsumedLocked(@NonNull List<TimingSession> sessions,
+            final long windowStartElapsed, long deadSpaceMs) {
+        long timeUntilQuotaConsumedMs = 0;
+        long start = windowStartElapsed;
+        for (int i = 0; i < sessions.size(); ++i) {
+            TimingSession session = sessions.get(i);
+
+            if (session.endTimeElapsed < windowStartElapsed) {
+                // Outside of window. Ignore.
+                continue;
+            } else if (session.startTimeElapsed <= windowStartElapsed) {
+                // Overlapping session. Can extend time by portion of session in window.
+                timeUntilQuotaConsumedMs += session.endTimeElapsed - windowStartElapsed;
+                start = session.endTimeElapsed;
+            } else {
+                // Completely within the window. Can only consider if there's enough dead space
+                // to get to the start of the session.
+                long diff = session.startTimeElapsed - start;
+                if (diff > deadSpaceMs) {
+                    break;
+                }
+                timeUntilQuotaConsumedMs += diff
+                        + (session.endTimeElapsed - session.startTimeElapsed);
+                deadSpaceMs -= diff;
+                start = session.endTimeElapsed;
+            }
+        }
+        // Will be non-zero if the loop didn't look at any sessions.
+        timeUntilQuotaConsumedMs += deadSpaceMs;
+        if (timeUntilQuotaConsumedMs > mMaxExecutionTimeMs) {
+            Slog.wtf(TAG, "Calculated quota consumed time too high: " + timeUntilQuotaConsumedMs);
+        }
+        return timeUntilQuotaConsumedMs;
+    }
+
     /** Returns the execution stats of the app in the most recent window. */
     @VisibleForTesting
     @NonNull
@@ -1483,7 +1568,7 @@
                     return;
                 }
                 Message msg = mHandler.obtainMessage(MSG_REACHED_QUOTA, mPkg);
-                final long timeRemainingMs = getRemainingExecutionTimeLocked(mPkg.userId,
+                final long timeRemainingMs = getTimeUntilQuotaConsumedLocked(mPkg.userId,
                         mPkg.packageName);
                 if (DEBUG) {
                     Slog.i(TAG, "Job for " + mPkg + " has " + timeRemainingMs + "ms left.");
@@ -1642,6 +1727,8 @@
                             // job is currently running.
                             // Reschedule message
                             Message rescheduleMsg = obtainMessage(MSG_REACHED_QUOTA, pkg);
+                            timeRemainingMs = getTimeUntilQuotaConsumedLocked(pkg.userId,
+                                    pkg.packageName);
                             if (DEBUG) {
                                 Slog.d(TAG, pkg + " has " + timeRemainingMs + "ms left.");
                             }
diff --git a/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java b/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java
new file mode 100644
index 0000000..98085b8
--- /dev/null
+++ b/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location;
+
+import android.location.GnssCapabilities;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * Provides GNSS capabilities supported by the GNSS HAL implementation.
+ */
+public class GnssCapabilitiesProvider {
+    private static final String TAG = "GnssCapabilitiesProvider";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    // Bit masks for capabilities in {@link android.location.GnssCapabilities}.
+    private static final long GNSS_CAPABILITY_LOW_POWER_MODE =
+            1L << GnssCapabilities.LOW_POWER_MODE;
+    private static final long GNSS_CAPABILITY_SATELLITE_BLACKLIST =
+            1L << GnssCapabilities.SATELLITE_BLACKLIST;
+    private static final long GNSS_CAPABILITY_GEOFENCING = 1L << GnssCapabilities.GEOFENCING;
+    private static final long GNSS_CAPABILITY_MEASUREMENTS = 1L << GnssCapabilities.MEASUREMENTS;
+    private static final long GNSS_CAPABILITY_NAV_MESSAGES = 1L << GnssCapabilities.NAV_MESSAGES;
+    private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS =
+            1L << GnssCapabilities.MEASUREMENT_CORRECTIONS;
+    private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS =
+            1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_LOS_SATS;
+    private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH =
+            1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH;
+    private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE =
+            1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_REFLECTING_PLANE;
+
+    private static final long GNSS_CAPABILITIES_TOP_HAL =
+            GNSS_CAPABILITY_LOW_POWER_MODE | GNSS_CAPABILITY_SATELLITE_BLACKLIST
+                    | GNSS_CAPABILITY_GEOFENCING | GNSS_CAPABILITY_MEASUREMENTS
+                    | GNSS_CAPABILITY_NAV_MESSAGES;
+
+    private static final long GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS =
+            GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS
+                    | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS
+                    | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH
+                    | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE;
+
+    // Capabilities in {@link android.location.GnssCapabilities} supported by GNSS chipset.
+    @GuardedBy("this")
+    private long mGnssCapabilities;
+
+    /**
+     * Returns the capabilities supported by the GNSS chipset.
+     *
+     * <p>The capabilities are described in {@link android.location.GnssCapabilities} and
+     * their integer values correspond to the bit positions in the returned {@code long} value.
+     */
+    public long getGnssCapabilities() {
+        synchronized (this) {
+            return mGnssCapabilities;
+        }
+    }
+
+    /**
+     * Updates the general capabilities exposed through {@link android.location.GnssCapabilities}.
+     */
+    void setTopHalCapabilities(int topHalCapabilities,
+            boolean hasGeofencingCapability, boolean hasMeasurementsCapability,
+            boolean hasNavMessagesCapability) {
+        long gnssCapabilities = 0;
+        if (hasCapability(topHalCapabilities,
+                GnssLocationProvider.GPS_CAPABILITY_LOW_POWER_MODE)) {
+            gnssCapabilities |= GNSS_CAPABILITY_LOW_POWER_MODE;
+        }
+        if (hasCapability(topHalCapabilities,
+                GnssLocationProvider.GPS_CAPABILITY_SATELLITE_BLACKLIST)) {
+            gnssCapabilities |= GNSS_CAPABILITY_SATELLITE_BLACKLIST;
+        }
+        if (hasGeofencingCapability) {
+            gnssCapabilities |= GNSS_CAPABILITY_GEOFENCING;
+        }
+        if (hasMeasurementsCapability) {
+            gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENTS;
+        }
+        if (hasNavMessagesCapability) {
+            gnssCapabilities |= GNSS_CAPABILITY_NAV_MESSAGES;
+        }
+
+        synchronized (this) {
+            mGnssCapabilities &= ~GNSS_CAPABILITIES_TOP_HAL;
+            mGnssCapabilities |= gnssCapabilities;
+            if (DEBUG) {
+                Log.d(TAG, "setTopHalCapabilities, mGnssCapabilities=0x" + Long.toHexString(
+                        mGnssCapabilities) + ", " + GnssCapabilities.of(mGnssCapabilities));
+            }
+        }
+    }
+
+    /**
+     * Updates the measurement corrections related capabilities exposed through
+     * {@link android.location.GnssCapabilities}.
+     */
+    void setSubHalMeasurementCorrectionsCapabilities(int measurementCorrectionsCapabilities) {
+        long gnssCapabilities = GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS;
+        if (hasCapability(measurementCorrectionsCapabilities,
+                GnssMeasurementCorrectionsProvider.CAPABILITY_LOS_SATS)) {
+            gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS;
+        }
+        if (hasCapability(measurementCorrectionsCapabilities,
+                GnssMeasurementCorrectionsProvider.CAPABILITY_EXCESS_PATH_LENGTH)) {
+            gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH;
+        }
+        if (hasCapability(measurementCorrectionsCapabilities,
+                GnssMeasurementCorrectionsProvider.CAPABILITY_REFLECTING_PLANE)) {
+            gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE;
+        }
+
+        synchronized (this) {
+            mGnssCapabilities &= ~GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS;
+            mGnssCapabilities |= gnssCapabilities;
+            if (DEBUG) {
+                Log.d(TAG, "setSubHalMeasurementCorrectionsCapabilities, mGnssCapabilities=0x"
+                        + Long.toHexString(mGnssCapabilities) + ", " + GnssCapabilities.of(
+                        mGnssCapabilities));
+            }
+        }
+    }
+
+    private static  boolean hasCapability(int halCapabilities, int capability) {
+        return (halCapabilities & capability) != 0;
+    }
+}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 8249999..be34adb1 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -173,8 +173,8 @@
     public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
     public static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
 
-    private static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100;
-    private static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200;
+    static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100;
+    static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200;
 
     // The AGPS SUPL mode
     private static final int AGPS_SUPL_MODE_MSA = 0x02;
@@ -338,8 +338,8 @@
     // true if we started navigation
     private boolean mStarted;
 
-    // capabilities of the GPS engine
-    private volatile int mEngineCapabilities;
+    // capabilities reported through the top level IGnssCallback.hal
+    private volatile int mTopHalCapabilities;
 
     // true if XTRA is supported
     private boolean mSupportsXtra;
@@ -359,8 +359,8 @@
     // The WorkSource associated with the most recent client request (i.e, most recent call to
     // setRequest).
     private WorkSource mWorkSource = null;
-    // True if gps should be disabled (used to support battery saver mode in settings).
-    private boolean mDisableGps = false;
+    // True if gps should be disabled because of PowerManager controls
+    private boolean mDisableGpsForPowerManager = false;
 
     /**
      * Properties loaded from PROPERTIES_FILE.
@@ -385,6 +385,8 @@
     private final NtpTimeHelper mNtpTimeHelper;
     private final GnssBatchingProvider mGnssBatchingProvider;
     private final GnssGeofenceProvider mGnssGeofenceProvider;
+    private final GnssCapabilitiesProvider mGnssCapabilitiesProvider;
+
     // Available only on GNSS HAL 2.0 implementations and later.
     private GnssVisibilityControl mGnssVisibilityControl;
 
@@ -538,18 +540,19 @@
 
     private void updateLowPowerMode() {
         // Disable GPS if we are in device idle mode.
-        boolean disableGps = mPowerManager.isDeviceIdleMode();
+        boolean disableGpsForPowerManager = mPowerManager.isDeviceIdleMode();
         final PowerSaveState result =
                 mPowerManager.getPowerSaveState(ServiceType.LOCATION);
         switch (result.locationMode) {
             case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
             case PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF:
                 // If we are in battery saver mode and the screen is off, disable GPS.
-                disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive();
+                disableGpsForPowerManager |=
+                        result.batterySaverEnabled && !mPowerManager.isInteractive();
                 break;
         }
-        if (disableGps != mDisableGps) {
-            mDisableGps = disableGps;
+        if (disableGpsForPowerManager != mDisableGpsForPowerManager) {
+            mDisableGpsForPowerManager = disableGpsForPowerManager;
             updateEnabled();
             updateRequirements();
         }
@@ -592,10 +595,8 @@
         mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
         mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
 
-        mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(
-                context,
-                GnssLocationProvider.this::onNetworkAvailable,
-                looper);
+        mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
+                GnssLocationProvider.this::onNetworkAvailable, looper);
 
         // App ops service to keep track of who is accessing the GPS
         mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -613,6 +614,7 @@
         // while IO initialization and registration is delegated to our internal handler
         // this approach is just fine because events are posted to our handler anyway
         mGnssConfiguration = new GnssConfiguration(mContext);
+        mGnssCapabilitiesProvider = new GnssCapabilitiesProvider();
         // Create a GPS net-initiated handler (also needed by handleInitialize)
         mNIHandler = new GpsNetInitiatedHandler(context,
                 mNetInitiatedListener,
@@ -953,11 +955,19 @@
 
     private void updateEnabled() {
         synchronized (mLock) {
-            boolean enabled =
-                    ((mProviderRequest != null && mProviderRequest.reportLocation
-                            && mProviderRequest.locationSettingsIgnored) || (
-                            mContext.getSystemService(LocationManager.class).isLocationEnabled()
-                                    && !mDisableGps)) && !mShutdown;
+            // Generally follow location setting
+            boolean enabled = mContext.getSystemService(LocationManager.class).isLocationEnabled();
+
+            // ... but disable if PowerManager overrides
+            enabled &= !mDisableGpsForPowerManager;
+
+            // .. but enable anyway, if there's an active settings-ignored request (e.g. ELS)
+            enabled |= (mProviderRequest != null && mProviderRequest.reportLocation
+                            && mProviderRequest.locationSettingsIgnored);
+
+            // ... and, finally, disable anyway, if device is being shut down
+            enabled &= !mShutdown;
+
             if (enabled == mEnabled) {
                 return;
             }
@@ -1271,12 +1281,8 @@
         mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
     }
 
-    public int getGnssCapabilities() {
-        return mEngineCapabilities;
-    }
-
     private boolean hasCapability(int capability) {
-        return ((mEngineCapabilities & capability) != 0);
+        return (mTopHalCapabilities & capability) != 0;
     }
 
     @NativeEntryPoint
@@ -1484,27 +1490,52 @@
     }
 
     @NativeEntryPoint
-    private void setEngineCapabilities(final int capabilities, boolean hasSubHalCapabilityFlags) {
-        // send to handler thread for fast native return, and in-order handling
+    private void setTopHalCapabilities(int topHalCapabilities, boolean hasSubHalCapabilityFlags) {
+        // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum
+        // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate
+        // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the
+        // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs
+        // which explicitly set the sub-HAL capability bits must continue to work.
         mHandler.post(() -> {
-            mEngineCapabilities = capabilities;
+            mTopHalCapabilities = topHalCapabilities;
 
             if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
                 mNtpTimeHelper.enablePeriodicTimeInjection();
                 requestUtcTime();
             }
 
-            mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities, hasSubHalCapabilityFlags);
-            mGnssNavigationMessageProvider.onCapabilitiesUpdated(capabilities,
-                    hasSubHalCapabilityFlags);
+            boolean hasGeofencingCapability;
+            boolean hasMeasurementsCapability;
+            boolean hasNavMessagesCapability;
+            if (hasSubHalCapabilityFlags) {
+                hasGeofencingCapability = hasCapability(GPS_CAPABILITY_GEOFENCING);
+                hasMeasurementsCapability = hasCapability(GPS_CAPABILITY_MEASUREMENTS);
+                hasNavMessagesCapability = hasCapability(GPS_CAPABILITY_NAV_MESSAGES);
+            } else {
+                hasGeofencingCapability = mGnssGeofenceProvider.isHardwareGeofenceSupported();
+                hasMeasurementsCapability = mGnssMeasurementsProvider.isAvailableInPlatform();
+                hasNavMessagesCapability = mGnssNavigationMessageProvider.isAvailableInPlatform();
+            }
+
+            mGnssMeasurementsProvider.onCapabilitiesUpdated(hasMeasurementsCapability);
+            mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasNavMessagesCapability);
             restartRequests();
+
+            mGnssCapabilitiesProvider.setTopHalCapabilities(topHalCapabilities,
+                    hasGeofencingCapability, hasMeasurementsCapability, hasNavMessagesCapability);
         });
     }
 
     @NativeEntryPoint
-    private void setMeasurementCorrectionsCapabilities(final int capabilities) {
-        mHandler.post(() -> mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated(
-                capabilities));
+    private void setSubHalMeasurementCorrectionsCapabilities(int subHalCapabilities) {
+        mHandler.post(() -> {
+            if (!mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated(subHalCapabilities)) {
+                return;
+            }
+
+            mGnssCapabilitiesProvider.setSubHalMeasurementCorrectionsCapabilities(
+                    subHalCapabilities);
+        });
     }
 
     private void restartRequests() {
@@ -1605,6 +1636,13 @@
         return () -> mGnssMetrics.dumpGnssMetricsAsProtoString();
     }
 
+    /**
+     * @hide
+     */
+    public GnssCapabilitiesProvider getGnssCapabilitiesProvider() {
+        return mGnssCapabilitiesProvider;
+    }
+
     @NativeEntryPoint
     private void reportLocationBatch(Location[] locationArray) {
         List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
@@ -2133,8 +2171,8 @@
                 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
         s.append("  mGnssNavigationMessageProvider.isRegistered()=")
                 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
-        s.append("  mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
-        s.append("  mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
+        s.append("  mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n');
+        s.append("  mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities));
         s.append(" ( ");
         if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
         if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
diff --git a/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java
index 2162787..82528ca 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java
@@ -34,9 +34,9 @@
     private static final String TAG = "GnssMeasurementCorrectionsProvider";
 
     // These must match with the Capabilities enum in IMeasurementCorrectionsCallback.hal.
-    private static final int CAPABILITY_LOS_SATS = 0x0000001;
-    private static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002;
-    private static final int CAPABILITY_REFLECTING_PLANE = 0x0000004;
+    static final int CAPABILITY_LOS_SATS = 0x0000001;
+    static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002;
+    static final int CAPABILITY_REFLECTING_PLANE = 0x0000004;
 
     private static final int INVALID_CAPABILITIES = 1 << 31;
 
@@ -83,21 +83,23 @@
     }
 
     /** Handle measurement corrections capabilities update from the GNSS HAL implementation. */
-    void onCapabilitiesUpdated(int capabilities) {
+    boolean onCapabilitiesUpdated(int capabilities) {
         if (hasCapability(capabilities, CAPABILITY_LOS_SATS) || hasCapability(capabilities,
                 CAPABILITY_EXCESS_PATH_LENGTH)) {
             mCapabilities = capabilities;
+            return true;
         } else {
             Log.e(TAG, "Failed to set capabilities. Received capabilities 0x"
                     + Integer.toHexString(capabilities) + " does not contain the mandatory "
                     + "LOS_SATS or the EXCESS_PATH_LENGTH capability.");
+            return false;
         }
     }
 
     /**
      * Returns the measurement corrections specific capabilities of the GNSS HAL implementation.
      */
-    public int getCapabilities() {
+    int getCapabilities() {
         return mCapabilities;
     }
 
@@ -122,14 +124,14 @@
         return s.toString();
     }
 
-    private boolean isCapabilitiesReceived() {
-        return mCapabilities != INVALID_CAPABILITIES;
-    }
-
     private static  boolean hasCapability(int halCapabilities, int capability) {
         return (halCapabilities & capability) != 0;
     }
 
+    private boolean isCapabilitiesReceived() {
+        return mCapabilities != INVALID_CAPABILITIES;
+    }
+
     @VisibleForTesting
     static class GnssMeasurementCorrectionsProviderNative {
         public boolean isMeasurementCorrectionsSupported() {
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index 844735a..ec05c31 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -105,15 +105,7 @@
     }
 
     /** Handle GNSS capabilities update from the GNSS HAL implementation. */
-    public void onCapabilitiesUpdated(int capabilities, boolean hasSubHalCapabilityFlags) {
-        // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum
-        // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate
-        // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the
-        // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs
-        // which explicitly set the sub-HAL capability bits must continue to work.
-        final boolean isGnssMeasurementsSupported = hasSubHalCapabilityFlags
-                ? (capabilities & GnssLocationProvider.GPS_CAPABILITY_MEASUREMENTS) != 0
-                : mNative.isMeasurementSupported();
+    public void onCapabilitiesUpdated(boolean isGnssMeasurementsSupported) {
         setSupported(isGnssMeasurementsSupported);
         updateResult();
     }
diff --git a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
index 7e8b599..4c45ef6 100644
--- a/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GnssNavigationMessageProvider.java
@@ -92,15 +92,7 @@
     }
 
     /** Handle GNSS capabilities update from the GNSS HAL implementation */
-    public void onCapabilitiesUpdated(int capabilities, boolean hasSubHalCapabilityFlags) {
-        // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum
-        // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate
-        // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the
-        // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs
-        // which explicitly set the sub-HAL capability bits must continue to work.
-        final boolean isGnssNavigationMessageSupported = hasSubHalCapabilityFlags
-                ? (capabilities & GnssLocationProvider.GPS_CAPABILITY_NAV_MESSAGES) != 0
-                : mNative.isNavigationMessageSupported();
+    public void onCapabilitiesUpdated(boolean isGnssNavigationMessageSupported) {
         setSupported(isGnssNavigationMessageSupported);
         updateResult();
     }
diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
index c06b03b..ab75b21 100644
--- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
+++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
@@ -27,6 +27,7 @@
 import android.os.Looper;
 import android.os.PowerManager;
 import android.provider.Telephony.Carriers;
+import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.util.Log;
 
@@ -591,13 +592,25 @@
         }
         TelephonyManager phone = (TelephonyManager)
                 mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        ServiceState serviceState = phone.getServiceState();
+        String projection = null;
+        String selection = null;
+
         // Carrier configuration may override framework roaming state, we need to use the actual
         // modem roaming state instead of the framework roaming state.
-        boolean isDataRoamingFromRegistration = phone.getServiceState()
-                .getDataRoamingFromRegistration();
-        String projection = isDataRoamingFromRegistration ? Carriers.ROAMING_PROTOCOL :
-                Carriers.PROTOCOL;
-        String selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn);
+        if (serviceState != null && serviceState.getDataRoamingFromRegistration()) {
+            projection = Carriers.ROAMING_PROTOCOL;
+        } else {
+            projection = Carriers.PROTOCOL;
+        }
+        // No SIM case for emergency
+        if (TelephonyManager.NETWORK_TYPE_UNKNOWN == phone.getNetworkType()
+                && AGPS_TYPE_EIMS == mAGpsType) {
+            selection = String.format(
+                "type like '%%emergency%%' and apn = '%s' and carrier_enabled = 1", apn);
+        } else {
+            selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn);
+        }
         try (Cursor cursor = mContext.getContentResolver().query(
                 Carriers.CONTENT_URI,
                 new String[]{projection},
@@ -613,7 +626,7 @@
             Log.e(TAG, "Error encountered on APN query for: " + apn, e);
         }
 
-        return APN_INVALID;
+        return APN_IPV4V6;
     }
 
     private int translateToApnIpType(String ipProtocol, String apn) {
@@ -630,7 +643,7 @@
         // we hit the default case so the ipProtocol is not recognized
         String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn);
         Log.e(TAG, message);
-        return APN_INVALID;
+        return APN_IPV4V6;
     }
 
     // AGPS support
diff --git a/services/core/java/com/android/server/location/GnssSatelliteBlacklistHelper.java b/services/core/java/com/android/server/location/GnssSatelliteBlacklistHelper.java
index 77951aa..eb99a85 100644
--- a/services/core/java/com/android/server/location/GnssSatelliteBlacklistHelper.java
+++ b/services/core/java/com/android/server/location/GnssSatelliteBlacklistHelper.java
@@ -20,7 +20,6 @@
 class GnssSatelliteBlacklistHelper {
 
     private static final String TAG = "GnssBlacklistHelper";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final String BLACKLIST_DELIMITER = ",";
 
     private final Context mContext;
@@ -55,9 +54,7 @@
         if (blacklist == null) {
             blacklist = "";
         }
-        if (DEBUG) {
-            Log.d(TAG, String.format("Update GNSS satellite blacklist: %s", blacklist));
-        }
+        Log.i(TAG, String.format("Update GNSS satellite blacklist: %s", blacklist));
 
         List<Integer> blacklistValues;
         try {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 3e134b2..da836c2 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -94,6 +94,7 @@
 import android.service.gatekeeper.IGateKeeperService;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
@@ -141,6 +142,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -324,7 +326,7 @@
             Arrays.fill(newPasswordChars, '\u0000');
             final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
             setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD, managedUserPassword,
-                    quality, managedUserId, false);
+                    quality, managedUserId, false, /* isLockTiedToParent= */ true);
             // We store a private credential for the managed user that's unlocked by the primary
             // account holder's credential. As such, the user will never be prompted to enter this
             // password directly, so we always store a password.
@@ -1303,13 +1305,13 @@
                         setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE,
                                 profilePasswordMap.get(managedUserId),
                                 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId,
-                                false);
+                                false, /* isLockTiedToParent= */ true);
                     } else {
                         Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
                         // Supplying null here would lead to untrusted credential change
                         setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, null,
                                 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId,
-                                true);
+                                true, /* isLockTiedToParent= */ true);
                     }
                     mStorage.removeChildProfileLock(managedUserId);
                     removeKeystoreProfileKey(managedUserId);
@@ -1328,6 +1330,67 @@
                 && mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
     }
 
+    /**
+     * Send credentials for user {@code userId} to {@link RecoverableKeyStoreManager} during an
+     * unlock operation.
+     */
+    private void sendCredentialsOnUnlockIfRequired(
+            int credentialType, @NonNull byte[] credential, int userId) {
+        // Don't send credentials during the factory reset protection flow.
+        if (userId == USER_FRP) {
+            return;
+        }
+
+        // A profile with a unified lock screen stores a randomly generated credential, so skip it.
+        // Its parent will send credentials for the profile, as it stores the unified lock
+        // credential.
+        if (isManagedProfileWithUnifiedLock(userId)) {
+            return;
+        }
+
+        // Send credentials for the user and any child profiles that share its lock screen.
+        for (int profileId : getProfilesWithSameLockScreen(userId)) {
+            mRecoverableKeyStoreManager.lockScreenSecretAvailable(
+                    credentialType, credential, profileId);
+        }
+    }
+
+    /**
+     * Send credentials for user {@code userId} to {@link RecoverableKeyStoreManager} when its
+     * credentials are set/changed.
+     */
+    private void sendCredentialsOnChangeIfRequired(
+            int credentialType, byte[] credential, int userId, boolean isLockTiedToParent) {
+        // A profile whose lock screen is being tied to its parent's will either have a randomly
+        // generated credential (creation) or null (removal). We rely on the parent to send its
+        // credentials for the profile in both cases as it stores the unified lock credential.
+        if (isLockTiedToParent) {
+            return;
+        }
+
+        // Send credentials for the user and any child profiles that share its lock screen.
+        for (int profileId : getProfilesWithSameLockScreen(userId)) {
+            mRecoverableKeyStoreManager.lockScreenSecretChanged(
+                    credentialType, credential, profileId);
+        }
+    }
+
+    /**
+     * Returns all profiles of {@code userId}, including itself, that have the same lock screen
+     * challenge.
+     */
+    private Set<Integer> getProfilesWithSameLockScreen(int userId) {
+        Set<Integer> profiles = new ArraySet<>();
+        for (UserInfo profile : mUserManager.getProfiles(userId)) {
+            if (profile.id == userId
+                    || (profile.profileGroupId == userId
+                            && isManagedProfileWithUnifiedLock(profile.id))) {
+                profiles.add(profile.id);
+            }
+        }
+        return profiles;
+    }
+
     // This method should be called by LockPatternUtil only, all internal methods in this class
     // should call setLockCredentialInternal.
     @Override
@@ -1342,16 +1405,24 @@
         checkWritePermission(userId);
         synchronized (mSeparateChallengeLock) {
             setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId,
-                    allowUntrustedChange);
+                    allowUntrustedChange, /* isLockTiedToParent= */ false);
             setSeparateProfileChallengeEnabledLocked(userId, true, null);
             notifyPasswordChanged(userId);
         }
+        if (mUserManager.getUserInfo(userId).isManagedProfile()) {
+            // Make sure the profile doesn't get locked straight after setting work challenge.
+            setDeviceUnlockedForUser(userId);
+        }
         notifySeparateProfileChallengeChanged(userId);
     }
 
+    /**
+     * @param isLockTiedToParent is {@code true} if {@code userId} is a profile and its new
+     *     credentials are being tied to its parent's credentials.
+     */
     private void setLockCredentialInternal(byte[] credential, @CredentialType int credentialType,
-            byte[] savedCredential, int requestedQuality, int userId,
-            boolean allowUntrustedChange) throws RemoteException {
+            byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange,
+            boolean isLockTiedToParent) throws RemoteException {
         // Normalize savedCredential and credential such that empty string is always represented
         // as null.
         if (savedCredential == null || savedCredential.length == 0) {
@@ -1363,7 +1434,7 @@
         synchronized (mSpManager) {
             if (isSyntheticPasswordBasedCredentialLocked(userId)) {
                 spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        requestedQuality, userId, allowUntrustedChange);
+                        requestedQuality, userId, allowUntrustedChange, isLockTiedToParent);
                 return;
             }
         }
@@ -1379,7 +1450,8 @@
             fixateNewestUserKeyAuth(userId);
             synchronizeUnifiedWorkChallengeForProfiles(userId, null);
             notifyActivePasswordMetricsAvailable(CREDENTIAL_TYPE_NONE, null, userId);
-            mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId);
+            sendCredentialsOnChangeIfRequired(
+                    credentialType, credential, userId, isLockTiedToParent);
             return;
         }
         if (credential == null) {
@@ -1414,7 +1486,7 @@
                 initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
                         currentHandle.type, requestedQuality, userId);
                 spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        requestedQuality, userId, allowUntrustedChange);
+                        requestedQuality, userId, allowUntrustedChange, isLockTiedToParent);
                 return;
             }
         }
@@ -1432,8 +1504,8 @@
             // Refresh the auth token
             doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */);
             synchronizeUnifiedWorkChallengeForProfiles(userId, null);
-            mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential,
-                userId);
+            sendCredentialsOnChangeIfRequired(
+                    credentialType, credential, userId, isLockTiedToParent);
         } else {
             throw new RemoteException("Failed to enroll " +
                     (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern"));
@@ -1674,8 +1746,7 @@
         // The user employs synthetic password based credential.
         if (response != null) {
             if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
-                mRecoverableKeyStoreManager.lockScreenSecretAvailable(credentialType, credential,
-                        userId);
+                sendCredentialsOnUnlockIfRequired(credentialType, credential, userId);
             }
             return response;
         }
@@ -1709,7 +1780,8 @@
             mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
             if (shouldReEnrollBaseZero) {
                 setLockCredentialInternal(credential, storedHash.type, credentialToVerify,
-                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId, false);
+                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId, false,
+                        /* isLockTiedToParent= */ false);
             }
         }
 
@@ -1800,12 +1872,12 @@
                         storedHash.type == CREDENTIAL_TYPE_PATTERN
                                 ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
                                 : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
-                                /* TODO(roosa): keep the same password quality */, userId, false);
+                                /* TODO(roosa): keep the same password quality */,
+                        userId, false, /* isLockTiedToParent= */ false);
                 if (!hasChallenge) {
                     notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId);
                     // Use credentials to create recoverable keystore snapshot.
-                    mRecoverableKeyStoreManager.lockScreenSecretAvailable(
-                            storedHash.type, credential, userId);
+                    sendCredentialsOnUnlockIfRequired(storedHash.type, credential, userId);
                     return VerifyCredentialResponse.OK;
                 }
                 // Fall through to get the auth token. Technically this should never happen,
@@ -1835,9 +1907,7 @@
             unlockUser(userId, response.getPayload(), secretFromCredential(credential));
 
             if (isManagedProfileWithSeparatedLock(userId)) {
-                TrustManager trustManager =
-                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
-                trustManager.setDeviceLockedForUser(userId, false);
+                setDeviceUnlockedForUser(userId);
             }
             int reEnrollQuality = storedHash.type == CREDENTIAL_TYPE_PATTERN
                     ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
@@ -1845,7 +1915,7 @@
                     /* TODO(roosa): keep the same password quality */;
             if (shouldReEnroll) {
                 setLockCredentialInternal(credential, storedHash.type, credential,
-                        reEnrollQuality, userId, false);
+                        reEnrollQuality, userId, false, /* isLockTiedToParent= */ false);
             } else {
                 // Now that we've cleared of all required GK migration, let's do the final
                 // migration to synthetic password.
@@ -1859,8 +1929,7 @@
                 }
             }
             // Use credentials to create recoverable keystore snapshot.
-            mRecoverableKeyStoreManager.lockScreenSecretAvailable(storedHash.type, credential,
-                userId);
+            sendCredentialsOnUnlockIfRequired(storedHash.type, credential, userId);
 
         } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
             if (response.getTimeout() > 0) {
@@ -2465,9 +2534,7 @@
             activateEscrowTokens(authResult.authToken, userId);
 
             if (isManagedProfileWithSeparatedLock(userId)) {
-                TrustManager trustManager =
-                        (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
-                trustManager.setDeviceLockedForUser(userId, false);
+                setDeviceUnlockedForUser(userId);
             }
             mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
 
@@ -2481,6 +2548,11 @@
         return response;
     }
 
+    private void setDeviceUnlockedForUser(int userId) {
+        final TrustManager trustManager = mContext.getSystemService(TrustManager.class);
+        trustManager.setDeviceLockedForUser(userId, false);
+    }
+
     /**
      * Change the user's lockscreen password by creating a new SP blob and update the handle, based
      * on an existing authentication token. Even though a new SP blob is created, the underlying
@@ -2549,7 +2621,7 @@
     @GuardedBy("mSpManager")
     private void spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType,
             byte[] savedCredential, int requestedQuality, int userId,
-            boolean allowUntrustedChange) throws RemoteException {
+            boolean allowUntrustedChange, boolean isLockTiedToParent) throws RemoteException {
         if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
         if (isManagedProfileWithUnifiedLock(userId)) {
             // get credential from keystore when managed profile has unified lock
@@ -2615,7 +2687,7 @@
             // requestedQuality, userId) instead if we still allow untrusted reset that changes
             // synthetic password. That would invalidate existing escrow tokens though.
         }
-        mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId);
+        sendCredentialsOnChangeIfRequired(credentialType, credential, userId, isLockTiedToParent);
     }
 
     /**
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
new file mode 100644
index 0000000..d284c60
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.media.IMediaRoute2Callback;
+import android.media.IMediaRoute2Provider;
+import android.media.MediaRoute2ProviderService;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+
+/**
+ * Maintains a connection to a particular media route provider service.
+ */
+final class MediaRoute2ProviderProxy implements ServiceConnection {
+    private static final String TAG = "MediaRoute2ProviderProxy";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final Context mContext;
+    private final ComponentName mComponentName;
+    private final int mUserId;
+    private final Handler mHandler;
+
+    private Callback mCallback;
+
+    // Selected Route info
+    public int mSelectedUid;
+    public String mSelectedRouteId;
+
+    // Connection state
+    private boolean mRunning;
+    private boolean mBound;
+    private Connection mActiveConnection;
+    private boolean mConnectionReady;
+
+    MediaRoute2ProviderProxy(Context context, ComponentName componentName, int userId) {
+        mContext = context;
+        mComponentName = componentName;
+        mUserId = userId;
+        mHandler = new Handler();
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "Proxy");
+        pw.println(prefix + "  mUserId=" + mUserId);
+        pw.println(prefix + "  mRunning=" + mRunning);
+        pw.println(prefix + "  mBound=" + mBound);
+        pw.println(prefix + "  mActiveConnection=" + mActiveConnection);
+        pw.println(prefix + "  mConnectionReady=" + mConnectionReady);
+    }
+
+    public void setCallback(Callback callback) {
+        mCallback = callback;
+    }
+
+    public void setSelectedRoute(int uid, String routeId) {
+        if (mConnectionReady) {
+            mActiveConnection.selectRoute(uid, routeId);
+            updateBinding();
+        }
+    }
+
+    public boolean hasComponentName(String packageName, String className) {
+        return mComponentName.getPackageName().equals(packageName)
+                && mComponentName.getClassName().equals(className);
+    }
+
+    public String getFlattenedComponentName() {
+        return mComponentName.flattenToShortString();
+    }
+
+    public void start() {
+        if (!mRunning) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Starting");
+            }
+
+            mRunning = true;
+            updateBinding();
+        }
+    }
+
+    public void stop() {
+        if (mRunning) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Stopping");
+            }
+
+            mRunning = false;
+            updateBinding();
+        }
+    }
+
+    public void rebindIfDisconnected() {
+        if (mActiveConnection == null && shouldBind()) {
+            unbind();
+            bind();
+        }
+    }
+
+    private void updateBinding() {
+        if (shouldBind()) {
+            bind();
+        } else {
+            unbind();
+        }
+    }
+
+    private boolean shouldBind() {
+        //TODO: binding could be delayed until it's necessary.
+        if (mRunning) {
+            return true;
+        }
+        return false;
+    }
+
+    private void bind() {
+        if (!mBound) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Binding");
+            }
+
+            Intent service = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
+            service.setComponent(mComponentName);
+            try {
+                mBound = mContext.bindServiceAsUser(service, this,
+                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+                        new UserHandle(mUserId));
+                if (!mBound && DEBUG) {
+                    Slog.d(TAG, this + ": Bind failed");
+                }
+            } catch (SecurityException ex) {
+                if (DEBUG) {
+                    Slog.d(TAG, this + ": Bind failed", ex);
+                }
+            }
+        }
+    }
+
+    private void unbind() {
+        if (mBound) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Unbinding");
+            }
+
+            mBound = false;
+            disconnect();
+            mContext.unbindService(this);
+        }
+    }
+
+    @Override
+    public void onServiceConnected(ComponentName name, IBinder service) {
+        if (DEBUG) {
+            Slog.d(TAG, this + ": Connected");
+        }
+
+        if (mBound) {
+            disconnect();
+
+            IMediaRoute2Provider provider = IMediaRoute2Provider.Stub.asInterface(service);
+            if (provider != null) {
+                Connection connection = new Connection(provider);
+                if (connection.register()) {
+                    mActiveConnection = connection;
+                } else {
+                    if (DEBUG) {
+                        Slog.d(TAG, this + ": Registration failed");
+                    }
+                }
+            } else {
+                Slog.e(TAG, this + ": Service returned invalid remote display provider binder");
+            }
+        }
+    }
+
+    @Override
+    public void onServiceDisconnected(ComponentName name) {
+        if (DEBUG) {
+            Slog.d(TAG, this + ": Service disconnected");
+        }
+        disconnect();
+    }
+
+    private void onConnectionReady(Connection connection) {
+        if (mActiveConnection == connection) {
+            mConnectionReady = true;
+        }
+    }
+
+    private void onConnectionDied(Connection connection) {
+        if (mActiveConnection == connection) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Service connection died");
+            }
+            disconnect();
+        }
+    }
+
+    private void onRouteSelected(Connection connection, int uid, String routeId) {
+        mSelectedUid = uid;
+        mSelectedRouteId = routeId;
+
+        if (mActiveConnection == connection) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": State changed ");
+            }
+            mHandler.post(mStateChanged);
+        }
+    }
+
+    private void disconnect() {
+        if (mActiveConnection != null) {
+            mConnectionReady = false;
+            mActiveConnection.dispose();
+            mActiveConnection = null;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Service connection " + mComponentName.flattenToShortString();
+    }
+
+    private final Runnable mStateChanged = new Runnable() {
+        @Override
+        public void run() {
+            if (mCallback != null) {
+                mCallback.onProviderStateChanged(MediaRoute2ProviderProxy.this);
+            }
+        }
+    };
+
+    public interface Callback {
+        void onProviderStateChanged(MediaRoute2ProviderProxy provider);
+    }
+
+    private final class Connection implements DeathRecipient {
+        private final IMediaRoute2Provider mProvider;
+        private final ProviderCallback mCallback;
+
+        Connection(IMediaRoute2Provider provider) {
+            mProvider = provider;
+            mCallback = new ProviderCallback(this);
+        }
+
+        public boolean register() {
+            try {
+                mProvider.asBinder().linkToDeath(this, 0);
+                mProvider.setCallback(mCallback);
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        onConnectionReady(Connection.this);
+                    }
+                });
+                return true;
+            } catch (RemoteException ex) {
+                binderDied();
+            }
+            return false;
+        }
+
+        public void dispose() {
+            mProvider.asBinder().unlinkToDeath(this, 0);
+            mCallback.dispose();
+        }
+
+        public void selectRoute(int uid, String id) {
+            try {
+                mProvider.selectRoute(uid, id);
+            } catch (RemoteException ex) {
+                Slog.e(TAG, "Failed to deliver request to set discovery mode.", ex);
+            }
+        }
+
+        @Override
+        public void binderDied() {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    onConnectionDied(Connection.this);
+                }
+            });
+        }
+
+        void postRouteSelected(int uid, String routeId) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    onRouteSelected(Connection.this, uid, routeId);
+                }
+            });
+        }
+    }
+
+    private static final class ProviderCallback extends IMediaRoute2Callback.Stub  {
+        private final WeakReference<Connection> mConnectionRef;
+
+        ProviderCallback(Connection connection) {
+            mConnectionRef = new WeakReference<Connection>(connection);
+        }
+
+        public void dispose() {
+            mConnectionRef.clear();
+        }
+
+        @Override
+        public void onRouteSelected(int uid, String routeId) throws RemoteException {
+            Connection connection = mConnectionRef.get();
+            if (connection != null) {
+                connection.postRouteSelected(uid, routeId);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
new file mode 100644
index 0000000..08d8c58
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.media.MediaRoute2ProviderService;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ */
+final class MediaRoute2ProviderWatcher {
+    private static final String TAG = "MediaRouteProvider";  // max. 23 chars
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final Context mContext;
+    private final Callback mCallback;
+    private final Handler mHandler;
+    private final int mUserId;
+    private final PackageManager mPackageManager;
+
+    private final ArrayList<MediaRoute2ProviderProxy> mProviders = new ArrayList<>();
+    private boolean mRunning;
+
+    MediaRoute2ProviderWatcher(Context context,
+            Callback callback, Handler handler, int userId) {
+        mContext = context;
+        mCallback = callback;
+        mHandler = handler;
+        mUserId = userId;
+        mPackageManager = context.getPackageManager();
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "Watcher");
+        pw.println(prefix + "  mUserId=" + mUserId);
+        pw.println(prefix + "  mRunning=" + mRunning);
+        pw.println(prefix + "  mProviders.size()=" + mProviders.size());
+    }
+
+    public void start() {
+        if (!mRunning) {
+            mRunning = true;
+
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+            filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+            filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+            filter.addDataScheme("package");
+            mContext.registerReceiverAsUser(mScanPackagesReceiver,
+                    new UserHandle(mUserId), filter, null, mHandler);
+
+            // Scan packages.
+            // Also has the side-effect of restarting providers if needed.
+            mHandler.post(mScanPackagesRunnable);
+        }
+    }
+
+    public void stop() {
+        if (mRunning) {
+            mRunning = false;
+
+            mContext.unregisterReceiver(mScanPackagesReceiver);
+            mHandler.removeCallbacks(mScanPackagesRunnable);
+
+            // Stop all providers.
+            for (int i = mProviders.size() - 1; i >= 0; i--) {
+                mProviders.get(i).stop();
+            }
+        }
+    }
+
+    private void scanPackages() {
+        if (!mRunning) {
+            return;
+        }
+
+        // Add providers for all new services.
+        // Reorder the list so that providers left at the end will be the ones to remove.
+        int targetIndex = 0;
+        Intent intent = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
+        for (ResolveInfo resolveInfo : mPackageManager.queryIntentServicesAsUser(
+                intent, 0, mUserId)) {
+            ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+            if (serviceInfo != null) {
+                int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);
+                if (sourceIndex < 0) {
+                    MediaRoute2ProviderProxy provider =
+                            new MediaRoute2ProviderProxy(mContext,
+                            new ComponentName(serviceInfo.packageName, serviceInfo.name),
+                            mUserId);
+                    provider.start();
+                    mProviders.add(targetIndex++, provider);
+                    mCallback.addProvider(provider);
+                } else if (sourceIndex >= targetIndex) {
+                    MediaRoute2ProviderProxy provider = mProviders.get(sourceIndex);
+                    provider.start(); // restart the provider if needed
+                    provider.rebindIfDisconnected();
+                    Collections.swap(mProviders, sourceIndex, targetIndex++);
+                }
+            }
+        }
+
+        // Remove providers for missing services.
+        if (targetIndex < mProviders.size()) {
+            for (int i = mProviders.size() - 1; i >= targetIndex; i--) {
+                MediaRoute2ProviderProxy provider = mProviders.get(i);
+                mCallback.removeProvider(provider);
+                mProviders.remove(provider);
+                provider.stop();
+            }
+        }
+    }
+
+    private int findProvider(String packageName, String className) {
+        int count = mProviders.size();
+        for (int i = 0; i < count; i++) {
+            MediaRoute2ProviderProxy provider = mProviders.get(i);
+            if (provider.hasComponentName(packageName, className)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private final BroadcastReceiver mScanPackagesReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) {
+                Slog.d(TAG, "Received package manager broadcast: " + intent);
+            }
+            scanPackages();
+        }
+    };
+
+    private final Runnable mScanPackagesRunnable = new Runnable() {
+        @Override
+        public void run() {
+            scanPackages();
+        }
+    };
+
+    public interface Callback {
+        void addProvider(MediaRoute2ProviderProxy provider);
+        void removeProvider(MediaRoute2ProviderProxy provider);
+    }
+}
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 3eb7321..f822e82 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -16,14 +16,10 @@
 
 package com.android.server.media;
 
-import com.android.internal.util.DumpUtils;
-import com.android.server.Watchdog;
-
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -34,6 +30,7 @@
 import android.media.AudioSystem;
 import android.media.IAudioRoutesObserver;
 import android.media.IAudioService;
+import android.media.IMediaRouter2ManagerClient;
 import android.media.IMediaRouterClient;
 import android.media.IMediaRouterService;
 import android.media.MediaRouter;
@@ -53,10 +50,14 @@
 import android.util.ArrayMap;
 import android.util.IntArray;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
 
+import com.android.internal.util.DumpUtils;
+import com.android.server.Watchdog;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -97,6 +98,7 @@
     private final Object mLock = new Object();
     private final SparseArray<UserRecord> mUserRecords = new SparseArray<>();
     private final ArrayMap<IBinder, ClientRecord> mAllClientRecords = new ArrayMap<>();
+    private final ArrayMap<IBinder, ManagerRecord> mAllManagerRecords = new ArrayMap<>();
     private int mCurrentUserId = -1;
     private final IAudioService mAudioService;
     private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
@@ -306,6 +308,22 @@
 
     // Binder call
     @Override
+    public void setControlCategories(IMediaRouterClient client, List<String> categories) {
+        if (client == null) {
+            throw new IllegalArgumentException("client must not be null");
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                setControlCategoriesLocked(client, categories);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // Binder call
+    @Override
     public void setDiscoveryRequest(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         if (client == null) {
@@ -404,6 +422,65 @@
         }
     }
 
+    // Binder call
+    @Override
+    public void registerManagerAsUser(IMediaRouter2ManagerClient client,
+            String packageName, int userId) {
+        if (client == null) {
+            throw new IllegalArgumentException("client must not be null");
+        }
+        //TODO: should check permission
+        final boolean trusted = true;
+
+        final int uid = Binder.getCallingUid();
+        if (!validatePackageName(uid, packageName)) {
+            throw new SecurityException("packageName must match the calling uid");
+        }
+
+        final int pid = Binder.getCallingPid();
+        final int resolvedUserId = ActivityManager.handleIncomingUser(pid, uid, userId,
+                false /*allowAll*/, true /*requireFull*/, "registerManagerAsUser", packageName);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                registerManagerLocked(client, uid, pid, packageName, resolvedUserId, trusted);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // Binder call
+    @Override
+    public void unregisterManager(IMediaRouter2ManagerClient client) {
+        if (client == null) {
+            throw new IllegalArgumentException("client must not be null");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                unregisterManagerLocked(client, false);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // Binder call
+    @Override
+    public void setRemoteRoute(IMediaRouter2ManagerClient client,
+            int uid, String routeId, boolean explicit) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                setRemoteRouteLocked(client, uid, routeId, explicit);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     void restoreBluetoothA2dp() {
         try {
             boolean a2dpOn;
@@ -475,6 +552,12 @@
         }
     }
 
+    void clientDied(ManagerRecord managerRecord) {
+        synchronized (mLock) {
+            unregisterManagerLocked(managerRecord.mClient, true);
+        }
+    }
+
     private void registerClientLocked(IMediaRouterClient client,
             int uid, int pid, String packageName, int userId, boolean trusted) {
         final IBinder binder = client.asBinder();
@@ -522,6 +605,17 @@
         return null;
     }
 
+    private void setControlCategoriesLocked(IMediaRouterClient client, List<String> categories) {
+        final IBinder binder = client.asBinder();
+        ClientRecord clientRecord = mAllClientRecords.get(binder);
+
+        if (clientRecord != null) {
+            clientRecord.mControlCategories = categories;
+            clientRecord.mUserRecord.mHandler.obtainMessage(
+                    UserHandler.MSG_UPDATE_CLIENT_USAGE, clientRecord).sendToTarget();
+        }
+    }
+
     private void setDiscoveryRequestLocked(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         final IBinder binder = client.asBinder();
@@ -575,6 +669,63 @@
         }
     }
 
+    private void registerManagerLocked(IMediaRouter2ManagerClient client,
+            int uid, int pid, String packageName, int userId, boolean trusted) {
+        final IBinder binder = client.asBinder();
+        ManagerRecord managerRecord = mAllManagerRecords.get(binder);
+        if (managerRecord == null) {
+            boolean newUser = false;
+            UserRecord userRecord = mUserRecords.get(userId);
+            if (userRecord == null) {
+                userRecord = new UserRecord(userId);
+                newUser = true;
+            }
+            managerRecord = new ManagerRecord(userRecord, client, uid, pid, packageName, trusted);
+            try {
+                binder.linkToDeath(managerRecord, 0);
+            } catch (RemoteException ex) {
+                throw new RuntimeException("Media router client died prematurely.", ex);
+            }
+
+            if (newUser) {
+                mUserRecords.put(userId, userRecord);
+                initializeUserLocked(userRecord);
+            }
+
+            userRecord.mManagerRecords.add(managerRecord);
+            mAllManagerRecords.put(binder, managerRecord);
+
+            // send client usage to manager
+            final int clientCount = userRecord.mClientRecords.size();
+            for (int i = 0; i < clientCount; i++) {
+                userRecord.mHandler.obtainMessage(UserHandler.MSG_UPDATE_CLIENT_USAGE,
+                        userRecord.mClientRecords.get(i)).sendToTarget();
+            }
+        }
+    }
+
+    private void unregisterManagerLocked(IMediaRouter2ManagerClient client, boolean died) {
+        ManagerRecord clientRecord = mAllManagerRecords.remove(client.asBinder());
+        if (clientRecord != null) {
+            UserRecord userRecord = clientRecord.mUserRecord;
+            userRecord.mManagerRecords.remove(clientRecord);
+            clientRecord.dispose();
+            disposeUserIfNeededLocked(userRecord); // since client removed from user
+        }
+    }
+
+    private void setRemoteRouteLocked(IMediaRouter2ManagerClient client,
+            int uid, String routeId, boolean explicit) {
+        ManagerRecord managerRecord = mAllManagerRecords.get(client.asBinder());
+        if (managerRecord != null) {
+            if (explicit && managerRecord.mTrusted) {
+                Pair<Integer, String> obj = new Pair<>(uid, routeId);
+                managerRecord.mUserRecord.mHandler.obtainMessage(
+                        UserHandler.MSG_SELECT_REMOTE_ROUTE, obj).sendToTarget();
+            }
+        }
+    }
+
     private void requestSetVolumeLocked(IMediaRouterClient client,
             String routeId, int volume) {
         final IBinder binder = client.asBinder();
@@ -667,6 +818,46 @@
         }
     }
 
+    final class ManagerRecord implements DeathRecipient {
+        public final UserRecord mUserRecord;
+        public final IMediaRouter2ManagerClient mClient;
+        public final int mUid;
+        public final int mPid;
+        public final String mPackageName;
+        public final boolean mTrusted;
+
+        ManagerRecord(UserRecord userRecord, IMediaRouter2ManagerClient client,
+                int uid, int pid, String packageName, boolean trusted) {
+            mUserRecord = userRecord;
+            mClient = client;
+            mUid = uid;
+            mPid = pid;
+            mPackageName = packageName;
+            mTrusted = trusted;
+        }
+
+        public void dispose() {
+            mClient.asBinder().unlinkToDeath(this, 0);
+        }
+
+        @Override
+        public void binderDied() {
+            clientDied(this);
+        }
+
+        public void dump(PrintWriter pw, String prefix) {
+            pw.println(prefix + this);
+
+            final String indent = prefix + "  ";
+            pw.println(indent + "mTrusted=" + mTrusted);
+        }
+
+        @Override
+        public String toString() {
+            return "Client " + mPackageName + " (pid " + mPid + ")";
+        }
+    }
+
     /**
      * Information about a particular client of the media router.
      * The contents of this object is guarded by mLock.
@@ -678,6 +869,7 @@
         public final int mPid;
         public final String mPackageName;
         public final boolean mTrusted;
+        public List<String> mControlCategories;
 
         public int mRouteTypes;
         public boolean mActiveScan;
@@ -728,7 +920,8 @@
      */
     final class UserRecord {
         public final int mUserId;
-        public final ArrayList<ClientRecord> mClientRecords = new ArrayList<ClientRecord>();
+        public final ArrayList<ClientRecord> mClientRecords = new ArrayList<>();
+        public final ArrayList<ManagerRecord> mManagerRecords = new ArrayList<>();
         public final UserHandler mHandler;
         public MediaRouterClientState mRouterState;
 
@@ -783,7 +976,9 @@
      */
     static final class UserHandler extends Handler
             implements RemoteDisplayProviderWatcher.Callback,
-            RemoteDisplayProviderProxy.Callback {
+            RemoteDisplayProviderProxy.Callback,
+            MediaRoute2ProviderWatcher.Callback,
+            MediaRoute2ProviderProxy.Callback {
         public static final int MSG_START = 1;
         public static final int MSG_STOP = 2;
         public static final int MSG_UPDATE_DISCOVERY_REQUEST = 3;
@@ -794,6 +989,9 @@
         private static final int MSG_UPDATE_CLIENT_STATE = 8;
         private static final int MSG_CONNECTION_TIMED_OUT = 9;
 
+        private static final int MSG_SELECT_REMOTE_ROUTE = 10;
+        private static final int MSG_UPDATE_CLIENT_USAGE = 11;
+
         private static final int TIMEOUT_REASON_NOT_AVAILABLE = 1;
         private static final int TIMEOUT_REASON_CONNECTION_LOST = 2;
         private static final int TIMEOUT_REASON_WAITING_FOR_CONNECTING = 3;
@@ -809,11 +1007,17 @@
         private final MediaRouterService mService;
         private final UserRecord mUserRecord;
         private final RemoteDisplayProviderWatcher mWatcher;
+        private final MediaRoute2ProviderWatcher mMediaWatcher;
+
         private final ArrayList<ProviderRecord> mProviderRecords =
                 new ArrayList<ProviderRecord>();
         private final ArrayList<IMediaRouterClient> mTempClients =
                 new ArrayList<IMediaRouterClient>();
 
+        private final ArrayList<MediaRoute2ProviderProxy> mMediaProviders =
+                new ArrayList<>();
+        private final ArrayList<IMediaRouter2ManagerClient> mTempManagers = new ArrayList<>();
+
         private boolean mRunning;
         private int mDiscoveryMode = RemoteDisplayState.DISCOVERY_MODE_NONE;
         private RouteRecord mSelectedRouteRecord;
@@ -828,6 +1032,8 @@
             mUserRecord = userRecord;
             mWatcher = new RemoteDisplayProviderWatcher(service.mContext, this,
                     this, mUserRecord.mUserId);
+            mMediaWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
+                    this, mUserRecord.mUserId);
         }
 
         @Override
@@ -869,6 +1075,15 @@
                     connectionTimedOut();
                     break;
                 }
+                case MSG_SELECT_REMOTE_ROUTE: {
+                    Pair<Integer, String> obj = (Pair<Integer, String>) msg.obj;
+                    selectRemoteRoute(obj.first, obj.second);
+                    break;
+                }
+                case MSG_UPDATE_CLIENT_USAGE: {
+                    updateClientUsage((ClientRecord) msg.obj);
+                    break;
+                }
             }
         }
 
@@ -900,6 +1115,7 @@
             if (!mRunning) {
                 mRunning = true;
                 mWatcher.start(); // also starts all providers
+                mMediaWatcher.start();
             }
         }
 
@@ -908,6 +1124,7 @@
                 mRunning = false;
                 unselectSelectedRoute();
                 mWatcher.stop(); // also stops all providers
+                mMediaWatcher.stop();
             }
         }
 
@@ -1039,6 +1256,26 @@
             }
         }
 
+        @Override
+        public void addProvider(MediaRoute2ProviderProxy provider) {
+            provider.setCallback(this);
+            mMediaProviders.add(provider);
+        }
+
+        @Override
+        public void removeProvider(MediaRoute2ProviderProxy provider) {
+            mMediaProviders.remove(provider);
+        }
+
+        @Override
+        public void onProviderStateChanged(MediaRoute2ProviderProxy provider) {
+            updateProvider(provider);
+        }
+
+        private void updateProvider(MediaRoute2ProviderProxy provider) {
+            scheduleUpdateClientState();
+        }
+
         /**
          * This function is called whenever the state of the selected route may have changed.
          * It checks the state and updates timeouts or unselects the route as appropriate.
@@ -1149,6 +1386,17 @@
             unselectSelectedRoute();
         }
 
+        private void selectRemoteRoute(int uid, String routeId) {
+            if (routeId != null) {
+                final int providerCount = mMediaProviders.size();
+
+                //TODO: should find proper provider (currently assumes a single provider)
+                for (int i = 0; i < providerCount; ++i) {
+                    mMediaProviders.get(i).setSelectedRoute(uid, routeId);
+                }
+            }
+        }
+
         private void scheduleUpdateClientState() {
             if (!mClientStateUpdateScheduled) {
                 mClientStateUpdateScheduled = true;
@@ -1166,6 +1414,15 @@
                 mProviderRecords.get(i).appendClientState(routerState);
             }
 
+            //TODO: send provider info
+            int selectedUid = 0;
+            String selectedRouteId = null;
+            final int mediaCount = mMediaProviders.size();
+            for (int i = 0; i < mediaCount; i++) {
+                selectedUid = mMediaProviders.get(i).mSelectedUid;
+                selectedRouteId = mMediaProviders.get(i).mSelectedRouteId;
+            }
+
             try {
                 synchronized (mService.mLock) {
                     // Update the UserRecord.
@@ -1176,6 +1433,11 @@
                     for (int i = 0; i < count; i++) {
                         mTempClients.add(mUserRecord.mClientRecords.get(i).mClient);
                     }
+
+                    final int count2 = mUserRecord.mManagerRecords.size();
+                    for (int i = 0; i < count2; i++) {
+                        mTempManagers.add(mUserRecord.mManagerRecords.get(i).mClient);
+                    }
                 }
 
                 // Notify all clients (outside of the lock).
@@ -1187,9 +1449,39 @@
                         Slog.w(TAG, "Failed to call onStateChanged. Client probably died.");
                     }
                 }
+                //TODO: Call proper callbacks when provider descriptor is implemented.
+                final int count2 = mTempManagers.size();
+                for (int i = 0; i < count2; i++) {
+                    try {
+                        mTempManagers.get(i).onRouteSelected(selectedUid, selectedRouteId);
+                    } catch (RemoteException ex) {
+                        Slog.w(TAG, "Failed to call onStateChanged. Manager probably died.", ex);
+                    }
+                }
             } finally {
                 // Clear the list in preparation for the next time.
                 mTempClients.clear();
+                mTempManagers.clear();
+            }
+        }
+
+        private void updateClientUsage(ClientRecord clientRecord) {
+            List<IMediaRouter2ManagerClient> managers = new ArrayList<>();
+            synchronized (mService.mLock) {
+                final int count = mUserRecord.mManagerRecords.size();
+                for (int i = 0; i < count; i++) {
+                    managers.add(mUserRecord.mManagerRecords.get(i).mClient);
+                }
+            }
+            final int count = managers.size();
+            for (int i = 0; i < count; i++) {
+                try {
+                    managers.get(i).onControlCategoriesChanged(clientRecord.mUid,
+                            clientRecord.mControlCategories);
+                } catch (RemoteException ex) {
+                    Slog.w(TAG, "Failed to call onControlCategoriesChanged. "
+                            + "Manager probably died.", ex);
+                }
             }
         }
 
@@ -1576,4 +1868,5 @@
             }
         }
     }
+
 }
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index e0fb9e7..a8c16c7 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -27,10 +27,10 @@
 import android.media.MediaParceledListSlice;
 import android.media.Rating;
 import android.media.VolumeProvider;
-import android.media.session.ControllerCallbackLink;
 import android.media.session.ISession;
 import android.media.session.ISessionCallback;
 import android.media.session.ISessionController;
+import android.media.session.ISessionControllerCallback;
 import android.media.session.MediaController;
 import android.media.session.MediaController.PlaybackInfo;
 import android.media.session.MediaSession;
@@ -88,7 +88,7 @@
     private final Context mContext;
 
     private final Object mLock = new Object();
-    private final ArrayList<ControllerCallbackLinkHolder> mControllerCallbackHolders =
+    private final ArrayList<ISessionControllerCallbackHolder> mControllerCallbackHolders =
             new ArrayList<>();
 
     private long mFlags;
@@ -265,7 +265,7 @@
      * @param useSuggested True to use adjustSuggestedStreamVolume instead of
      */
     public void adjustVolume(String packageName, String opPackageName, int pid, int uid,
-            ControllerCallbackLink caller, boolean asSystemService, int direction, int flags,
+            ISessionControllerCallback caller, boolean asSystemService, int direction, int flags,
             boolean useSuggested) {
         int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND;
         if (isPlaybackActive() || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
@@ -311,7 +311,7 @@
     }
 
     private void setVolumeTo(String packageName, String opPackageName, int pid, int uid,
-            ControllerCallbackLink caller, int value, int flags) {
+            ISessionControllerCallback caller, int value, int flags) {
         if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
             int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
             final int volumeValue = value;
@@ -558,7 +558,7 @@
     }
 
     private void logCallbackException(
-            String msg, ControllerCallbackLinkHolder holder, Exception e) {
+            String msg, ISessionControllerCallbackHolder holder, Exception e) {
         Log.v(TAG, msg + ", this=" + this + ", callback package=" + holder.mPackageName
                 + ", exception=" + e);
     }
@@ -569,18 +569,16 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyPlaybackStateChanged(mPlaybackState);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushPlaybackStateUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushPlaybackStateUpdate",
-                                holder, e);
-                    }
+                    holder.mCallback.onPlaybackStateChanged(mPlaybackState);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushPlaybackStateUpdate",
+                            holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushPlaybackStateUpdate",
+                            holder, e);
                 }
             }
         }
@@ -592,18 +590,14 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyMetadataChanged(mMetadata);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushMetadataUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushMetadataUpdate",
-                                holder, e);
-                    }
+                    holder.mCallback.onMetadataChanged(mMetadata);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushMetadataUpdate", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushMetadataUpdate", holder, e);
                 }
             }
         }
@@ -615,17 +609,15 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyQueueChanged(mQueue);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushQueueUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushQueueUpdate", holder, e);
-                    }
+                    holder.mCallback.onQueueChanged(mQueue == null ? null :
+                            new MediaParceledListSlice<>(mQueue));
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushQueueUpdate", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushQueueUpdate", holder, e);
                 }
             }
         }
@@ -637,18 +629,15 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyQueueTitleChanged(mQueueTitle);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushQueueTitleUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushQueueTitleUpdate",
-                                holder, e);
-                    }
+                    holder.mCallback.onQueueTitleChanged(mQueueTitle);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushQueueTitleUpdate",
+                            holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushQueueTitleUpdate", holder, e);
                 }
             }
         }
@@ -660,17 +649,14 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyExtrasChanged(mExtras);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushExtrasUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushExtrasUpdate", holder, e);
-                    }
+                    holder.mCallback.onExtrasChanged(mExtras);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushExtrasUpdate", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushExtrasUpdate", holder, e);
                 }
             }
         }
@@ -683,17 +669,14 @@
             }
             PlaybackInfo info = getVolumeAttributes();
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyVolumeInfoChanged(info);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushVolumeUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushVolumeUpdate", holder, e);
-                    }
+                    holder.mCallback.onVolumeInfoChanged(info);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushVolumeUpdate", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushVolumeUpdate", holder, e);
                 }
             }
         }
@@ -705,16 +688,14 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyEvent(event, data);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushEvent", holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushEvent", holder, e);
-                    }
+                    holder.mCallback.onEvent(event, data);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushEvent", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushEvent", holder, e);
                 }
             }
         }
@@ -728,18 +709,15 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifySessionDestroyed();
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushSessionDestroyed",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushSessionDestroyed",
-                                holder, e);
-                    }
+                    holder.mCallback.onSessionDestroyed();
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushSessionDestroyed",
+                            holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushSessionDestroyed", holder, e);
                 }
             }
             // After notifying clear all listeners
@@ -779,10 +757,10 @@
         return result == null ? state : result;
     }
 
-    private int getControllerHolderIndexForCb(ControllerCallbackLink cb) {
-        IBinder binder = cb.getBinder();
+    private int getControllerHolderIndexForCb(ISessionControllerCallback cb) {
+        IBinder binder = cb.asBinder();
         for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-            if (binder.equals(mControllerCallbackHolders.get(i).mCallback.getBinder())) {
+            if (binder.equals(mControllerCallbackHolders.get(i).mCallback.asBinder())) {
                 return i;
             }
         }
@@ -1027,7 +1005,7 @@
         }
 
         public boolean sendMediaButton(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, boolean asSystemService,
+                ISessionControllerCallback caller, boolean asSystemService,
                 KeyEvent keyEvent) {
             try {
                 if (asSystemService) {
@@ -1045,7 +1023,7 @@
         }
 
         public void sendCommand(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
+                ISessionControllerCallback caller, String command, Bundle args, ResultReceiver cb) {
             try {
                 mCb.onCommand(packageName, pid, uid, caller, command, args, cb);
             } catch (RemoteException e) {
@@ -1054,7 +1032,7 @@
         }
 
         public void sendCustomAction(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String action,
+                ISessionControllerCallback caller, String action,
                 Bundle args) {
             try {
                 mCb.onCustomAction(packageName, pid, uid, caller, action, args);
@@ -1064,7 +1042,7 @@
         }
 
         public void prepare(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             try {
                 mCb.onPrepare(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1073,7 +1051,7 @@
         }
 
         public void prepareFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId, Bundle extras) {
+                ISessionControllerCallback caller, String mediaId, Bundle extras) {
             try {
                 mCb.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras);
             } catch (RemoteException e) {
@@ -1082,7 +1060,7 @@
         }
 
         public void prepareFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query, Bundle extras) {
+                ISessionControllerCallback caller, String query, Bundle extras) {
             try {
                 mCb.onPrepareFromSearch(packageName, pid, uid, caller, query, extras);
             } catch (RemoteException e) {
@@ -1091,7 +1069,7 @@
         }
 
         public void prepareFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+                ISessionControllerCallback caller, Uri uri, Bundle extras) {
             try {
                 mCb.onPrepareFromUri(packageName, pid, uid, caller, uri, extras);
             } catch (RemoteException e) {
@@ -1099,7 +1077,7 @@
             }
         }
 
-        public void play(String packageName, int pid, int uid, ControllerCallbackLink caller) {
+        public void play(String packageName, int pid, int uid, ISessionControllerCallback caller) {
             try {
                 mCb.onPlay(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1108,7 +1086,7 @@
         }
 
         public void playFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId, Bundle extras) {
+                ISessionControllerCallback caller, String mediaId, Bundle extras) {
             try {
                 mCb.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras);
             } catch (RemoteException e) {
@@ -1117,7 +1095,7 @@
         }
 
         public void playFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query, Bundle extras) {
+                ISessionControllerCallback caller, String query, Bundle extras) {
             try {
                 mCb.onPlayFromSearch(packageName, pid, uid, caller, query, extras);
             } catch (RemoteException e) {
@@ -1126,7 +1104,7 @@
         }
 
         public void playFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+                ISessionControllerCallback caller, Uri uri, Bundle extras) {
             try {
                 mCb.onPlayFromUri(packageName, pid, uid, caller, uri, extras);
             } catch (RemoteException e) {
@@ -1135,7 +1113,7 @@
         }
 
         public void skipToTrack(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, long id) {
+                ISessionControllerCallback caller, long id) {
             try {
                 mCb.onSkipToTrack(packageName, pid, uid, caller, id);
             } catch (RemoteException e) {
@@ -1143,7 +1121,7 @@
             }
         }
 
-        public void pause(String packageName, int pid, int uid, ControllerCallbackLink caller) {
+        public void pause(String packageName, int pid, int uid, ISessionControllerCallback caller) {
             try {
                 mCb.onPause(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1151,7 +1129,7 @@
             }
         }
 
-        public void stop(String packageName, int pid, int uid, ControllerCallbackLink caller) {
+        public void stop(String packageName, int pid, int uid, ISessionControllerCallback caller) {
             try {
                 mCb.onStop(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1159,7 +1137,7 @@
             }
         }
 
-        public void next(String packageName, int pid, int uid, ControllerCallbackLink caller) {
+        public void next(String packageName, int pid, int uid, ISessionControllerCallback caller) {
             try {
                 mCb.onNext(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1168,7 +1146,7 @@
         }
 
         public void previous(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             try {
                 mCb.onPrevious(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1177,7 +1155,7 @@
         }
 
         public void fastForward(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             try {
                 mCb.onFastForward(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1186,7 +1164,7 @@
         }
 
         public void rewind(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             try {
                 mCb.onRewind(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1194,7 +1172,7 @@
             }
         }
 
-        public void seekTo(String packageName, int pid, int uid, ControllerCallbackLink caller,
+        public void seekTo(String packageName, int pid, int uid, ISessionControllerCallback caller,
                 long pos) {
             try {
                 mCb.onSeekTo(packageName, pid, uid, caller, pos);
@@ -1203,7 +1181,7 @@
             }
         }
 
-        public void rate(String packageName, int pid, int uid, ControllerCallbackLink caller,
+        public void rate(String packageName, int pid, int uid, ISessionControllerCallback caller,
                 Rating rating) {
             try {
                 mCb.onRate(packageName, pid, uid, caller, rating);
@@ -1213,7 +1191,7 @@
         }
 
         public void setPlaybackSpeed(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, float speed) {
+                ISessionControllerCallback caller, float speed) {
             try {
                 mCb.onSetPlaybackSpeed(packageName, pid, uid, caller, speed);
             } catch (RemoteException e) {
@@ -1222,7 +1200,7 @@
         }
 
         public void adjustVolume(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, boolean asSystemService, int direction) {
+                ISessionControllerCallback caller, boolean asSystemService, int direction) {
             try {
                 if (asSystemService) {
                     mCb.onAdjustVolume(mContext.getPackageName(), Process.myPid(),
@@ -1236,7 +1214,7 @@
         }
 
         public void setVolumeTo(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, int value) {
+                ISessionControllerCallback caller, int value) {
             try {
                 mCb.onSetVolumeTo(packageName, pid, uid, caller, value);
             } catch (RemoteException e) {
@@ -1253,34 +1231,34 @@
 
     class ControllerStub extends ISessionController.Stub {
         @Override
-        public void sendCommand(String packageName, ControllerCallbackLink caller,
+        public void sendCommand(String packageName, ISessionControllerCallback caller,
                 String command, Bundle args, ResultReceiver cb) {
             mSessionCb.sendCommand(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, command, args, cb);
         }
 
         @Override
-        public boolean sendMediaButton(String packageName, ControllerCallbackLink cb,
+        public boolean sendMediaButton(String packageName, ISessionControllerCallback cb,
                 KeyEvent keyEvent) {
             return mSessionCb.sendMediaButton(packageName, Binder.getCallingPid(),
                     Binder.getCallingUid(), cb, false, keyEvent);
         }
 
         @Override
-        public void registerCallback(String packageName, ControllerCallbackLink cb) {
+        public void registerCallback(String packageName, ISessionControllerCallback cb) {
             synchronized (mLock) {
                 // If this session is already destroyed tell the caller and
                 // don't add them.
                 if (mDestroyed) {
                     try {
-                        cb.notifySessionDestroyed();
+                        cb.onSessionDestroyed();
                     } catch (Exception e) {
                         // ignored
                     }
                     return;
                 }
                 if (getControllerHolderIndexForCb(cb) < 0) {
-                    mControllerCallbackHolders.add(new ControllerCallbackLinkHolder(cb,
+                    mControllerCallbackHolders.add(new ISessionControllerCallbackHolder(cb,
                             packageName, Binder.getCallingUid()));
                     if (DEBUG) {
                         Log.d(TAG, "registering controller callback " + cb + " from controller"
@@ -1291,14 +1269,14 @@
         }
 
         @Override
-        public void unregisterCallback(ControllerCallbackLink cb) {
+        public void unregisterCallback(ISessionControllerCallback cb) {
             synchronized (mLock) {
                 int index = getControllerHolderIndexForCb(cb);
                 if (index != -1) {
                     mControllerCallbackHolders.remove(index);
                 }
                 if (DEBUG) {
-                    Log.d(TAG, "unregistering callback " + cb.getBinder());
+                    Log.d(TAG, "unregistering callback " + cb.asBinder());
                 }
             }
         }
@@ -1335,7 +1313,7 @@
 
         @Override
         public void adjustVolume(String packageName, String opPackageName,
-                ControllerCallbackLink caller, int direction, int flags) {
+                ISessionControllerCallback caller, int direction, int flags) {
             int pid = Binder.getCallingPid();
             int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
@@ -1349,7 +1327,7 @@
 
         @Override
         public void setVolumeTo(String packageName, String opPackageName,
-                ControllerCallbackLink caller, int value, int flags) {
+                ISessionControllerCallback caller, int value, int flags) {
             int pid = Binder.getCallingPid();
             int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
@@ -1362,117 +1340,117 @@
         }
 
         @Override
-        public void prepare(String packageName, ControllerCallbackLink caller) {
+        public void prepare(String packageName, ISessionControllerCallback caller) {
             mSessionCb.prepare(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void prepareFromMediaId(String packageName, ControllerCallbackLink caller,
+        public void prepareFromMediaId(String packageName, ISessionControllerCallback caller,
                 String mediaId, Bundle extras) {
             mSessionCb.prepareFromMediaId(packageName, Binder.getCallingPid(),
                     Binder.getCallingUid(), caller, mediaId, extras);
         }
 
         @Override
-        public void prepareFromSearch(String packageName, ControllerCallbackLink caller,
+        public void prepareFromSearch(String packageName, ISessionControllerCallback caller,
                 String query, Bundle extras) {
             mSessionCb.prepareFromSearch(packageName, Binder.getCallingPid(),
                     Binder.getCallingUid(), caller, query, extras);
         }
 
         @Override
-        public void prepareFromUri(String packageName, ControllerCallbackLink caller,
+        public void prepareFromUri(String packageName, ISessionControllerCallback caller,
                 Uri uri, Bundle extras) {
             mSessionCb.prepareFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, uri, extras);
         }
 
         @Override
-        public void play(String packageName, ControllerCallbackLink caller) {
+        public void play(String packageName, ISessionControllerCallback caller) {
             mSessionCb.play(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void playFromMediaId(String packageName, ControllerCallbackLink caller,
+        public void playFromMediaId(String packageName, ISessionControllerCallback caller,
                 String mediaId, Bundle extras) {
             mSessionCb.playFromMediaId(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, mediaId, extras);
         }
 
         @Override
-        public void playFromSearch(String packageName, ControllerCallbackLink caller,
+        public void playFromSearch(String packageName, ISessionControllerCallback caller,
                 String query, Bundle extras) {
             mSessionCb.playFromSearch(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, query, extras);
         }
 
         @Override
-        public void playFromUri(String packageName, ControllerCallbackLink caller,
+        public void playFromUri(String packageName, ISessionControllerCallback caller,
                 Uri uri, Bundle extras) {
             mSessionCb.playFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, uri, extras);
         }
 
         @Override
-        public void skipToQueueItem(String packageName, ControllerCallbackLink caller,
+        public void skipToQueueItem(String packageName, ISessionControllerCallback caller,
                 long id) {
             mSessionCb.skipToTrack(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, id);
         }
 
         @Override
-        public void pause(String packageName, ControllerCallbackLink caller) {
+        public void pause(String packageName, ISessionControllerCallback caller) {
             mSessionCb.pause(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void stop(String packageName, ControllerCallbackLink caller) {
+        public void stop(String packageName, ISessionControllerCallback caller) {
             mSessionCb.stop(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void next(String packageName, ControllerCallbackLink caller) {
+        public void next(String packageName, ISessionControllerCallback caller) {
             mSessionCb.next(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void previous(String packageName, ControllerCallbackLink caller) {
+        public void previous(String packageName, ISessionControllerCallback caller) {
             mSessionCb.previous(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller);
         }
 
         @Override
-        public void fastForward(String packageName, ControllerCallbackLink caller) {
+        public void fastForward(String packageName, ISessionControllerCallback caller) {
             mSessionCb.fastForward(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller);
         }
 
         @Override
-        public void rewind(String packageName, ControllerCallbackLink caller) {
+        public void rewind(String packageName, ISessionControllerCallback caller) {
             mSessionCb.rewind(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void seekTo(String packageName, ControllerCallbackLink caller, long pos) {
+        public void seekTo(String packageName, ISessionControllerCallback caller, long pos) {
             mSessionCb.seekTo(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller,
                     pos);
         }
 
         @Override
-        public void rate(String packageName, ControllerCallbackLink caller, Rating rating) {
+        public void rate(String packageName, ISessionControllerCallback caller, Rating rating) {
             mSessionCb.rate(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller,
                     rating);
         }
 
         @Override
-        public void setPlaybackSpeed(String packageName, ControllerCallbackLink caller,
+        public void setPlaybackSpeed(String packageName, ISessionControllerCallback caller,
                 float speed) {
             mSessionCb.setPlaybackSpeed(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, speed);
         }
 
         @Override
-        public void sendCustomAction(String packageName, ControllerCallbackLink caller,
+        public void sendCustomAction(String packageName, ISessionControllerCallback caller,
                 String action, Bundle args) {
             mSessionCb.sendCustomAction(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, action, args);
@@ -1515,12 +1493,12 @@
         }
     }
 
-    private class ControllerCallbackLinkHolder {
-        private final ControllerCallbackLink mCallback;
+    private class ISessionControllerCallbackHolder {
+        private final ISessionControllerCallback mCallback;
         private final String mPackageName;
         private final int mUid;
 
-        ControllerCallbackLinkHolder(ControllerCallbackLink callback, String packageName,
+        ISessionControllerCallbackHolder(ISessionControllerCallback callback, String packageName,
                 int uid) {
             mCallback = callback;
             mPackageName = packageName;
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 1f1ba20..5d667b6 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -35,7 +35,6 @@
 import android.media.projection.MediaProjectionManager;
 import android.os.Binder;
 import android.os.Build;
-import android.os.Build.VERSION_CODES;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -63,7 +62,7 @@
  */
 public final class MediaProjectionManagerService extends SystemService
         implements Watchdog.Monitor {
-    private static final boolean REQUIRE_FG_SERVICE_FOR_PROJECTION = false;
+    private static final boolean REQUIRE_FG_SERVICE_FOR_PROJECTION = true;
     private static final String TAG = "MediaProjectionManagerService";
 
     private final Object mLock = new Object(); // Protects the list of media projections
@@ -146,7 +145,7 @@
                 return;
             }
 
-            if (mProjectionGrant.targetSdkVersion < VERSION_CODES.Q) {
+            if (!mProjectionGrant.requiresForegroundService()) {
                 return;
             }
 
@@ -294,7 +293,8 @@
                     throw new IllegalArgumentException("No package matching :" + packageName);
                 }
 
-                projection = new MediaProjection(type, uid, packageName, ai.targetSdkVersion);
+                projection = new MediaProjection(type, uid, packageName, ai.targetSdkVersion,
+                        ai.isPrivilegedApp());
                 if (isPermanentGrant) {
                     mAppOps.setMode(AppOpsManager.OP_PROJECT_MEDIA,
                             projection.uid, projection.packageName, AppOpsManager.MODE_ALLOWED);
@@ -396,19 +396,22 @@
         public final int uid;
         public final String packageName;
         public final UserHandle userHandle;
-        public final int targetSdkVersion;
+        private final int mTargetSdkVersion;
+        private final boolean mIsPrivileged;
 
         private IMediaProjectionCallback mCallback;
         private IBinder mToken;
         private IBinder.DeathRecipient mDeathEater;
         private int mType;
 
-        MediaProjection(int type, int uid, String packageName, int targetSdkVersion) {
+        MediaProjection(int type, int uid, String packageName, int targetSdkVersion,
+                boolean isPrivileged) {
             mType = type;
             this.uid = uid;
             this.packageName = packageName;
             userHandle = new UserHandle(UserHandle.getUserId(uid));
-            this.targetSdkVersion = targetSdkVersion;
+            mTargetSdkVersion = targetSdkVersion;
+            mIsPrivileged = isPrivileged;
         }
 
         @Override // Binder call
@@ -466,7 +469,7 @@
                 }
 
                 if (REQUIRE_FG_SERVICE_FOR_PROJECTION
-                        && targetSdkVersion >= Build.VERSION_CODES.Q
+                        && requiresForegroundService()
                         && !mActivityManagerInternal.hasRunningForegroundService(
                                 uid, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION)) {
                     throw new SecurityException("Media projections require a foreground service"
@@ -531,6 +534,10 @@
             return new MediaProjectionInfo(packageName, userHandle);
         }
 
+        boolean requiresForegroundService() {
+            return mTargetSdkVersion >= Build.VERSION_CODES.Q && !mIsPrivileged;
+        }
+
         public void dump(PrintWriter pw) {
             pw.println("(" + packageName + ", uid=" + uid + "): " + typeToString(mType));
         }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 75b62cb..af58b19 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1335,7 +1335,7 @@
             case TYPE_WARNING: {
                 title = res.getText(R.string.data_usage_warning_title);
                 body = res.getString(R.string.data_usage_warning_body,
-                        Formatter.formatFileSize(mContext, totalBytes));
+                        Formatter.formatFileSize(mContext, totalBytes, Formatter.FLAG_IEC_UNITS));
 
                 builder.setSmallIcon(R.drawable.stat_notify_error);
 
@@ -1383,7 +1383,7 @@
                 }
                 final long overBytes = totalBytes - policy.limitBytes;
                 body = res.getString(R.string.data_usage_limit_snoozed_body,
-                        Formatter.formatFileSize(mContext, overBytes));
+                        Formatter.formatFileSize(mContext, overBytes, Formatter.FLAG_IEC_UNITS));
 
                 builder.setOngoing(true);
                 builder.setSmallIcon(R.drawable.stat_notify_error);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e43fc1f..f2e56b5 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -17,7 +17,12 @@
 package com.android.server.notification;
 
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+import static android.app.Notification.CATEGORY_CALL;
+import static android.app.Notification.FLAG_AUTOGROUP_SUMMARY;
+import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.Notification.FLAG_NO_CLEAR;
+import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED;
 import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED;
 import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED;
@@ -84,6 +89,7 @@
 
 import android.Manifest;
 import android.Manifest.permission;
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -102,11 +108,14 @@
 import android.app.NotificationManager;
 import android.app.NotificationManager.Policy;
 import android.app.PendingIntent;
+import android.app.Person;
 import android.app.StatusBarManager;
 import android.app.UriGrantsManager;
 import android.app.admin.DeviceAdminInfo;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.app.backup.BackupManager;
+import android.app.role.OnRoleHoldersChangedListener;
+import android.app.role.RoleManager;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStatsManagerInternal;
 import android.companion.ICompanionDeviceManager;
@@ -151,6 +160,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.provider.DeviceConfig;
@@ -216,7 +226,6 @@
 import com.android.server.notification.ManagedServices.ManagedServiceInfo;
 import com.android.server.notification.ManagedServices.UserProfiles;
 import com.android.server.pm.PackageManagerService;
-import com.android.server.pm.UserManagerService;
 import com.android.server.policy.PhoneWindowManager;
 import com.android.server.statusbar.StatusBarManagerInternal;
 import com.android.server.uri.UriGrantsManagerInternal;
@@ -249,6 +258,7 @@
 import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.BiConsumer;
 
@@ -300,6 +310,12 @@
             Adjustment.KEY_TEXT_REPLIES,
             Adjustment.KEY_USER_SENTIMENT};
 
+    static final String[] NON_BLOCKABLE_DEFAULT_ROLES = new String[] {
+            RoleManager.ROLE_DIALER,
+            RoleManager.ROLE_SMS,
+            RoleManager.ROLE_EMERGENCY
+    };
+
     // When #matchesCallFilter is called from the ringer, wait at most
     // 3s to resolve the contacts. This timeout is required since
     // ContactsProvider might take a long time to start up.
@@ -343,6 +359,8 @@
     private IDeviceIdleController mDeviceIdleController;
     private IUriGrantsManager mUgm;
     private UriGrantsManagerInternal mUgmInternal;
+    private RoleObserver mRoleObserver;
+    private UserManager mUm;
 
     final IBinder mForegroundToken = new Binder();
     private WorkerHandler mHandler;
@@ -553,18 +571,13 @@
         }
     }
 
-    UserManagerService getUserManagerService() {
-        return UserManagerService.getInstance();
-    }
-
     void readPolicyXml(InputStream stream, boolean forRestore, int userId)
             throws XmlPullParserException, NumberFormatException, IOException {
         final XmlPullParser parser = Xml.newPullParser();
         parser.setInput(stream, StandardCharsets.UTF_8.name());
         XmlUtils.beginDocument(parser, TAG_NOTIFICATION_POLICY);
         boolean migratedManagedServices = false;
-        boolean ineligibleForManagedServices = forRestore
-                && getUserManagerService().isManagedProfile(userId);
+        boolean ineligibleForManagedServices = forRestore && mUm.isManagedProfile(userId);
         int outerDepth = parser.getDepth();
         while (XmlUtils.nextElementWithin(parser, outerDepth)) {
             if (ZenModeConfig.ZEN_TAG.equals(parser.getName())) {
@@ -612,7 +625,8 @@
         mAssistants.resetDefaultAssistantsIfNecessary();
     }
 
-    private void loadPolicyFile() {
+    @VisibleForTesting
+    protected void loadPolicyFile() {
         if (DBG) Slog.d(TAG, "loadPolicyFile");
         synchronized (mPolicyFile) {
             InputStream infile = null;
@@ -836,7 +850,7 @@
                 }
             }
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
-                    Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE,
+                    FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE,
                     true, userId, REASON_CANCEL, nv.rank, nv.count,null);
             nv.recycle();
         }
@@ -1530,7 +1544,8 @@
             NotificationUsageStats usageStats, AtomicFile policyFile,
             ActivityManager activityManager, GroupHelper groupHelper, IActivityManager am,
             UsageStatsManagerInternal appUsageStats, DevicePolicyManagerInternal dpm,
-            IUriGrantsManager ugm, UriGrantsManagerInternal ugmInternal, AppOpsManager appOps) {
+            IUriGrantsManager ugm, UriGrantsManagerInternal ugmInternal, AppOpsManager appOps,
+            UserManager userManager) {
         Resources resources = getContext().getResources();
         mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
                 Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
@@ -1552,6 +1567,7 @@
         mDeviceIdleController = IDeviceIdleController.Stub.asInterface(
                 ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
         mDpm = dpm;
+        mUm = userManager;
 
         mHandler = new WorkerHandler(looper);
         mRankingThread.start();
@@ -1697,14 +1713,16 @@
                         AppGlobals.getPackageManager()),
                 new ConditionProviders(getContext(), mUserProfiles, AppGlobals.getPackageManager()),
                 null, snoozeHelper, new NotificationUsageStats(getContext()),
-                new AtomicFile(new File(systemDir, "notification_policy.xml"), "notification-policy"),
+                new AtomicFile(new File(
+                        systemDir, "notification_policy.xml"), "notification-policy"),
                 (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE),
                 getGroupHelper(), ActivityManager.getService(),
                 LocalServices.getService(UsageStatsManagerInternal.class),
                 LocalServices.getService(DevicePolicyManagerInternal.class),
                 UriGrantsManager.getService(),
                 LocalServices.getService(UriGrantsManagerInternal.class),
-                (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE));
+                (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE),
+                getContext().getSystemService(UserManager.class));
 
         // register for various Intents
         IntentFilter filter = new IntentFilter();
@@ -1827,6 +1845,9 @@
             mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
             mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
             mZenModeHelper.onSystemReady();
+            mRoleObserver = new RoleObserver(getContext().getSystemService(RoleManager.class),
+                    getContext().getMainExecutor());
+            mRoleObserver.init();
         } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
             // This observer will force an update when observe is called, causing us to
             // bind to listener services.
@@ -2324,7 +2345,7 @@
             // Don't allow client applications to cancel foreground service notis or autobundled
             // summaries.
             final int mustNotHaveFlags = isCallingUidSystem() ? 0 :
-                    (FLAG_FOREGROUND_SERVICE | Notification.FLAG_AUTOGROUP_SUMMARY);
+                    (FLAG_FOREGROUND_SERVICE | FLAG_AUTOGROUP_SUMMARY);
             cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0,
                     mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null);
         }
@@ -2406,6 +2427,11 @@
         @Override
         public boolean areNotificationsEnabledForPackage(String pkg, int uid) {
             checkCallerIsSystemOrSameApp(pkg);
+            if (UserHandle.getCallingUserId() != UserHandle.getUserId(uid)) {
+                getContext().enforceCallingPermission(
+                        android.Manifest.permission.INTERACT_ACROSS_USERS,
+                        "canNotifyAsPackage for uid " + uid);
+            }
 
             return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE;
         }
@@ -2419,6 +2445,13 @@
         public boolean areBubblesAllowedForPackage(String pkg, int uid) {
             enforceSystemOrSystemUIOrSamePackage(pkg,
                     "Caller not system or systemui or same package");
+
+            if (UserHandle.getCallingUserId() != UserHandle.getUserId(uid)) {
+                getContext().enforceCallingPermission(
+                        android.Manifest.permission.INTERACT_ACROSS_USERS,
+                        "canNotifyAsPackage for uid " + uid);
+            }
+
             return mPreferencesHelper.areBubblesAllowed(pkg, uid);
         }
 
@@ -3116,7 +3149,7 @@
         private void cancelNotificationFromListenerLocked(ManagedServiceInfo info,
                 int callingUid, int callingPid, String pkg, String tag, int id, int userId) {
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
-                    Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE,
+                    FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE | FLAG_BUBBLE,
                     true,
                     userId, REASON_LISTENER_CANCEL, info);
         }
@@ -4106,11 +4139,19 @@
         if (r == null) {
             return;
         }
-        if (mAssistants.isAdjustmentAllowed(adjustment.getKey())) {
-            if (adjustment.getSignals() != null) {
-                Bundle.setDefusable(adjustment.getSignals(), true);
-                r.addAdjustment(adjustment);
+        if (adjustment.getSignals() != null) {
+            final Bundle adjustments = adjustment.getSignals();
+            Bundle.setDefusable(adjustments, true);
+            List<String> toRemove = new ArrayList<>();
+            for (String potentialKey : adjustments.keySet()) {
+                if (!mAssistants.isAdjustmentAllowed(potentialKey)) {
+                    toRemove.add(potentialKey);
+                }
             }
+            for (String removeKey : toRemove) {
+                adjustments.remove(removeKey);
+            }
+            r.addAdjustment(adjustment);
         }
     }
 
@@ -4199,7 +4240,7 @@
                                 .setGroupSummary(true)
                                 .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
                                 .setGroup(GroupHelper.AUTOGROUP_KEY)
-                                .setFlag(Notification.FLAG_AUTOGROUP_SUMMARY, true)
+                                .setFlag(FLAG_AUTOGROUP_SUMMARY, true)
                                 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
                                 .setColor(adjustedSbn.getNotification().color)
                                 .setLocalOnly(true)
@@ -4720,6 +4761,45 @@
         }
     }
 
+    /**
+     * Updates the flags for this notification to reflect whether it is a bubble or not.
+     */
+    private void flagNotificationForBubbles(NotificationRecord r, String pkg, int userId,
+            NotificationRecord oldRecord) {
+        Notification notification = r.getNotification();
+
+        // Does the app want to bubble & have permission to bubble?
+        boolean canBubble = notification.getBubbleMetadata() != null
+                && mPreferencesHelper.areBubblesAllowed(pkg, userId)
+                && r.getChannel().canBubble();
+
+        // Is the app in the foreground?
+        final boolean appIsForeground =
+                mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
+
+        // Is the notification something we'd allow to bubble?
+        // A call with a foreground service + person
+        ArrayList<Person> peopleList = notification.extras != null
+                ? notification.extras.getParcelableArrayList(Notification.EXTRA_PEOPLE_LIST)
+                : null;
+        boolean isForegroundCall = CATEGORY_CALL.equals(notification.category)
+                && (notification.flags & FLAG_FOREGROUND_SERVICE) != 0;
+        // OR message style (which always has a person)
+        Class<? extends Notification.Style> style = notification.getNotificationStyle();
+        boolean isMessageStyle = Notification.MessagingStyle.class.equals(style);
+        boolean notificationAppropriateToBubble = isMessageStyle
+                || (peopleList != null && !peopleList.isEmpty() && isForegroundCall);
+        // OR something that was previously a bubble & still exists
+        boolean bubbleUpdate = oldRecord != null
+                && (oldRecord.getNotification().flags & FLAG_BUBBLE) != 0;
+
+        if (canBubble && (notificationAppropriateToBubble || appIsForeground || bubbleUpdate)) {
+            notification.flags |= FLAG_BUBBLE;
+        } else {
+            notification.flags &= ~FLAG_BUBBLE;
+        }
+    }
+
     private void doChannelWarningToast(CharSequence toastText) {
         Binder.withCleanCallingIdentity(() -> {
             final int defaultWarningEnabled = Build.IS_DEBUGGABLE ? 1 : 0;
@@ -5075,6 +5155,9 @@
                 final int id = n.getId();
                 final String tag = n.getTag();
 
+                // We need to fix the notification up a little for bubbles
+                flagNotificationForBubbles(r, pkg, callingUid, old);
+
                 // Handle grouped notifications and bail out early if we
                 // can to avoid extracting signals.
                 handleGroupedNotificationLocked(r, old, callingUid, callingPid);
@@ -5176,8 +5259,8 @@
                     // Ensure if this is a foreground service that the proper additional
                     // flags are set.
                     if ((notification.flags & FLAG_FOREGROUND_SERVICE) != 0) {
-                        notification.flags |= Notification.FLAG_ONGOING_EVENT
-                                | Notification.FLAG_NO_CLEAR;
+                        notification.flags |= FLAG_ONGOING_EVENT
+                                | FLAG_NO_CLEAR;
                     }
 
                     mRankingHelper.extractSignals(r);
@@ -6634,8 +6717,11 @@
                             null, userId, 0, 0, reason, listenerName);
 
                     FlagChecker flagChecker = (int flags) -> {
-                        if ((flags & (Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR))
-                                != 0) {
+                        int flagsToCheck = FLAG_ONGOING_EVENT | FLAG_NO_CLEAR;
+                        if (REASON_LISTENER_CANCEL_ALL == reason) {
+                            flagsToCheck |= FLAG_BUBBLE;
+                        }
+                        if ((flags & flagsToCheck) != 0) {
                             return false;
                         }
                         return true;
@@ -8054,6 +8140,98 @@
         }
     }
 
+    class RoleObserver implements OnRoleHoldersChangedListener {
+        // Role name : user id : list of approved packages
+        private ArrayMap<String, ArrayMap<Integer, ArraySet<String>>> mNonBlockableDefaultApps;
+
+        private final RoleManager mRm;
+        private final Executor mExecutor;
+
+        RoleObserver(@NonNull RoleManager roleManager,
+                @NonNull @CallbackExecutor Executor executor) {
+            mRm = roleManager;
+            mExecutor = executor;
+        }
+
+        public void init() {
+            List<UserInfo> users = mUm.getUsers();
+            mNonBlockableDefaultApps = new ArrayMap<>();
+            for (int i = 0; i < NON_BLOCKABLE_DEFAULT_ROLES.length; i++) {
+                final ArrayMap<Integer, ArraySet<String>> userToApprovedList = new ArrayMap<>();
+                mNonBlockableDefaultApps.put(NON_BLOCKABLE_DEFAULT_ROLES[i], userToApprovedList);
+                for (int j = 0; j < users.size(); j++) {
+                    Integer userId = users.get(j).getUserHandle().getIdentifier();
+                    ArraySet<String> approvedForUserId = new ArraySet<>(mRm.getRoleHoldersAsUser(
+                            NON_BLOCKABLE_DEFAULT_ROLES[i], UserHandle.of(userId)));
+                    userToApprovedList.put(userId, approvedForUserId);
+                    mPreferencesHelper.updateDefaultApps(userId, null, approvedForUserId);
+                }
+            }
+
+            mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
+        }
+
+        @VisibleForTesting
+        public boolean isApprovedPackageForRoleForUser(String role, String pkg, int userId) {
+            return mNonBlockableDefaultApps.get(role).get(userId).contains(pkg);
+        }
+
+        /**
+         * Convert the assistant-role holder into settings. The rest of the system uses the
+         * settings.
+         *
+         * @param roleName the name of the role whose holders are changed
+         * @param user the user for this role holder change
+         */
+        @Override
+        public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
+            // we only care about a couple of the roles they'll tell us about
+            boolean relevantChange = false;
+            for (int i = 0; i < NON_BLOCKABLE_DEFAULT_ROLES.length; i++) {
+                if (NON_BLOCKABLE_DEFAULT_ROLES[i].equals(roleName)) {
+                    relevantChange = true;
+                    break;
+                }
+            }
+
+            if (!relevantChange) {
+                return;
+            }
+
+            ArraySet<String> roleHolders = new ArraySet<>(mRm.getRoleHoldersAsUser(roleName, user));
+
+            // find the diff
+            ArrayMap<Integer, ArraySet<String>> prevApprovedForRole =
+                    mNonBlockableDefaultApps.getOrDefault(roleName, new ArrayMap<>());
+            ArraySet<String> previouslyApproved =
+                    prevApprovedForRole.getOrDefault(user.getIdentifier(), new ArraySet<>());
+
+            ArraySet<String> toRemove = new ArraySet<>();
+            ArraySet<String> toAdd = new ArraySet<>();
+
+            for (String previous : previouslyApproved) {
+                if (!roleHolders.contains(previous)) {
+                    toRemove.add(previous);
+                }
+            }
+            for (String nowApproved : roleHolders) {
+                if (!previouslyApproved.contains(nowApproved)) {
+                    toAdd.add(nowApproved);
+                }
+            }
+
+            // store newly approved apps
+            prevApprovedForRole.put(user.getIdentifier(), roleHolders);
+            mNonBlockableDefaultApps.put(roleName, prevApprovedForRole);
+
+            // update what apps can be blocked
+            mPreferencesHelper.updateDefaultApps(user.getIdentifier(), toRemove, toAdd);
+
+            // RoleManager is the source of truth for this data so we don't need to trigger a
+            // write of the notification policy xml for this change
+        }
+    }
+
     public static final class DumpFilter {
         public boolean filtered = false;
         public String pkgFilter;
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index de93120..4ed24ec 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -783,7 +783,8 @@
         // Consider Notification Assistant and system overrides to importance. If both, system wins.
         if (!getChannel().hasUserSetImportance()
                 && mAssistantImportance != IMPORTANCE_UNSPECIFIED
-                && !getChannel().isImportanceLockedByOEM()) {
+                && !getChannel().isImportanceLockedByOEM()
+                && !getChannel().isImportanceLockedByCriticalDeviceFunction()) {
             mImportance = mAssistantImportance;
             mImportanceExplanationCode = MetricsEvent.IMPORTANCE_EXPLANATION_ASST;
         }
@@ -1290,13 +1291,11 @@
                 lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL,
                         stats.naturalImportance);
             }
-            // Log Assistant override if it was itself overridden by System. Since System can't be
-            // overridden, it never needs logging.
-            if (mImportanceExplanationCode == MetricsEvent.IMPORTANCE_EXPLANATION_SYSTEM
-                    && mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
-                lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST,
+        }
+        // Log Assistant override if present, whether or not importance calculation is complete.
+        if (mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
+            lm.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST,
                         mAssistantImportance);
-            }
         }
         return lm;
     }
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 660309c..a3e90dc 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -37,6 +37,8 @@
 import android.service.notification.RankingHelperProto;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.util.proto.ProtoOutputStream;
@@ -100,6 +102,7 @@
     private static final boolean DEFAULT_SHOW_BADGE = true;
     private static final boolean DEFAULT_ALLOW_BUBBLE = true;
     private static final boolean DEFAULT_OEM_LOCKED_IMPORTANCE  = false;
+    private static final boolean DEFAULT_APP_LOCKED_IMPORTANCE  = false;
 
     /**
      * Default value for what fields are user locked. See {@link LockableAppFields} for all lockable
@@ -659,6 +662,7 @@
                 channel.setImportanceLockedByOEM(true);
             }
         }
+        channel.setImportanceLockedByCriticalDeviceFunction(r.defaultAppLockedImportance);
         if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
             channel.setLockscreenVisibility(
                     NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
@@ -707,6 +711,10 @@
         if (updatedChannel.isImportanceLockedByOEM()) {
             updatedChannel.setImportance(channel.getImportance());
         }
+        updatedChannel.setImportanceLockedByCriticalDeviceFunction(r.defaultAppLockedImportance);
+        if (updatedChannel.isImportanceLockedByCriticalDeviceFunction()) {
+            updatedChannel.setImportance(channel.getImportance());
+        }
 
         r.channels.put(updatedChannel.getId(), updatedChannel);
 
@@ -844,6 +852,26 @@
         }
     }
 
+    public void updateDefaultApps(int userId, ArraySet<String> toRemove, ArraySet<String> toAdd) {
+        synchronized (mPackagePreferences) {
+            for (PackagePreferences p : mPackagePreferences.values()) {
+                if (userId == UserHandle.getUserId(p.uid)) {
+                    if (toRemove != null && toRemove.contains(p.pkg)) {
+                        p.defaultAppLockedImportance = false;
+                        for (NotificationChannel channel : p.channels.values()) {
+                            channel.setImportanceLockedByCriticalDeviceFunction(false);
+                        }
+                    } else if (toAdd != null && toAdd.contains(p.pkg)) {
+                        p.defaultAppLockedImportance = true;
+                        for (NotificationChannel channel : p.channels.values()) {
+                            channel.setImportanceLockedByCriticalDeviceFunction(true);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     public NotificationChannelGroup getNotificationChannelGroupWithChannels(String pkg,
             int uid, String groupId, boolean includeDeleted) {
         Preconditions.checkNotNull(pkg);
@@ -1729,8 +1757,11 @@
         boolean showBadge = DEFAULT_SHOW_BADGE;
         boolean allowBubble = DEFAULT_ALLOW_BUBBLE;
         int lockedAppFields = DEFAULT_LOCKED_APP_FIELDS;
+        // these fields are loaded on boot from a different source of truth and so are not
+        // written to notification policy xml
         boolean oemLockedImportance = DEFAULT_OEM_LOCKED_IMPORTANCE;
         List<String> futureOemLockedChannels = new ArrayList<>();
+        boolean defaultAppLockedImportance = DEFAULT_APP_LOCKED_IMPORTANCE;
 
         Delegate delegate = null;
         ArrayMap<String, NotificationChannel> channels = new ArrayMap<>();
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 37dd63a..51d5acc 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -345,7 +345,7 @@
             switch (action) {
                 case ACTION_PACKAGE_ADDED:
                     if (replacing) {
-                        onPackageUpgraded(packageName, userIds);
+                        onPackageReplaced(packageName, userIds);
                     } else {
                         onPackageAdded(packageName, userIds);
                     }
@@ -355,7 +355,7 @@
                     break;
                 case ACTION_PACKAGE_REMOVED:
                     if (replacing) {
-                        onPackageUpgrading(packageName, userIds);
+                        onPackageReplacing(packageName, userIds);
                     } else {
                         onPackageRemoved(packageName, userIds);
                     }
@@ -374,7 +374,7 @@
                     synchronized (mLock) {
                         final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId,
                                 false);
-                        if (pi != null) {
+                        if (pi != null && !pi.applicationInfo.isInstantApp()) {
                             mPackageManager.cachePackageInfo(packageName, userId, pi);
                             if (pi.isOverlayPackage()) {
                                 mImpl.onOverlayPackageAdded(packageName, userId);
@@ -397,7 +397,7 @@
                     synchronized (mLock) {
                         final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId,
                                 false);
-                        if (pi != null) {
+                        if (pi != null && pi.applicationInfo.isInstantApp()) {
                             mPackageManager.cachePackageInfo(packageName, userId, pi);
                             if (pi.isOverlayPackage()) {
                                 mImpl.onOverlayPackageChanged(packageName, userId);
@@ -412,18 +412,16 @@
             }
         }
 
-        private void onPackageUpgrading(@NonNull final String packageName,
+        private void onPackageReplacing(@NonNull final String packageName,
                 @NonNull final int[] userIds) {
             try {
-                traceBegin(TRACE_TAG_RRO, "OMS#onPackageUpgrading " + packageName);
+                traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplacing " + packageName);
                 for (int userId : userIds) {
                     synchronized (mLock) {
                         mPackageManager.forgetPackageInfo(packageName, userId);
                         final OverlayInfo oi = mImpl.getOverlayInfo(packageName, userId);
                         if (oi != null) {
-                            mImpl.onOverlayPackageUpgrading(packageName, userId);
-                        } else {
-                            mImpl.onTargetPackageUpgrading(packageName, userId);
+                            mImpl.onOverlayPackageReplacing(packageName, userId);
                         }
                     }
                 }
@@ -432,20 +430,20 @@
             }
         }
 
-        private void onPackageUpgraded(@NonNull final String packageName,
+        private void onPackageReplaced(@NonNull final String packageName,
                 @NonNull final int[] userIds) {
             try {
-                traceBegin(TRACE_TAG_RRO, "OMS#onPackageUpgraded " + packageName);
+                traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplaced " + packageName);
                 for (int userId : userIds) {
                     synchronized (mLock) {
                         final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId,
                                 false);
-                        if (pi != null) {
+                        if (pi != null && !pi.applicationInfo.isInstantApp()) {
                             mPackageManager.cachePackageInfo(packageName, userId, pi);
                             if (pi.isOverlayPackage()) {
-                                mImpl.onOverlayPackageUpgraded(packageName, userId);
+                                mImpl.onOverlayPackageReplaced(packageName, userId);
                             } else {
-                                mImpl.onTargetPackageUpgraded(packageName, userId);
+                                mImpl.onTargetPackageReplaced(packageName, userId);
                             }
                         }
                     }
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 15ed063..ec53e98 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -21,8 +21,8 @@
 import static android.content.om.OverlayInfo.STATE_ENABLED_STATIC;
 import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
 import static android.content.om.OverlayInfo.STATE_NO_IDMAP;
-import static android.content.om.OverlayInfo.STATE_OVERLAY_UPGRADING;
-import static android.content.om.OverlayInfo.STATE_TARGET_UPGRADING;
+import static android.content.om.OverlayInfo.STATE_OVERLAY_IS_BEING_REPLACED;
+import static android.content.om.OverlayInfo.STATE_TARGET_IS_BEING_REPLACED;
 
 import static com.android.server.om.OverlayManagerService.DEBUG;
 import static com.android.server.om.OverlayManagerService.TAG;
@@ -30,12 +30,15 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.om.OverlayInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
 
+import com.android.internal.util.ArrayUtils;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -54,9 +57,14 @@
  * @see OverlayManagerService
  */
 final class OverlayManagerServiceImpl {
+    /**
+     * @deprecated Not used. See {@link android.content.om.OverlayInfo#STATE_TARGET_UPGRADING}.
+     */
+    @Deprecated
+    private static final int FLAG_TARGET_IS_BEING_REPLACED = 1 << 0;
+
     // Flags to use in conjunction with updateState.
-    private static final int FLAG_TARGET_IS_UPGRADING = 1 << 0;
-    private static final int FLAG_OVERLAY_IS_UPGRADING = 1 << 1;
+    private static final int FLAG_OVERLAY_IS_BEING_REPLACED = 1 << 1;
 
     private final PackageManagerHelper mPackageManager;
     private final IdmapManager mIdmapManager;
@@ -247,9 +255,7 @@
             Slog.d(TAG, "onTargetPackageAdded packageName=" + packageName + " userId=" + userId);
         }
 
-        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
-            mListener.onOverlaysChanged(packageName, userId);
-        }
+        updateAndRefreshOverlaysForTarget(packageName, userId, 0);
     }
 
     void onTargetPackageChanged(@NonNull final String packageName, final int userId) {
@@ -257,24 +263,24 @@
             Slog.d(TAG, "onTargetPackageChanged packageName=" + packageName + " userId=" + userId);
         }
 
-        updateAllOverlaysForTarget(packageName, userId, 0);
+        updateAndRefreshOverlaysForTarget(packageName, userId, 0);
     }
 
-    void onTargetPackageUpgrading(@NonNull final String packageName, final int userId) {
+    void onTargetPackageReplacing(@NonNull final String packageName, final int userId) {
         if (DEBUG) {
-            Slog.d(TAG, "onTargetPackageUpgrading packageName=" + packageName + " userId="
+            Slog.d(TAG, "onTargetPackageReplacing packageName=" + packageName + " userId="
                     + userId);
         }
 
-        updateAllOverlaysForTarget(packageName, userId, FLAG_TARGET_IS_UPGRADING);
+        updateAndRefreshOverlaysForTarget(packageName, userId, 0);
     }
 
-    void onTargetPackageUpgraded(@NonNull final String packageName, final int userId) {
+    void onTargetPackageReplaced(@NonNull final String packageName, final int userId) {
         if (DEBUG) {
-            Slog.d(TAG, "onTargetPackageUpgraded packageName=" + packageName + " userId=" + userId);
+            Slog.d(TAG, "onTargetPackageReplaced packageName=" + packageName + " userId=" + userId);
         }
 
-        updateAllOverlaysForTarget(packageName, userId, 0);
+        updateAndRefreshOverlaysForTarget(packageName, userId, 0);
     }
 
     void onTargetPackageRemoved(@NonNull final String packageName, final int userId) {
@@ -282,22 +288,27 @@
             Slog.d(TAG, "onTargetPackageRemoved packageName=" + packageName + " userId=" + userId);
         }
 
-        if (updateAllOverlaysForTarget(packageName, userId, 0)) {
-            mListener.onOverlaysChanged(packageName, userId);
-        }
+        updateAndRefreshOverlaysForTarget(packageName, userId, 0);
     }
 
     /**
      * Update the state of any overlays for this target.
-     *
-     * Returns true if the system should refresh the app's overlay paths (i.e.
-     * if the settings were modified for this target, or there is at least one
-     * enabled framework overlay).
      */
-    private boolean updateAllOverlaysForTarget(@NonNull final String targetPackageName,
+    private void updateAndRefreshOverlaysForTarget(@NonNull final String targetPackageName,
             final int userId, final int flags) {
+        final List<OverlayInfo> ois = new ArrayList<>();
+
+        // Framework overlays added first because order matters when resolving a resource
+        if (!"android".equals(targetPackageName)) {
+            ois.addAll(mSettings.getOverlaysForTarget("android", userId));
+        }
+
+        // Then add the targeted, non-framework overlays which have higher priority
+        ois.addAll(mSettings.getOverlaysForTarget(targetPackageName, userId));
+
+        final List<String> enabledBaseCodePaths = new ArrayList<>(ois.size());
+
         boolean modified = false;
-        final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(targetPackageName, userId);
         final int n = ois.size();
         for (int i = 0; i < n; i++) {
             final OverlayInfo oi = ois.get(i);
@@ -313,13 +324,35 @@
                     Slog.e(TAG, "failed to update settings", e);
                     modified |= mSettings.remove(oi.packageName, userId);
                 }
+
+                if (oi.isEnabled() && overlayPackage.applicationInfo != null) {
+                    enabledBaseCodePaths.add(overlayPackage.applicationInfo.getBaseCodePath());
+                }
             }
         }
 
-        // check for enabled framework overlays
-        modified = modified || !getEnabledOverlayPackageNames("android", userId).isEmpty();
+        if (!modified) {
+            PackageInfo packageInfo = mPackageManager.getPackageInfo(targetPackageName, userId);
+            ApplicationInfo appInfo = packageInfo == null ? null : packageInfo.applicationInfo;
+            String[] resourceDirs = appInfo == null ? null : appInfo.resourceDirs;
 
-        return modified;
+            // If the lists aren't the same length, the enabled overlays have changed
+            if (ArrayUtils.size(resourceDirs) != enabledBaseCodePaths.size()) {
+                modified = true;
+            } else if (resourceDirs != null) {
+                // If any element isn't equal, an overlay or the order of overlays has changed
+                for (int index = 0; index < resourceDirs.length; index++) {
+                    if (!resourceDirs[index].equals(enabledBaseCodePaths.get(index))) {
+                        modified = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (modified) {
+            mListener.onOverlaysChanged(targetPackageName, userId);
+        }
     }
 
     void onOverlayPackageAdded(@NonNull final String packageName, final int userId) {
@@ -364,15 +397,16 @@
         }
     }
 
-    void onOverlayPackageUpgrading(@NonNull final String packageName, final int userId) {
+    void onOverlayPackageReplacing(@NonNull final String packageName, final int userId) {
         if (DEBUG) {
-            Slog.d(TAG, "onOverlayPackageUpgrading packageName=" + packageName + " userId="
+            Slog.d(TAG, "onOverlayPackageReplacing packageName=" + packageName + " userId="
                     + userId);
         }
 
         try {
             final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
-            if (updateState(oi.targetPackageName, packageName, userId, FLAG_OVERLAY_IS_UPGRADING)) {
+            if (updateState(oi.targetPackageName, packageName, userId,
+                        FLAG_OVERLAY_IS_BEING_REPLACED)) {
                 removeIdmapIfPossible(oi);
                 mListener.onOverlaysChanged(oi.targetPackageName, userId);
             }
@@ -381,15 +415,15 @@
         }
     }
 
-    void onOverlayPackageUpgraded(@NonNull final String packageName, final int userId) {
+    void onOverlayPackageReplaced(@NonNull final String packageName, final int userId) {
         if (DEBUG) {
-            Slog.d(TAG, "onOverlayPackageUpgraded packageName=" + packageName + " userId="
+            Slog.d(TAG, "onOverlayPackageReplaced packageName=" + packageName + " userId="
                     + userId);
         }
 
         final PackageInfo pkg = mPackageManager.getPackageInfo(packageName, userId);
         if (pkg == null) {
-            Slog.w(TAG, "overlay package " + packageName + " was upgraded, but couldn't be found");
+            Slog.w(TAG, "overlay package " + packageName + " was replaced, but couldn't be found");
             onOverlayPackageRemoved(packageName, userId);
             return;
         }
@@ -670,12 +704,12 @@
             @Nullable final PackageInfo overlayPackage, final int userId, final int flags)
             throws OverlayManagerSettings.BadKeyException {
 
-        if ((flags & FLAG_TARGET_IS_UPGRADING) != 0) {
-            return STATE_TARGET_UPGRADING;
+        if ((flags & FLAG_TARGET_IS_BEING_REPLACED) != 0) {
+            return STATE_TARGET_IS_BEING_REPLACED;
         }
 
-        if ((flags & FLAG_OVERLAY_IS_UPGRADING) != 0) {
-            return STATE_OVERLAY_UPGRADING;
+        if ((flags & FLAG_OVERLAY_IS_BEING_REPLACED) != 0) {
+            return STATE_OVERLAY_IS_BEING_REPLACED;
         }
 
         // assert expectation on overlay package: can only be null if the flags are used
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index 667dfa1..36b5beb 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -309,7 +309,6 @@
             pw.println("mTargetOverlayableName.: " + item.getTargetOverlayableName());
             pw.println("mBaseCodePath..........: " + item.getBaseCodePath());
             pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
-            pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
             pw.println("mIsEnabled.............: " + item.isEnabled());
             pw.println("mIsStatic..............: " + item.isStatic());
             pw.println("mPriority..............: " + item.mPriority);
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 5fdd872..944aef5 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -27,6 +27,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
 import android.content.pm.PackageParser.PackageParserException;
 import android.os.RemoteException;
@@ -95,7 +96,8 @@
                     }
                     try {
                         list.add(PackageParser.generatePackageInfoFromApex(
-                                new File(ai.packagePath), true /* collect certs */));
+                                new File(ai.packagePath), PackageManager.GET_META_DATA
+                                | PackageManager.GET_SIGNING_CERTIFICATES));
                     } catch (PackageParserException pe) {
                         throw new IllegalStateException("Unable to parse: " + ai, pe);
                     }
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 4b46374..7f346f5 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -148,51 +148,6 @@
         }
     }
 
-    int performDexOpt(SharedLibraryInfo info, String[] instructionSets, DexoptOptions options) {
-        String classLoaderContext = DexoptUtils.getClassLoaderContext(info);
-        final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
-        String compilerFilter = PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
-                PackageManagerService.REASON_SHARED);
-        int result = DEX_OPT_SKIPPED;
-        for (String instructionSet : dexCodeInstructionSets) {
-            int dexoptNeeded = getDexoptNeeded(
-                        info.getPath(), instructionSet, compilerFilter,
-                        classLoaderContext, false /* newProfile */,
-                        false /* downgrade */);
-            if (Math.abs(dexoptNeeded) == DexFile.NO_DEXOPT_NEEDED) {
-                continue;
-            }
-            // Special string recognized by installd.
-            final String packageName = "*";
-            final String outputPath = null;
-            int dexFlags = DEXOPT_PUBLIC
-                    | (options.isBootComplete() ? DEXOPT_BOOTCOMPLETE : 0)
-                    | (options.isDexoptIdleBackgroundJob() ? DEXOPT_IDLE_BACKGROUND_JOB : 0);
-            dexFlags = adjustDexoptFlags(dexFlags);
-            final String uuid = StorageManager.UUID_SYSTEM;
-            final String seInfo = null;
-            final int targetSdkVersion = 0;  // Builtin libraries targets the system's SDK version
-            try {
-                mInstaller.dexopt(info.getPath(), Process.SYSTEM_UID, packageName,
-                        instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
-                        uuid, classLoaderContext, seInfo, false /* downgrade */,
-                        targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null,
-                        getReasonName(options.getCompilationReason()));
-                // The end result is:
-                //  - FAILED if any path failed,
-                //  - PERFORMED if at least one path needed compilation,
-                //  - SKIPPED when all paths are up to date
-                if (result != DEX_OPT_FAILED) {
-                    result = DEX_OPT_PERFORMED;
-                }
-            } catch (InstallerException e) {
-                Slog.w(TAG, "Failed to dexopt", e);
-                result = DEX_OPT_FAILED;
-            }
-        }
-        return result;
-    }
-
     /**
      * Performs dexopt on all code paths of the given package.
      * It assumes the install lock is held.
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index ad17549..e4cb283 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -360,7 +360,7 @@
 
                         final long age = System.currentTimeMillis() - session.createdMillis;
                         final long timeSinceUpdate =
-                                System.currentTimeMillis() - session.updatedMillis;
+                                System.currentTimeMillis() - session.getUpdatedMillis();
                         final boolean valid;
                         if (session.isStaged()) {
                             if (timeSinceUpdate >= MAX_TIME_SINCE_UPDATE_MILLIS
@@ -396,6 +396,11 @@
         } finally {
             IoUtils.closeQuietly(fis);
         }
+        // After all of the sessions were loaded, they are ready to be sealed and validated
+        for (int i = 0; i < mSessions.size(); ++i) {
+            PackageInstallerSession session = mSessions.valueAt(i);
+            session.sealAndValidateIfNecessary();
+        }
     }
 
     @GuardedBy("mSessions")
@@ -493,10 +498,11 @@
             }
         }
 
-        if (callingUid == Process.SYSTEM_UID) {
+        if (Build.IS_DEBUGGABLE || isDowngradeAllowedForCaller(callingUid)) {
             params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
         } else {
             params.installFlags &= ~PackageManager.INSTALL_ALLOW_DOWNGRADE;
+            params.installFlags &= ~PackageManager.INSTALL_REQUEST_DOWNGRADE;
         }
 
         boolean isApex = (params.installFlags & PackageManager.INSTALL_APEX) != 0;
@@ -616,6 +622,11 @@
         return sessionId;
     }
 
+    private boolean isDowngradeAllowedForCaller(int callingUid) {
+        return callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID
+                || callingUid == Process.SHELL_UID;
+    }
+
     @Override
     public void updateSessionAppIcon(int sessionId, Bitmap appIcon) {
         synchronized (mSessions) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 66b530f..d2a160b 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -202,7 +202,7 @@
 
     /** Timestamp of the last time this session changed state  */
     @GuardedBy("mLock")
-    long updatedMillis;
+    private long updatedMillis;
 
     /** Uid of the creator of this session. */
     private final int mOriginalInstallerUid;
@@ -231,6 +231,8 @@
     @GuardedBy("mLock")
     private boolean mSealed = false;
     @GuardedBy("mLock")
+    private boolean mShouldBeSealed = false;
+    @GuardedBy("mLock")
     private boolean mCommitted = false;
     @GuardedBy("mLock")
     private boolean mRelinquished = false;
@@ -430,6 +432,7 @@
         this.updatedMillis = createdMillis;
         this.stageDir = stageDir;
         this.stageCid = stageCid;
+        this.mShouldBeSealed = sealed;
         if (childSessionIds != null) {
             for (int childSessionId : childSessionIds) {
                 mChildSessionIds.put(childSessionId, 0);
@@ -450,16 +453,6 @@
         mStagedSessionErrorCode = stagedSessionErrorCode;
         mStagedSessionErrorMessage =
                 stagedSessionErrorMessage != null ? stagedSessionErrorMessage : "";
-        if (sealed) {
-            synchronized (mLock) {
-                try {
-                    sealAndValidateLocked();
-                } catch (PackageManagerException | IOException e) {
-                    destroyInternal();
-                    throw new IllegalArgumentException(e);
-                }
-            }
-        }
     }
 
     public SessionInfo generateInfo() {
@@ -476,6 +469,7 @@
                     mResolvedBaseFile.getAbsolutePath() : null;
             info.progress = mProgress;
             info.sealed = mSealed;
+            info.isCommitted = mCommitted;
             info.active = mActiveCount.get() > 0;
 
             info.mode = params.mode;
@@ -843,17 +837,34 @@
 
     @Override
     public void commit(@NonNull IntentSender statusReceiver, boolean forTransfer) {
-        if (!markAsCommitted(statusReceiver, forTransfer  /* enforce */)) {
+        if (!markAsCommitted(statusReceiver, forTransfer)) {
             return;
         }
         if (isMultiPackage()) {
-
             final SparseIntArray remainingSessions = mChildSessionIds.clone();
-            final ChildStatusIntentReceiver localIntentReceiver =
-                    new ChildStatusIntentReceiver(remainingSessions, statusReceiver);
-            for (int childSessionId : getChildSessionIds()) {
-                mSessionProvider.getSession(childSessionId)
-                        .markAsCommitted(localIntentReceiver.getIntentSender(), forTransfer);
+            final IntentSender childIntentSender =
+                    new ChildStatusIntentReceiver(remainingSessions, statusReceiver)
+                            .getIntentSender();
+            RuntimeException commitException = null;
+            boolean commitFailed = false;
+            for (int i = mChildSessionIds.size() - 1; i >= 0; --i) {
+                final int childSessionId = mChildSessionIds.keyAt(i);
+                try {
+                    // commit all children, regardless if any of them fail; we'll throw/return
+                    // as appropriate once all children have been processed
+                    if (!mSessionProvider.getSession(childSessionId)
+                            .markAsCommitted(childIntentSender, forTransfer)) {
+                        commitFailed = true;
+                    }
+                } catch (RuntimeException e) {
+                    commitException = e;
+                }
+            }
+            if (commitException != null) {
+                throw commitException;
+            }
+            if (commitFailed) {
+                return;
             }
         }
         mHandler.obtainMessage(MSG_COMMIT).sendToTarget();
@@ -931,6 +942,8 @@
             @NonNull IntentSender statusReceiver, boolean forTransfer) {
         Preconditions.checkNotNull(statusReceiver);
 
+        List<PackageInstallerSession> childSessions = getChildSessions();
+
         final boolean wasSealed;
         synchronized (mLock) {
             assertCallerIsOwnerOrRootLocked();
@@ -962,7 +975,7 @@
             wasSealed = mSealed;
             if (!mSealed) {
                 try {
-                    sealAndValidateLocked();
+                    sealAndValidateLocked(childSessions);
                 } catch (IOException e) {
                     throw new IllegalArgumentException(e);
                 } catch (PackageManagerException e) {
@@ -993,21 +1006,91 @@
         return true;
     }
 
+    /** Return a list of child sessions or null if the session is not multipackage
+     *
+     * <p> This method is handy to prevent potential deadlocks (b/123391593)
+     */
+    private @Nullable List<PackageInstallerSession> getChildSessions() {
+        List<PackageInstallerSession> childSessions = null;
+        if (isMultiPackage()) {
+            final int[] childSessionIds = getChildSessionIds();
+            childSessions = new ArrayList<>(childSessionIds.length);
+            for (int childSessionId : childSessionIds) {
+                childSessions.add(mSessionProvider.getSession(childSessionId));
+            }
+        }
+        return childSessions;
+    }
+
+    /**
+     * Assert multipackage install has consistent sessions.
+     *
+     * @throws PackageManagerException if child sessions don't match parent session
+     *                                  in respect to staged and enable rollback parameters.
+     */
+    @GuardedBy("mLock")
+    private void assertMultiPackageConsistencyLocked(
+            @NonNull List<PackageInstallerSession> childSessions) throws PackageManagerException {
+        for (PackageInstallerSession childSession : childSessions) {
+            // It might be that the parent session is loaded before all of it's child sessions are,
+            // e.g. when reading sessions from XML. Those sessions will be null here, and their
+            // conformance with the multipackage params will be checked when they're loaded.
+            if (childSession == null) {
+                continue;
+            }
+            assertConsistencyWithLocked(childSession);
+        }
+    }
+
+    /**
+     * Assert consistency with the given session.
+     *
+     * @throws PackageManagerException if other sessions doesn't match this session
+     *                                  in respect to staged and enable rollback parameters.
+     */
+    @GuardedBy("mLock")
+    private void assertConsistencyWithLocked(PackageInstallerSession other)
+            throws PackageManagerException {
+        // Session groups must be consistent wrt to isStaged parameter. Non-staging session
+        // cannot be grouped with staging sessions.
+        if (this.params.isStaged != other.params.isStaged) {
+            throw new PackageManagerException(
+                PackageManager.INSTALL_FAILED_MULTIPACKAGE_INCONSISTENCY,
+                "Multipackage Inconsistency: session " + other.sessionId
+                    + " and session " + sessionId
+                    + " have inconsistent staged settings");
+        }
+        if (this.params.getEnableRollback() != other.params.getEnableRollback()) {
+            throw new PackageManagerException(
+                PackageManager.INSTALL_FAILED_MULTIPACKAGE_INCONSISTENCY,
+                "Multipackage Inconsistency: session " + other.sessionId
+                    + " and session " + sessionId
+                    + " have inconsistent rollback settings");
+        }
+    }
+
     /**
      * Seal the session to prevent further modification and validate the contents of it.
      *
      * <p>The session will be sealed after calling this method even if it failed.
      *
+     * @param childSessions the child sessions of a multipackage that will be checked for
+     *                      consistency. Can be null if session is not multipackage.
      * @throws PackageManagerException if the session was sealed but something went wrong. If the
      *                                 session was sealed this is the only possible exception.
      */
     @GuardedBy("mLock")
-    private void sealAndValidateLocked() throws PackageManagerException, IOException {
+    private void sealAndValidateLocked(List<PackageInstallerSession> childSessions)
+            throws PackageManagerException, IOException {
         assertNoWriteFileTransfersOpenLocked();
         assertPreparedAndNotDestroyedLocked("sealing of session");
 
         mSealed = true;
 
+        if (childSessions != null) {
+            assertMultiPackageConsistencyLocked(childSessions);
+        }
+
         if (params.isStaged) {
             final PackageInstallerSession activeSession = mStagingManager.getActiveSession();
             final boolean anotherSessionAlreadyInProgress =
@@ -1047,6 +1130,38 @@
         }
     }
 
+    /**
+     * If session should be sealed, then it's sealed to prevent further modification
+     * and then it's validated.
+     *
+     * If the session was sealed but something went wrong then it's destroyed.
+     *
+     * <p> This is meant to be called after all of the sessions are loaded and added to
+     * PackageInstallerService
+     */
+    void sealAndValidateIfNecessary() {
+        synchronized (mLock) {
+            if (!mShouldBeSealed) {
+                return;
+            }
+        }
+        List<PackageInstallerSession> childSessions = getChildSessions();
+        synchronized (mLock) {
+            try {
+                sealAndValidateLocked(childSessions);
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
+            } catch (PackageManagerException e) {
+                Slog.e(TAG, "Package not valid", e);
+                // Session is sealed but could not be verified, we need to destroy it.
+                destroyInternal();
+                // Dispatch message to remove session from PackageInstallerService
+                dispatchSessionFinished(
+                        e.error, ExceptionUtils.getCompleteMessage(e), null);
+            }
+        }
+    }
+
     /** Update the timestamp of when the staged session last changed state */
     public void markUpdated() {
         synchronized (mLock) {
@@ -1075,12 +1190,14 @@
             throw new SecurityException("Can only transfer sessions that use public options");
         }
 
+        List<PackageInstallerSession> childSessions = getChildSessions();
+
         synchronized (mLock) {
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotSealedLocked("transfer");
 
             try {
-                sealAndValidateLocked();
+                sealAndValidateLocked(childSessions);
             } catch (IOException e) {
                 throw new IllegalStateException(e);
             } catch (PackageManagerException e) {
@@ -1131,14 +1248,7 @@
         // outside of the lock, because reading the child
         // sessions with the lock held could lead to deadlock
         // (b/123391593).
-        List<PackageInstallerSession> childSessions = null;
-        if (isMultiPackage()) {
-            final int[] childSessionIds = getChildSessionIds();
-            childSessions = new ArrayList<>(childSessionIds.length);
-            for (int childSessionId : childSessionIds) {
-                childSessions.add(mSessionProvider.getSession(childSessionId));
-            }
-        }
+        List<PackageInstallerSession> childSessions = getChildSessions();
 
         try {
             synchronized (mLock) {
@@ -1740,6 +1850,15 @@
         }
     }
 
+    /**
+     * @return the timestamp of when this session last changed state
+     */
+    public long getUpdatedMillis() {
+        synchronized (mLock) {
+            return updatedMillis;
+        }
+    }
+
     String getInstallerPackageName() {
         synchronized (mLock) {
             return mInstallerPackageName;
@@ -1964,15 +2083,6 @@
                             + " does not exist"),
                     false, true).rethrowAsRuntimeException();
         }
-        // Session groups must be consistent wrt to isStaged parameter. Non-staging session
-        // cannot be grouped with staging sessions.
-        if (this.params.isStaged ^ childSession.params.isStaged) {
-            throw new RemoteException("Unable to add child.",
-                    new PackageManagerException("Child session " + childSessionId
-                            + " and parent session " + this.sessionId + " do not have consistent"
-                            + " staging session settings."),
-                    false, true);
-        }
         synchronized (mLock) {
             assertCallerIsOwnerOrRootLocked();
             assertPreparedAndNotSealedLocked("addChildSessionId");
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 73b000e..643c582d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -476,6 +476,7 @@
     static final int SCAN_AS_VENDOR = 1 << 20;
     static final int SCAN_AS_PRODUCT = 1 << 21;
     static final int SCAN_AS_PRODUCT_SERVICES = 1 << 22;
+    static final int SCAN_AS_ODM = 1 << 23;
 
     @IntDef(flag = true, prefix = { "SCAN_" }, value = {
             SCAN_NO_DEX,
@@ -594,6 +595,8 @@
 
     private static final String PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
 
+    private static final String ODM_OVERLAY_DIR = "/odm/overlay";
+
     /** Canonical intent used to identify what counts as a "web browser" app */
     private static final Intent sBrowserIntent;
     static {
@@ -1141,11 +1144,22 @@
                     switch (userStatus) {
                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
                             if (!verified) {
-                                // updatedStatus is already UNDEFINED
-                                needUpdate = true;
+                                // Don't demote if sysconfig says 'always'
+                                SystemConfig systemConfig = SystemConfig.getInstance();
+                                ArraySet<String> packages = systemConfig.getLinkedApps();
+                                if (!packages.contains(packageName)) {
+                                    // updatedStatus is already UNDEFINED
+                                    needUpdate = true;
 
-                                if (DEBUG_DOMAIN_VERIFICATION) {
-                                    Slog.d(TAG, "Formerly validated but now failing; demoting");
+                                    if (DEBUG_DOMAIN_VERIFICATION) {
+                                        Slog.d(TAG, "Formerly validated but now failing; demoting");
+                                    }
+                                } else {
+                                    if (DEBUG_DOMAIN_VERIFICATION) {
+                                        Slog.d(TAG, "Updating bundled package " + packageName
+                                                + " failed autoVerify, but sysconfig supersedes");
+                                    }
+                                    // leave needUpdate == false here intentionally
                                 }
                             }
                             break;
@@ -1304,8 +1318,11 @@
 
     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
 
-    // Delay time in millisecs
-    static final int BROADCAST_DELAY = 10 * 1000;
+    private static final long BROADCAST_DELAY_DURING_STARTUP = 10 * 1000L; // 10 seconds (in millis)
+    private static final long BROADCAST_DELAY = 1 * 1000L; // 1 second (in millis)
+
+    // When the service constructor finished plus a delay (used for broadcast delay computation)
+    private long mServiceStartWithDelay;
 
     private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
             2 * 60 * 60 * 1000L; /* two hours */
@@ -1927,8 +1944,13 @@
                 // Send broadcast package appeared if external for all users
                 if (isExternal(res.pkg)) {
                     if (!update) {
+                        final StorageManager storage =
+                                mContext.getSystemService(StorageManager.class);
+                        VolumeInfo volume =
+                                storage.findVolumeByUuid(
+                                        res.pkg.applicationInfo.storageUuid.toString());
                         int packageExternalStorageType =
-                                getPackageExternalStorageType(res.pkg);
+                                getPackageExternalStorageType(volume, isExternal(res.pkg));
                         // If the package was installed externally, log it.
                         if (packageExternalStorageType != StorageEnums.UNKNOWN) {
                             StatsLog.write(StatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
@@ -2025,15 +2047,16 @@
 
     /**
      * Gets the type of the external storage a package is installed on.
-     * @param pkg The package for which to get the external storage type.
-     * @return {@link StorageEnum#TYPE_UNKNOWN} if it is not stored externally or the corresponding
-     * {@link StorageEnum} storage type value if it is.
+     * @param packageVolume The storage volume of the package.
+     * @param packageIsExternal true if the package is currently installed on
+     * external/removable/unprotected storage.
+     * @return {@link StorageEnum#TYPE_UNKNOWN} if the package is not stored externally or the
+     * corresponding {@link StorageEnum} storage type value if it is.
      */
-    private int getPackageExternalStorageType(PackageParser.Package pkg) {
-        final StorageManager storage = mContext.getSystemService(StorageManager.class);
-        VolumeInfo volume = storage.findVolumeByUuid(pkg.applicationInfo.storageUuid.toString());
-        if (volume != null) {
-            DiskInfo disk = volume.getDisk();
+    private static int getPackageExternalStorageType(VolumeInfo packageVolume,
+            boolean packageIsExternal) {
+        if (packageVolume != null) {
+            DiskInfo disk = packageVolume.getDisk();
             if (disk != null) {
                 if (disk.isSd()) {
                     return StorageEnums.SD_CARD;
@@ -2041,7 +2064,7 @@
                 if (disk.isUsb()) {
                     return StorageEnums.USB;
                 }
-                if (isExternal(pkg)) {
+                if (packageIsExternal) {
                     return StorageEnums.OTHER;
                 }
             }
@@ -2503,6 +2526,13 @@
                     | SCAN_AS_SYSTEM
                     | SCAN_AS_PRODUCT_SERVICES,
                     0);
+            scanDirTracedLI(new File(ODM_OVERLAY_DIR),
+                    mDefParseFlags
+                    | PackageParser.PARSE_IS_SYSTEM_DIR,
+                    scanFlags
+                    | SCAN_AS_SYSTEM
+                    | SCAN_AS_ODM,
+                    0);
 
             mParallelPackageParserCallback.findStaticOverlayPackages();
 
@@ -2951,7 +2981,7 @@
 
             // Now that we know all of the shared libraries, update all clients to have
             // the correct library paths.
-            updateAllSharedLibrariesLPw(null);
+            updateAllSharedLibrariesLocked(null, Collections.unmodifiableMap(mPackages));
 
             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
                 // NOTE: We ignore potential failures here during a system scan (like
@@ -3206,6 +3236,8 @@
         // once we have a booted system.
         mInstaller.setWarnIfHeld(mPackages);
 
+        mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
+
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
     }
 
@@ -3480,7 +3512,7 @@
     private @NonNull String getRequiredInstallerLPr() {
         final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
-        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
+        intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE);
 
         final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
                 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
@@ -9547,7 +9579,7 @@
                             mDexManager.getPackageUseInfoOrDefault(depPackage.packageName),
                             libraryOptions);
                 } else {
-                    pdo.performDexOpt(info, instructionSets, libraryOptions);
+                    // TODO(ngeoffray): Support dexopting system shared libraries.
                 }
             }
         }
@@ -10000,11 +10032,11 @@
     }
 
     @GuardedBy("mPackages")
-    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
-            PackageParser.Package changingLib) throws PackageManagerException {
+    private void updateSharedLibrariesLocked(PackageParser.Package pkg,
+            PackageParser.Package changingLib, Map<String, PackageParser.Package> availablePackages)
+                    throws PackageManagerException {
         final ArrayList<SharedLibraryInfo> sharedLibraryInfos =
-                collectSharedLibraryInfos(pkg, Collections.unmodifiableMap(mPackages),
-                        mSharedLibraries, null);
+                collectSharedLibraryInfos(pkg, availablePackages, mSharedLibraries, null);
         executeSharedLibrariesUpdateLPr(pkg, changingLib, sharedLibraryInfos);
     }
 
@@ -10096,7 +10128,6 @@
                                     + " library " + libName + " version "
                                     + libraryInfo.getLongVersion() + "; failing!");
                     }
-
                     PackageParser.Package libPkg =
                             availablePackages.get(libraryInfo.getPackageName());
                     if (libPkg == null) {
@@ -10104,12 +10135,8 @@
                                 "Package " + packageName + " requires unavailable static shared"
                                         + " library; failing!");
                     }
-
                     final String[] expectedCertDigests = requiredCertDigests[i];
-
-
                     if (expectedCertDigests.length > 1) {
-
                         // For apps targeting O MR1 we require explicit enumeration of all certs.
                         final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
                                 ? PackageUtils.computeSignaturesSha256Digests(
@@ -10141,7 +10168,6 @@
                             }
                         }
                     } else {
-
                         // lib signing cert could have rotated beyond the one expected, check to see
                         // if the new one has been blessed by the old
                         if (!libPkg.mSigningDetails.hasSha256Certificate(
@@ -10153,7 +10179,6 @@
                         }
                     }
                 }
-
                 if (outUsedLibraries == null) {
                     outUsedLibraries = new ArrayList<>();
                 }
@@ -10164,7 +10189,7 @@
     }
 
     private static boolean hasString(List<String> list, List<String> which) {
-        if (list == null) {
+        if (list == null || which == null) {
             return false;
         }
         for (int i=list.size()-1; i>=0; i--) {
@@ -10178,39 +10203,63 @@
     }
 
     @GuardedBy("mPackages")
-    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
-            PackageParser.Package changingPkg) {
-        ArrayList<PackageParser.Package> res = null;
-        for (PackageParser.Package pkg : mPackages.values()) {
-            if (changingPkg != null
-                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
-                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
-                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
-                            changingPkg.staticSharedLibName)) {
-                return null;
-            }
-            if (res == null) {
-                res = new ArrayList<>();
-            }
-            res.add(pkg);
-            try {
-                updateSharedLibrariesLPr(pkg, changingPkg);
-            } catch (PackageManagerException e) {
-                // If a system app update or an app and a required lib missing we
-                // delete the package and for updated system apps keep the data as
-                // it is better for the user to reinstall than to be in an limbo
-                // state. Also libs disappearing under an app should never happen
-                // - just in case.
-                if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
-                    final int flags = pkg.isUpdatedSystemApp()
-                            ? PackageManager.DELETE_KEEP_DATA : 0;
-                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
-                            flags , null, true, null);
-                }
-                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
-            }
+    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLocked(
+            PackageParser.Package updatedPkg,
+            Map<String, PackageParser.Package> availablePackages) {
+        ArrayList<PackageParser.Package> resultList = null;
+        // Set of all descendants of a library; used to eliminate cycles
+        ArraySet<String> descendants = null;
+        // The current list of packages that need updating
+        ArrayList<PackageParser.Package> needsUpdating = null;
+        if (updatedPkg != null) {
+            needsUpdating = new ArrayList<>(1);
+            needsUpdating.add(updatedPkg);
         }
-        return res;
+        do {
+            final PackageParser.Package changingPkg =
+                    (needsUpdating == null) ? null : needsUpdating.remove(0);
+            for (int i = mPackages.size() - 1; i >= 0; --i) {
+                final PackageParser.Package pkg = mPackages.valueAt(i);
+                if (changingPkg != null
+                        && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
+                        && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
+                        && !ArrayUtils.contains(pkg.usesStaticLibraries,
+                                changingPkg.staticSharedLibName)) {
+                    continue;
+                }
+                if (resultList == null) {
+                    resultList = new ArrayList<>();
+                }
+                resultList.add(pkg);
+                // if we're updating a shared library, all of its descendants must be updated
+                if (changingPkg != null) {
+                    if (descendants == null) {
+                        descendants = new ArraySet<>();
+                    }
+                    if (!descendants.contains(pkg.packageName)) {
+                        descendants.add(pkg.packageName);
+                        needsUpdating.add(pkg);
+                    }
+                }
+                try {
+                    updateSharedLibrariesLocked(pkg, changingPkg, availablePackages);
+                } catch (PackageManagerException e) {
+                    // If a system app update or an app and a required lib missing we
+                    // delete the package and for updated system apps keep the data as
+                    // it is better for the user to reinstall than to be in an limbo
+                    // state. Also libs disappearing under an app should never happen
+                    // - just in case.
+                    if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
+                        final int flags = pkg.isUpdatedSystemApp()
+                                ? PackageManager.DELETE_KEEP_DATA : 0;
+                        deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
+                                flags , null, true, null);
+                    }
+                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
+                }
+            }
+        } while (needsUpdating != null && needsUpdating.size() > 0);
+        return resultList;
     }
 
     @GuardedBy({"mInstallLock", "mPackages"})
@@ -10360,6 +10409,7 @@
      * <li>{@link #SCAN_AS_PRODUCT_SERVICES}</li>
      * <li>{@link #SCAN_AS_INSTANT_APP}</li>
      * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
+     * <li>{@link #SCAN_AS_ODM}</li>
      * </ul>
      */
     private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
@@ -10396,6 +10446,10 @@
                     & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0) {
                 scanFlags |= SCAN_AS_PRODUCT_SERVICES;
             }
+            if ((systemPkgSetting.pkgPrivateFlags
+                    & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
+                scanFlags |= SCAN_AS_ODM;
+            }
         }
         if (pkgSetting != null) {
             final int userId = ((user == null) ? 0 : user.getIdentifier());
@@ -11167,6 +11221,10 @@
             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
         }
 
+        if ((scanFlags & SCAN_AS_ODM) != 0) {
+            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ODM;
+        }
+
         // Check if the package is signed with the same key as the platform package.
         if (PLATFORM_PACKAGE_NAME.equals(pkg.packageName) ||
                 (platformPkg != null && compareSignatures(
@@ -11493,17 +11551,44 @@
                                 " is static but not pre-installed.");
                     }
 
-                    // The only case where we allow installation of a non-system overlay is when
-                    // its signature is signed with the platform certificate.
-                    PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
-                    if ((platformPkgSetting.signatures.mSigningDetails
-                            != PackageParser.SigningDetails.UNKNOWN)
-                            && (compareSignatures(
-                                    platformPkgSetting.signatures.mSigningDetails.signatures,
-                                    pkg.mSigningDetails.signatures)
-                                            != PackageManager.SIGNATURE_MATCH)) {
-                        throw new PackageManagerException("Overlay " + pkg.packageName +
-                                " must be signed with the platform certificate.");
+                    // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
+                    // signed with the platform certificate. Check this in increasing order of
+                    // computational cost.
+                    if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q) {
+                        final PackageSetting platformPkgSetting =
+                                mSettings.getPackageLPr("android");
+                        if ((platformPkgSetting.signatures.mSigningDetails
+                                    != PackageParser.SigningDetails.UNKNOWN)
+                                && (compareSignatures(
+                                        platformPkgSetting.signatures.mSigningDetails.signatures,
+                                        pkg.mSigningDetails.signatures)
+                                    != PackageManager.SIGNATURE_MATCH)) {
+                            throw new PackageManagerException("Overlay " + pkg.packageName
+                                    + " must target Q or later, "
+                                    + "or be signed with the platform certificate");
+                        }
+                    }
+
+                    // A non-preloaded overlay package, without <overlay android:targetName>, will
+                    // only be used if it is signed with the same certificate as its target. If the
+                    // target is already installed, check this here to augment the last line of
+                    // defence which is OMS.
+                    if (pkg.mOverlayTargetName == null) {
+                        final PackageSetting targetPkgSetting =
+                                mSettings.getPackageLPr(pkg.mOverlayTarget);
+                        if (targetPkgSetting != null) {
+                            if ((targetPkgSetting.signatures.mSigningDetails
+                                        != PackageParser.SigningDetails.UNKNOWN)
+                                    && (compareSignatures(
+                                            targetPkgSetting.signatures.mSigningDetails.signatures,
+                                            pkg.mSigningDetails.signatures)
+                                        != PackageManager.SIGNATURE_MATCH)) {
+                                throw new PackageManagerException("Overlay " + pkg.packageName
+                                        + " and target " + pkg.mOverlayTarget + " signed with"
+                                        + " different certificates, and the overlay lacks"
+                                        + " <overlay android:targetName>");
+                            }
+                        }
                     }
                 }
             }
@@ -11632,19 +11717,19 @@
                 for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
                     commitSharedLibraryInfoLocked(info);
                 }
+                final Map<String, PackageParser.Package> combinedPackages =
+                        reconciledPkg.getCombinedPackages();
                 try {
                     // Shared libraries for the package need to be updated.
-                    updateSharedLibrariesLPr(pkg, null);
+                    updateSharedLibrariesLocked(pkg, null, combinedPackages);
                 } catch (PackageManagerException e) {
                     Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
                 }
-            }
-
-            if (reconciledPkg.hasDynamicSharedLibraries() && (scanFlags & SCAN_BOOTING) == 0) {
-                // If we are not booting, we need to update any applications
-                // that are clients of our shared library.  If we are booting,
-                // this will all be done once the scan is complete.
-                clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
+                // Update all applications that use this library. Skip when booting
+                // since this will be done after all packages are scaned.
+                if ((scanFlags & SCAN_BOOTING) == 0) {
+                    clientLibPkgs = updateAllSharedLibrariesLocked(pkg, combinedPackages);
+                }
             }
         }
 
@@ -12089,6 +12174,8 @@
             codeRoot = Environment.getProductDirectory();
         } else if (FileUtils.contains(Environment.getProductServicesDirectory(), codePath)) {
             codeRoot = Environment.getProductServicesDirectory();
+        } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
+            codeRoot = Environment.getOdmDirectory();
         } else {
             // Unrecognized code path; take its top real segment as the apk root:
             // e.g. /something/app/blah.apk => /something
@@ -14810,7 +14897,6 @@
                         }
                     }
 
-                    // TODO(ruhler) b/112431924: What user? Test for multi-user.
                     Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
                     enableRollbackIntent.putExtra(
                             PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
@@ -14832,7 +14918,7 @@
                     // it will not miss the broadcast.
                     enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
 
-                    mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, getUser(),
+                    mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, UserHandle.SYSTEM,
                             android.Manifest.permission.PACKAGE_ROLLBACK_AGENT,
                             new BroadcastReceiver() {
                                 @Override
@@ -15733,6 +15819,7 @@
      * TODO: move most of the data contained her into a PackageSetting for commit.
      */
     private static class ReconciledPackage {
+        public final ReconcileRequest request;
         public final PackageSetting pkgSetting;
         public final ScanResult scanResult;
         // TODO: Remove install-specific details from the reconcile result
@@ -15746,14 +15833,18 @@
         public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos;
         public final boolean removeAppKeySetData;
 
-        private ReconciledPackage(InstallArgs installArgs, PackageSetting pkgSetting,
+        private ReconciledPackage(ReconcileRequest request,
+                InstallArgs installArgs,
+                PackageSetting pkgSetting,
                 PackageInstalledInfo installResult,
-                PrepareResult prepareResult, ScanResult scanResult,
+                PrepareResult prepareResult,
+                ScanResult scanResult,
                 DeletePackageAction deletePackageAction,
                 List<SharedLibraryInfo> allowedSharedLibraryInfos,
                 SigningDetails signingDetails,
                 boolean sharedUserSignaturesChanged,
                 boolean removeAppKeySetData) {
+            this.request = request;
             this.installArgs = installArgs;
             this.pkgSetting = pkgSetting;
             this.installResult = installResult;
@@ -15766,9 +15857,20 @@
             this.removeAppKeySetData = removeAppKeySetData;
         }
 
-        public boolean hasDynamicSharedLibraries() {
-            return !ArrayUtils.isEmpty(allowedSharedLibraryInfos)
-                    && allowedSharedLibraryInfos.get(0).getType() != SharedLibraryInfo.TYPE_STATIC;
+        /**
+         * Returns a combined set of packages containing the packages already installed combined
+         * with the package(s) currently being installed. The to-be installed packages take
+         * precedence and may shadow already installed packages.
+         */
+        private Map<String, PackageParser.Package> getCombinedPackages() {
+            final ArrayMap<String, PackageParser.Package> combinedPackages =
+                    new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size());
+
+            combinedPackages.putAll(request.allPackages);
+            for (ScanResult scanResult : request.scannedPackages.values()) {
+                combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.pkg);
+            }
+            return combinedPackages;
         }
     }
 
@@ -15958,7 +16060,7 @@
             }
 
             result.put(installPackageName,
-                    new ReconciledPackage(installArgs, scanResult.pkgSetting,
+                    new ReconciledPackage(request, installArgs, scanResult.pkgSetting,
                             res, request.preparedPackages.get(installPackageName), scanResult,
                             deletePackageAction, allowedSharedLibInfos, signingDetails,
                             sharedUserSignaturesChanged, removeAppKeySetData));
@@ -16326,7 +16428,6 @@
                                         sharedLibLatestVersionSetting);
                             }
                         }
-                        prepareScanResultLocked(result);
                     }
                 } catch (PackageManagerException e) {
                     request.installResult.setError("Scanning Failed.", e);
@@ -17162,13 +17263,15 @@
                     final boolean oem = isOemApp(oldPackage);
                     final boolean vendor = isVendorApp(oldPackage);
                     final boolean product = isProductApp(oldPackage);
+                    final boolean odm = isOdmApp(oldPackage);
                     final @ParseFlags int systemParseFlags = parseFlags;
                     final @ScanFlags int systemScanFlags = scanFlags
                             | SCAN_AS_SYSTEM
                             | (privileged ? SCAN_AS_PRIVILEGED : 0)
                             | (oem ? SCAN_AS_OEM : 0)
                             | (vendor ? SCAN_AS_VENDOR : 0)
-                            | (product ? SCAN_AS_PRODUCT : 0);
+                            | (product ? SCAN_AS_PRODUCT : 0)
+                            | (odm ? SCAN_AS_ODM : 0);
 
                     if (DEBUG_INSTALL) {
                         Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
@@ -17499,6 +17602,10 @@
                 & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
     }
 
+    private static boolean isOdmApp(PackageParser.Package pkg) {
+        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0;
+    }
+
     private static boolean hasDomainURLs(PackageParser.Package pkg) {
         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
     }
@@ -17789,6 +17896,12 @@
     @Override
     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
         final int callingUid = Binder.getCallingUid();
+        if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
+                != PERMISSION_GRANTED) {
+            EventLog.writeEvent(0x534e4554, "128599183", -1, "");
+            throw new SecurityException(android.Manifest.permission.MANAGE_USERS
+                    + " permission is required to call this API");
+        }
         if (getInstantAppPackageName(callingUid) != null
                 && !isCallerSameApp(packageName, callingUid)) {
             return false;
@@ -18267,6 +18380,15 @@
         return false;
     }
 
+    static boolean locationIsOdm(String path) {
+        try {
+            return path.startsWith(Environment.getOdmDirectory().getCanonicalPath() + "/");
+        } catch (IOException e) {
+            Slog.e(TAG, "Unable to access code path " + path);
+        }
+        return false;
+    }
+
     /*
      * Tries to delete system package.
      */
@@ -18380,6 +18502,9 @@
         if (locationIsProductServices(codePathString)) {
             scanFlags |= SCAN_AS_PRODUCT_SERVICES;
         }
+        if (locationIsOdm(codePathString)) {
+            scanFlags |= SCAN_AS_ODM;
+        }
 
         final File codePath = new File(codePathString);
         final PackageParser.Package pkg =
@@ -18387,7 +18512,7 @@
 
         try {
             // update shared libraries for the newly re-installed system package
-            updateSharedLibrariesLPr(pkg, null);
+            updateSharedLibrariesLocked(pkg, null, Collections.unmodifiableMap(mPackages));
         } catch (PackageManagerException e) {
             Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
         }
@@ -20010,8 +20135,12 @@
      */
     public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo,
             int userId) {
+        if (TextUtils.isEmpty(sessionInfo.installerPackageName)) {
+            return;
+        }
         Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED)
-                .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo);
+                .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
+                .setPackage(sessionInfo.installerPackageName);
         mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId));
     }
 
@@ -20207,6 +20336,11 @@
         return mContext.getString(R.string.config_defaultTextClassifierPackage);
     }
 
+    @Override
+    public String getAttentionServicePackageName() {
+        return mContext.getString(R.string.config_defaultAttentionService);
+    }
+
     private @Nullable String getDocumenterPackageName() {
         final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
         intent.addCategory(Intent.CATEGORY_OPENABLE);
@@ -20457,7 +20591,7 @@
                         prepareAppDataAfterInstallLIF(pkg);
                         synchronized (mPackages) {
                             try {
-                                updateSharedLibrariesLPr(pkg, null);
+                                updateSharedLibrariesLocked(pkg, null, mPackages);
                             } catch (PackageManagerException e) {
                                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
                             }
@@ -20582,8 +20716,14 @@
                     mPendingBroadcasts.put(userId, packageName, components);
                 }
                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
-                    // Schedule a message
-                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
+                    // Schedule a message - if it has been a "reasonably long time" since the
+                    // service started, send the broadcast with a delay of one second to avoid
+                    // delayed reactions from the receiver, else keep the default ten second delay
+                    // to avoid extreme thrashing on service startup.
+                    final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
+                                                ? BROADCAST_DELAY
+                                                : BROADCAST_DELAY_DURING_STARTUP;
+                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
                 }
             }
         }
@@ -22462,6 +22602,7 @@
         final int targetSdkVersion;
         final PackageFreezer freezer;
         final int[] installedUserIds;
+        final boolean isCurrentLocationExternal;
 
         // reader
         synchronized (mPackages) {
@@ -22508,6 +22649,7 @@
                         "Failed to move already frozen package");
             }
 
+            isCurrentLocationExternal = isExternal(pkg);
             codeFile = new File(pkg.codePath);
             installerPackageName = ps.installerPackageName;
             packageAbiOverride = ps.cpuAbiOverrideString;
@@ -22610,6 +22752,7 @@
                     case PackageInstaller.STATUS_SUCCESS:
                         mMoveCallbacks.notifyStatusChanged(moveId,
                                 PackageManager.MOVE_SUCCEEDED);
+                        logAppMovedStorage(packageName, isCurrentLocationExternal);
                         break;
                     case PackageInstaller.STATUS_FAILURE_STORAGE:
                         mMoveCallbacks.notifyStatusChanged(moveId,
@@ -22668,6 +22811,36 @@
         mHandler.sendMessage(msg);
     }
 
+    /**
+     * Logs that an app has been moved from internal to external storage and vice versa.
+     * @param packageName The package that was moved.
+     */
+    private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) {
+        final PackageParser.Package pkg;
+        synchronized (mPackages) {
+            pkg = mPackages.get(packageName);
+        }
+        if (pkg == null) {
+            return;
+        }
+
+        final StorageManager storage = mContext.getSystemService(StorageManager.class);
+        VolumeInfo volume = storage.findVolumeByUuid(pkg.applicationInfo.storageUuid.toString());
+        int packageExternalStorageType = getPackageExternalStorageType(volume, isExternal(pkg));
+
+        if (!isPreviousLocationExternal && isExternal(pkg)) {
+            // Move from internal to external storage.
+            StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType,
+                    StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
+                    packageName);
+        } else if (isPreviousLocationExternal && !isExternal(pkg)) {
+            // Move from external to internal storage.
+            StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType,
+                    StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
+                    packageName);
+        }
+    }
+
     @Override
     public int movePrimaryStorage(String volumeUuid) throws RemoteException {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
@@ -23262,6 +23435,23 @@
             }
             return results;
         }
+
+        @Override
+        public int getLocationFlags(String packageName) throws RemoteException {
+            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
+            ApplicationInfo appInfo = getApplicationInfo(packageName,
+                    /*flags*/ 0,
+                    /*userId*/ callingUser);
+            if (appInfo == null) {
+                throw new RemoteException(
+                        "Couldn't get ApplicationInfo for package " + packageName);
+            }
+            return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
+                    | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
+                    | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0)
+                    | (appInfo.isProductServices()
+                            ? IPackageManagerNative.LOCATION_PRODUCT_SERVICES : 0));
+        }
     }
 
     private class PackageManagerInternalImpl extends PackageManagerInternal {
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 2c2cc7e..ead09b4 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -152,6 +152,10 @@
         return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
     }
 
+    public boolean isOdm() {
+        return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0;
+    }
+
     public boolean isSystem() {
         return (pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
     }
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index fbf5439..a24818f 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -64,6 +64,7 @@
                 | ApplicationInfo.PRIVATE_FLAG_VENDOR
                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT
                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
-                | ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER);
+                | ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER
+                | ApplicationInfo.PRIVATE_FLAG_ODM);
     }
 }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 459de1a..4f81fd9 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -32,6 +32,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -59,6 +60,7 @@
 import android.os.PatternMatcher;
 import android.os.PersistableBundle;
 import android.os.Process;
+import android.os.SELinux;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -775,7 +777,8 @@
                 | ApplicationInfo.PRIVATE_FLAG_OEM
                 | ApplicationInfo.PRIVATE_FLAG_VENDOR
                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT
-                | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES);
+                | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
+                | ApplicationInfo.PRIVATE_FLAG_ODM);
         pkgSetting.pkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
@@ -787,6 +790,8 @@
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT;
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
+        pkgSetting.pkgPrivateFlags |=
+                pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM;
         pkgSetting.primaryCpuAbiString = primaryCpuAbi;
         pkgSetting.secondaryCpuAbiString = secondaryCpuAbi;
         if (childPkgNames != null) {
@@ -916,13 +921,13 @@
     }
 
     /*
-     * Update the shared user setting when a package using
-     * specifying the shared user id is removed. The gids
-     * associated with each permission of the deleted package
-     * are removed from the shared user's gid list only if its
-     * not in use by other permissions of packages in the
-     * shared user setting.
+     * Update the shared user setting when a package with a shared user id is removed. The gids
+     * associated with each permission of the deleted package are removed from the shared user'
+     * gid list only if its not in use by other permissions of packages in the shared user setting.
+     *
+     * @return the affected user id
      */
+    @UserIdInt
     int updateSharedUserPermsLPw(PackageSetting deletedPs, int userId) {
         if ((deletedPs == null) || (deletedPs.pkg == null)) {
             Slog.i(PackageManagerService.TAG,
@@ -937,6 +942,7 @@
 
         SharedUserSetting sus = deletedPs.sharedUser;
 
+        int affectedUserId = UserHandle.USER_NULL;
         // Update permissions
         for (String eachPerm : deletedPs.pkg.requestedPermissions) {
             BasePermission bp = mPermissions.getPermission(eachPerm);
@@ -983,17 +989,22 @@
 
             if (permissionsState.revokeInstallPermission(bp) ==
                     PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
-                return UserHandle.USER_ALL;
+                affectedUserId = UserHandle.USER_ALL;
             }
 
             // Try to revoke as an install permission which is per user.
             if (permissionsState.revokeRuntimePermission(bp, userId) ==
                     PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
-                return userId;
+                if (affectedUserId == UserHandle.USER_NULL) {
+                    affectedUserId = userId;
+                } else if (affectedUserId != userId) {
+                    // Multiple users affected.
+                    affectedUserId = UserHandle.USER_ALL;
+                }
             }
         }
 
-        return UserHandle.USER_NULL;
+        return affectedUserId;
     }
 
     int removePackageLPw(String name) {
@@ -2643,6 +2654,24 @@
     }
 
     void writePackageListLPr(int creatingUserId) {
+        String filename = mPackageListFilename.getAbsolutePath();
+        String ctx = SELinux.fileSelabelLookup(filename);
+        if (ctx == null) {
+            Slog.wtf(TAG, "Failed to get SELinux context for " +
+                mPackageListFilename.getAbsolutePath());
+        }
+
+        if (!SELinux.setFSCreateContext(ctx)) {
+            Slog.wtf(TAG, "Failed to set packages.list SELinux context");
+        }
+        try {
+            writePackageListLPrInternal(creatingUserId);
+        } finally {
+            SELinux.setFSCreateContext(null);
+        }
+    }
+
+    private void writePackageListLPrInternal(int creatingUserId) {
         // Only derive GIDs for active users (not dying)
         final List<UserInfo> users = UserManagerService.getInstance().getUsers(true);
         int[] userIds = new int[users.size()];
@@ -4376,6 +4405,7 @@
             ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION",
             ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE, "PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE",
             ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE, "ALLOW_AUDIO_PLAYBACK_CAPTURE",
+            ApplicationInfo.PRIVATE_FLAG_ALLOW_EXTERNAL_STORAGE_SANDBOX, "ALLOW_EXTERNAL_STORAGE_SANDBOX",
             ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND, "BACKUP_IN_FOREGROUND",
             ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
             ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE",
@@ -4393,6 +4423,7 @@
             ApplicationInfo.PRIVATE_FLAG_PRODUCT, "PRODUCT",
             ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES, "PRODUCT_SERVICES",
             ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
+            ApplicationInfo.PRIVATE_FLAG_ODM, "ODM",
     };
 
     void dumpVersionLPr(IndentingPrintWriter pw) {
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 39c731c..a0f0a31 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -44,11 +44,13 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.storage.IStorageManager;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.apk.ApkSignatureVerifier;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.content.PackageHelper;
 import com.android.internal.os.BackgroundThread;
 
 import java.io.File;
@@ -253,6 +255,21 @@
             }
         }
 
+        // Make sure we start a filesystem checkpoint on the next boot.
+        try {
+            IStorageManager storageManager = PackageHelper.getStorageManager();
+            if (storageManager.supportsCheckpoint()) {
+                storageManager.startCheckpoint(1 /* numRetries */);
+            }
+        } catch (RemoteException e) {
+            // While StorageManager lives in the same process, the native implementation
+            // it calls through lives in 'vold'; so, this call can fail if 'vold' isn't
+            // reachable.
+            // Since we can live without filesystem checkpointing, just warn in this case
+            // and continue.
+            Slog.w(TAG, "Could not start filesystem checkpoint.");
+        }
+
         session.setStagedSessionReady();
         if (sessionContainsApex(session)
                 && !mApexManager.markStagedSessionReady(session.sessionId)) {
@@ -367,8 +384,10 @@
         PackageInstaller.SessionParams params = originalSession.params.copy();
         params.isStaged = false;
         params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
+        // TODO(b/129744602): use the userid from the original session.
         int apkSessionId = mPi.createSession(
-                params, originalSession.getInstallerPackageName(), originalSession.userId);
+                params, originalSession.getInstallerPackageName(),
+                0 /* UserHandle.SYSTEM */);
         PackageInstallerSession apkSession = mPi.getSession(apkSessionId);
 
         try {
@@ -448,8 +467,10 @@
             }
             PackageInstaller.SessionParams params = session.params.copy();
             params.isStaged = false;
+            // TODO(b/129744602): use the userid from the original session.
             int apkParentSessionId = mPi.createSession(
-                    params, session.getInstallerPackageName(), session.userId);
+                    params, session.getInstallerPackageName(),
+                    0 /* UserHandle.SYSTEM */);
             PackageInstallerSession apkParentSession = mPi.getSession(apkParentSessionId);
             try {
                 apkParentSession.open();
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 316a9c0..204f186 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3372,15 +3372,15 @@
     @Override
     public int getUserSerialNumber(int userHandle) {
         synchronized (mUsersLock) {
-            if (!exists(userHandle)) return -1;
-            return getUserInfoLU(userHandle).serialNumber;
+            final UserInfo userInfo = getUserInfoLU(userHandle);
+            return userInfo != null ? userInfo.serialNumber : -1;
         }
     }
 
     @Override
     public boolean isUserNameSet(int userHandle) {
         synchronized (mUsersLock) {
-            UserInfo userInfo = getUserInfoLU(userHandle);
+            final UserInfo userInfo = getUserInfoLU(userHandle);
             return userInfo != null && userInfo.name != null;
         }
     }
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 0a17e130..5c386b4 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -186,41 +186,10 @@
         SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS);
     }
 
-    @Deprecated
     private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>();
     static {
-        // STOPSHIP(b/112545973): remove once feature enabled by default
-        if (!StorageManager.hasIsolatedStorage()) {
-            STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
-            STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
-        }
-    }
-
-    private static final Set<String> MEDIA_AURAL_PERMISSIONS = new ArraySet<>();
-    static {
-        // STOPSHIP(b/112545973): remove once feature enabled by default
-        if (StorageManager.hasIsolatedStorage()) {
-            MEDIA_AURAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_AUDIO);
-
-            // STOPSHIP(b/124466734): remove these manual grants once the legacy
-            // permission logic is unified with PermissionController
-            MEDIA_AURAL_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
-            MEDIA_AURAL_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
-        }
-    }
-
-    private static final Set<String> MEDIA_VISUAL_PERMISSIONS = new ArraySet<>();
-    static {
-        // STOPSHIP(b/112545973): remove once feature enabled by default
-        if (StorageManager.hasIsolatedStorage()) {
-            MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VIDEO);
-            MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_MEDIA_IMAGES);
-
-            // STOPSHIP(b/124466734): remove these manual grants once the legacy
-            // permission logic is unified with PermissionController
-            MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
-            MEDIA_VISUAL_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
-        }
+        STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+        STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
     }
 
     private static final int MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS = 1;
@@ -477,8 +446,7 @@
         // Media provider
         grantSystemFixedPermissionsToSystemPackage(
                 getDefaultProviderAuthorityPackage(MediaStore.AUTHORITY, userId), userId,
-                STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS, MEDIA_VISUAL_PERMISSIONS,
-                PHONE_PERMISSIONS);
+                STORAGE_PERMISSIONS, PHONE_PERMISSIONS);
 
         // Downloads provider
         grantSystemFixedPermissionsToSystemPackage(
@@ -600,7 +568,7 @@
         grantPermissionsToSystemPackage(
                 getDefaultSystemHandlerActivityPackageForCategory(
                         Intent.CATEGORY_APP_GALLERY, userId),
-                userId, STORAGE_PERMISSIONS, MEDIA_VISUAL_PERMISSIONS);
+                userId, STORAGE_PERMISSIONS);
 
         // Email
         grantPermissionsToSystemPackage(
@@ -650,7 +618,7 @@
                 grantPermissionsToSystemPackage(packageName, userId,
                         CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS, MICROPHONE_PERMISSIONS,
                         PHONE_PERMISSIONS, SMS_PERMISSIONS, CAMERA_PERMISSIONS,
-                        SENSORS_PERMISSIONS, STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS);
+                        SENSORS_PERMISSIONS, STORAGE_PERMISSIONS);
                 grantSystemFixedPermissionsToSystemPackage(packageName, userId,
                         ALWAYS_LOCATION_PERMISSIONS, ACTIVITY_RECOGNITION_PERMISSIONS);
             }
@@ -668,7 +636,7 @@
                 .setDataAndType(Uri.fromFile(new File("foo.mp3")), AUDIO_MIME_TYPE);
         grantPermissionsToSystemPackage(
                 getDefaultSystemHandlerActivityPackage(musicIntent, userId), userId,
-                STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS);
+                STORAGE_PERMISSIONS);
 
         // Home
         Intent homeIntent = new Intent(Intent.ACTION_MAIN)
@@ -732,7 +700,7 @@
         grantSystemFixedPermissionsToSystemPackage(
                 getDefaultSystemHandlerActivityPackage(
                         RingtoneManager.ACTION_RINGTONE_PICKER, userId),
-                userId, STORAGE_PERMISSIONS, MEDIA_AURAL_PERMISSIONS);
+                userId, STORAGE_PERMISSIONS);
 
         // TextClassifier Service
         String textClassifierPackageName =
@@ -743,6 +711,14 @@
                     LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS);
         }
 
+        // Atthention Service
+        String attentionServicePackageName =
+                mContext.getPackageManager().getAttentionServicePackageName();
+        if (!TextUtils.isEmpty(attentionServicePackageName)) {
+            grantPermissionsToSystemPackage(attentionServicePackageName, userId,
+                    CAMERA_PERMISSIONS);
+        }
+
         // There is no real "marker" interface to identify the shared storage backup, it is
         // hardcoded in BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE.
         grantSystemFixedPermissionsToSystemPackage("com.android.sharedstoragebackup", userId,
@@ -1092,6 +1068,8 @@
     private void grantRuntimePermissions(PackageInfo pkg,
             Set<String> permissionsWithoutSplits, boolean systemFixed, boolean ignoreSystemPackage,
             int userId) {
+        UserHandle user = UserHandle.of(userId);
+
         if (pkg == null) {
             return;
         }
@@ -1112,7 +1090,14 @@
         }
         requestedPermissions = ArrayUtils.filterNotNull(requestedPermissions, String[]::new);
 
-        PackageManager pm = mContext.getPackageManager();
+        PackageManager pm;
+        try {
+            pm = mContext.createPackageContextAsUser(mContext.getPackageName(), 0,
+                    user).getPackageManager();
+        } catch (NameNotFoundException doesNotHappen) {
+            throw new IllegalStateException(doesNotHappen);
+        }
+
         final ArraySet<String> permissions = new ArraySet<>(permissionsWithoutSplits);
         ApplicationInfo applicationInfo = pkg.applicationInfo;
 
@@ -1190,7 +1175,6 @@
             }
 
             if (permissions.contains(permission)) {
-                UserHandle user = UserHandle.of(userId);
                 final int flags = mContext.getPackageManager().getPermissionFlags(
                         permission, pkg.packageName, user);
 
@@ -1213,8 +1197,11 @@
                             UserHandle.getAppId(pkg.applicationInfo.uid));
                     String op = AppOpsManager.permissionToOp(permission);
 
-                    mContext.getPackageManager()
-                            .grantRuntimePermission(pkg.packageName, permission, user);
+                    if (pm.checkPermission(permission, pkg.packageName)
+                            != PackageManager.PERMISSION_GRANTED) {
+                        mContext.getPackageManager()
+                                .grantRuntimePermission(pkg.packageName, permission, user);
+                    }
 
                     mContext.getPackageManager().updatePermissionFlags(permission, pkg.packageName,
                             newFlags, newFlags, user);
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 3029f51..86a3994 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -17,20 +17,14 @@
 package com.android.server.pm.permission;
 
 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
-import static android.Manifest.permission.READ_MEDIA_AUDIO;
-import static android.Manifest.permission.READ_MEDIA_IMAGES;
-import static android.Manifest.permission.READ_MEDIA_VIDEO;
 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_ERRORED;
 import static android.app.AppOpsManager.MODE_FOREGROUND;
-import static android.app.AppOpsManager.MODE_IGNORED;
-import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
 import static android.app.AppOpsManager.OP_NONE;
 import static android.app.AppOpsManager.permissionToOp;
 import static android.app.AppOpsManager.permissionToOpCode;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
-import static android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
@@ -1155,8 +1149,6 @@
                     updatedUserIds);
             updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
                     permissionsState, pkg, updatedUserIds);
-            updatedUserIds = applyLegacyStoragePermissionModel(origPermissions, permissionsState,
-                    pkg, updatedUserIds);
 
             setAppOpsLocked(permissionsState, pkg);
         }
@@ -1476,184 +1468,6 @@
     }
 
     /**
-     * Pre-Q apps use READ/WRITE_EXTERNAL_STORAGE, post-Q apps use READ_MEDIA_AUDIO/VIDEO/IMAGES.
-     *
-     * <p>There is the special case of the grandfathered post-Q app that has all legacy and modern
-     * permissions system-fixed granted. The only way to remove these permissions is to uninstall
-     * the app.
-     *
-     * @param origPs The permission state of the package before the update
-     * @param ps The permissions state of the package
-     * @param pkg The package
-     * @param updatedUserIds The userIds we have already been updated before
-     *
-     * @return The userIds that have been updated
-     *
-     * @see com.android.server.StorageManagerService#applyLegacyStorage()
-     */
-    private @NonNull int[] applyLegacyStoragePermissionModel(@NonNull PermissionsState origPs,
-            @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
-            @NonNull int[] updatedUserIds) {
-        AppOpsManagerInternal appOpsManager = LocalServices.getService(AppOpsManagerInternal.class);
-        int[] users = UserManagerService.getInstance().getUserIds();
-
-        boolean isQApp = pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q;
-        boolean isPreMApp = pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M;
-        int appId = getAppId(pkg.applicationInfo.uid);
-
-        int numRequestedPerms = pkg.requestedPermissions.size();
-        for (int i = 0; i < numRequestedPerms; i++) {
-            String perm = pkg.requestedPermissions.get(i);
-
-            boolean isLegacyStoragePermission = false;
-            boolean isModernStoragePermission = false;
-            switch (perm) {
-                case READ_EXTERNAL_STORAGE:
-                case WRITE_EXTERNAL_STORAGE:
-                    isLegacyStoragePermission = true;
-                    break;
-                case READ_MEDIA_AUDIO:
-                case READ_MEDIA_VIDEO:
-                case READ_MEDIA_IMAGES:
-                    isModernStoragePermission = true;
-                    break;
-                default:
-                    // 'perm' is not a storage permission, skip it
-                    continue;
-            }
-
-            BasePermission bp = mSettings.getPermissionLocked(perm);
-
-            for (int userId : users) {
-                boolean useLegacyStoragePermissionModel;
-                if (isQApp) {
-                    useLegacyStoragePermissionModel = appOpsManager.checkOperationUnchecked(
-                            OP_LEGACY_STORAGE, getUid(userId, appId), pkg.packageName)
-                            == MODE_ALLOWED;
-                } else {
-                    useLegacyStoragePermissionModel = true;
-                }
-
-                int origCombinedLegacyFlags =
-                        origPs.getPermissionFlags(READ_EXTERNAL_STORAGE, userId)
-                        | origPs.getPermissionFlags(WRITE_EXTERNAL_STORAGE, userId);
-
-                int origCombinedModernFlags = origPs.getPermissionFlags(READ_MEDIA_AUDIO, userId)
-                        | origPs.getPermissionFlags(READ_MEDIA_VIDEO, userId)
-                        | origPs.getPermissionFlags(READ_MEDIA_IMAGES, userId);
-
-                boolean oldPermAreLegacyStorageModel =
-                        (origCombinedLegacyFlags & FLAG_PERMISSION_HIDDEN) == 0;
-                boolean oldPermAreModernStorageModel =
-                        (origCombinedModernFlags & FLAG_PERMISSION_HIDDEN) == 0;
-
-                if (oldPermAreLegacyStorageModel && oldPermAreModernStorageModel) {
-                    // This only happens after an platform upgrade from before Q
-                    oldPermAreModernStorageModel = false;
-                }
-
-                boolean shouldBeHidden;
-                boolean shouldBeFixed;
-                boolean shouldBeGranted = false;
-                boolean shouldBeRevoked = false;
-                int userFlags = -1;
-                if (useLegacyStoragePermissionModel) {
-                    shouldBeHidden = isModernStoragePermission;
-                    shouldBeFixed = isQApp || isModernStoragePermission;
-
-                    if (shouldBeFixed) {
-                        userFlags = 0;
-                        shouldBeGranted = true;
-                        shouldBeRevoked = false;
-                    } else if (oldPermAreModernStorageModel) {
-                        // Inherit grant state on permission model change
-                        userFlags = origCombinedModernFlags;
-
-                        shouldBeGranted = origPs.hasRuntimePermission(READ_MEDIA_AUDIO, userId)
-                                || origPs.hasRuntimePermission(READ_MEDIA_VIDEO, userId)
-                                || origPs.hasRuntimePermission(READ_MEDIA_IMAGES, userId);
-
-                        shouldBeRevoked = !shouldBeGranted;
-                    }
-                } else {
-                    shouldBeHidden = isLegacyStoragePermission;
-                    shouldBeFixed = isLegacyStoragePermission;
-
-                    if (shouldBeFixed) {
-                        userFlags = 0;
-                        shouldBeGranted = true;
-                        shouldBeRevoked = false;
-                    } else if (oldPermAreLegacyStorageModel) {
-                        // Inherit grant state on permission model change
-                        userFlags = origCombinedLegacyFlags;
-
-                        shouldBeGranted = origPs.hasRuntimePermission(READ_EXTERNAL_STORAGE, userId)
-                                || origPs.hasRuntimePermission(WRITE_EXTERNAL_STORAGE, userId);
-
-                        if ((origCombinedLegacyFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0
-                                && !isPreMApp) {
-                            shouldBeGranted = false;
-                        }
-
-                        shouldBeRevoked = !shouldBeGranted;
-                    }
-                }
-
-                // Granted permissions can never be user fixed
-                if (shouldBeGranted & userFlags != -1) {
-                    userFlags &= ~FLAG_PERMISSION_USER_FIXED;
-                }
-
-                boolean changed = false;
-                synchronized (mLock) {
-                    if (shouldBeGranted) {
-                        if (isPreMApp) {
-                            setAppOpMode(perm, pkg, userId, MODE_ALLOWED);
-                        } else if (!ps.hasRuntimePermission(perm, userId)) {
-                            ps.grantRuntimePermission(bp, userId);
-                            changed = true;
-                        }
-                    }
-
-                    if (shouldBeRevoked) {
-                        if (isPreMApp) {
-                            setAppOpMode(perm, pkg, userId, MODE_IGNORED);
-                        } else if (ps.hasRuntimePermission(perm, userId)) {
-                            ps.revokeRuntimePermission(bp, userId);
-                            changed = true;
-                        }
-                    }
-
-                    if (shouldBeFixed) {
-                        changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm),
-                                userId, FLAG_PERMISSION_SYSTEM_FIXED, FLAG_PERMISSION_SYSTEM_FIXED);
-                    }
-
-                    if (userFlags != -1) {
-                        changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm),
-                                userId, USER_PERMISSION_FLAGS, userFlags);
-                    }
-
-                    changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), userId,
-                            FLAG_PERMISSION_HIDDEN,
-                            shouldBeHidden ? FLAG_PERMISSION_HIDDEN : 0);
-
-                    if (shouldBeHidden) {
-                        changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm),
-                                userId, FLAG_PERMISSION_REVIEW_REQUIRED, 0);
-                    }
-                }
-
-                if (changed) {
-                    updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
-                }
-            }
-        }
-
-        return updatedUserIds;
-    }
-
-    /**
      * Fix app-op modes for runtime permissions.
      *
      * @param permsState The state of the permissions of the package
diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
index c610ed0..2280d3f 100644
--- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
@@ -19,9 +19,6 @@
                 },
                 {
                     "include-filter": "android.permission.cts.PermissionFlagsTest"
-                },
-                {
-                    "include-filter": "android.permission.cts.DualStoragePermissionModelTest"
                 }
             ]
         },
diff --git a/services/core/java/com/android/server/policy/EventLogTags.logtags b/services/core/java/com/android/server/policy/EventLogTags.logtags
new file mode 100644
index 0000000..7563382
--- /dev/null
+++ b/services/core/java/com/android/server/policy/EventLogTags.logtags
@@ -0,0 +1,8 @@
+# See system/core/logcat/event.logtags for a description of the format of this file.
+
+option java_package com.android.server.policy
+
+
+# 0 for screen off, 1 for screen on
+70000 screen_toggled (screen_state|1|5)
+70001 intercept_power (action|3),(mPowerKeyHandled|1),(mPowerKeyPressCounter|1)
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 55af357..0e0fc12 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -167,7 +167,6 @@
 import android.service.vr.IPersistentVrStateCallbacks;
 import android.speech.RecognizerIntent;
 import android.telecom.TelecomManager;
-import android.util.EventLog;
 import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.MutableBoolean;
@@ -207,7 +206,6 @@
 import com.android.internal.policy.PhoneWindow;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.ScreenshotHelper;
 import com.android.server.ExtconStateObserver;
 import com.android.server.ExtconUEventObserver;
 import com.android.server.GestureLauncherService;
@@ -378,7 +376,6 @@
     BurnInProtectionHelper mBurnInProtectionHelper;
     private DisplayFoldController mDisplayFoldController;
     AppOpsManager mAppOpsManager;
-    private ScreenshotHelper mScreenshotHelper;
     private boolean mHasFeatureWatch;
     private boolean mHasFeatureLeanback;
     private boolean mHasFeatureHdmiCec;
@@ -1602,7 +1599,8 @@
                     return -1;
                 }
 
-                handleShortPressOnHome(mDisplayId);
+                // Post to main thread to avoid blocking input pipeline.
+                mHandler.post(() -> handleShortPressOnHome(mDisplayId));
                 return -1;
             }
 
@@ -1639,7 +1637,8 @@
                 }
             } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                 if (!keyguardOn) {
-                    handleLongPressOnHome(event.getDeviceId());
+                    // Post to main thread to avoid blocking input pipeline.
+                    mHandler.post(() -> handleLongPressOnHome(event.getDeviceId()));
                 }
             }
             return -1;
@@ -1924,7 +1923,6 @@
                         mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged();
                     }
                 });
-        mScreenshotHelper = new ScreenshotHelper(mContext);
     }
 
     /**
@@ -2227,6 +2225,11 @@
 
     @Override
     public boolean canBeHiddenByKeyguardLw(WindowState win) {
+
+        // Keyguard visibility of window from activities are determined over activity visibility.
+        if (win.getAppToken() != null) {
+            return false;
+        }
         switch (win.getAttrs().type) {
             case TYPE_STATUS_BAR:
             case TYPE_NAVIGATION_BAR:
@@ -2240,19 +2243,30 @@
     }
 
     private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) {
+        final LayoutParams attrs = win.getAttrs();
 
-        // Keyguard visibility of window from activities are determined over activity visibility.
-        if (win.getAppToken() != null) {
-            return false;
+        boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER
+                && !mWindowManagerInternal.isStackVisibleLw(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+        if (hideDockDivider) {
+            return true;
         }
 
-        final LayoutParams attrs = win.getAttrs();
+        // If AOD is showing, the IME should be hidden. However, sometimes the AOD is considered
+        // hidden because it's in the process of hiding, but it's still being shown on screen.
+        // In that case, we want to continue hiding the IME until the windows have completed
+        // drawing. This way, we know that the IME can be safely shown since the other windows are
+        // now shown.
+        final boolean hideIme = win.isInputMethodWindow()
+                && (mAodShowing || !mDefaultDisplayPolicy.isWindowManagerDrawComplete());
+        if (hideIme) {
+            return true;
+        }
+
         final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleLw()
                 && (imeTarget.canShowWhenLocked() || !canBeHiddenByKeyguardLw(imeTarget));
 
         // Show IME over the keyguard if the target allows it
-        boolean allowWhenLocked = (win.isInputMethodWindow() || imeTarget == this)
-                && showImeOverKeyguard;
+        boolean allowWhenLocked = win.isInputMethodWindow() && showImeOverKeyguard;
 
         final boolean isKeyguardShowing = mKeyguardDelegate.isShowing();
 
@@ -2263,17 +2277,7 @@
                     || (attrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0;
         }
 
-        boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER
-                && !mWindowManagerInternal.isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
-        // If AOD is showing, the IME should be hidden. However, sometimes the AOD is considered
-        // hidden because it's in the process of hiding, but it's still being shown on screen.
-        // In that case, we want to continue hiding the IME until the windows have completed
-        // drawing. This way, we know that the IME can be safely shown since the other windows are
-        // now shown.
-        final boolean hideIme = win.isInputMethodWindow()
-                && (mAodShowing || !mDefaultDisplayPolicy.isWindowManagerDrawComplete());
-        return (isKeyguardShowing && !allowWhenLocked && win.getDisplayId() == DEFAULT_DISPLAY)
-                || hideDockDivider || hideIme;
+        return isKeyguardShowing && !allowWhenLocked && win.getDisplayId() == DEFAULT_DISPLAY;
     }
 
     /** {@inheritDoc} */
@@ -3807,6 +3811,9 @@
             }
 
             case KeyEvent.KEYCODE_POWER: {
+                EventLogTags.writeInterceptPower(
+                        KeyEvent.actionToString(event.getAction()),
+                        mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
                 // Any activity on the power button stops the accessibility shortcut
                 cancelPendingAccessibilityShortcutAction();
                 result &= ~ACTION_PASS_TO_USER;
@@ -4356,7 +4363,7 @@
     // Called on the PowerManager's Notifier thread.
     @Override
     public void finishedGoingToSleep(int why) {
-        EventLog.writeEvent(70000, 0);
+        EventLogTags.writeScreenToggled(0);
         if (DEBUG_WAKEUP) {
             Slog.i(TAG, "Finished going to sleep... (why="
                     + WindowManagerPolicyConstants.offReasonToString(why) + ")");
@@ -4388,7 +4395,7 @@
     // Called on the PowerManager's Notifier thread.
     @Override
     public void startedWakingUp(@OnReason int why) {
-        EventLog.writeEvent(70000, 1);
+        EventLogTags.writeScreenToggled(1);
         if (DEBUG_WAKEUP) {
             Slog.i(TAG, "Started waking up... (why="
                     + WindowManagerPolicyConstants.onReasonToString(why) + ")");
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
index f23b68e..38bdc62 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
@@ -594,7 +594,7 @@
                 boolean forceBackgroundCheck,
                 int locationMode) {
 
-            this.adjustBrightnessFactor = adjustBrightnessFactor;
+            this.adjustBrightnessFactor = Math.min(1, Math.max(0, adjustBrightnessFactor));
             this.advertiseIsEnabled = advertiseIsEnabled;
             this.deferFullBackup = deferFullBackup;
             this.deferKeyValueBackup = deferKeyValueBackup;
@@ -613,7 +613,14 @@
             this.filesForNoninteractive = filesForNoninteractive;
             this.forceAllAppsStandby = forceAllAppsStandby;
             this.forceBackgroundCheck = forceBackgroundCheck;
-            this.locationMode = locationMode;
+
+            if (locationMode < PowerManager.MIN_LOCATION_MODE
+                    || PowerManager.MAX_LOCATION_MODE < locationMode) {
+                Slog.e(TAG, "Invalid location mode: " + locationMode);
+                this.locationMode = PowerManager.LOCATION_MODE_NO_CHANGE;
+            } else {
+                this.locationMode = locationMode;
+            }
 
             mHashCode = Objects.hash(
                     adjustBrightnessFactor,
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index d632749..068e78a 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -225,6 +225,22 @@
     public ParceledListSlice getAvailableRollbacks() {
         enforceManageRollbacks("getAvailableRollbacks");
 
+        // Wait for the handler thread to get the list of available rollbacks
+        // to get the most up-to-date results. This is intended to reduce test
+        // flakiness when checking available rollbacks immediately after
+        // installing a package with rollback enabled.
+        final LinkedBlockingQueue<Boolean> result = new LinkedBlockingQueue<>();
+        getHandler().post(() -> result.offer(true));
+
+        try {
+            result.take();
+        } catch (InterruptedException ie) {
+            // We may not get the most up-to-date information, but whatever we
+            // can get now is better than nothing, so log but otherwise ignore
+            // the exception.
+            Log.w(TAG, "Interrupted while waiting for handler thread in getAvailableRollbacks");
+        }
+
         synchronized (mLock) {
             ensureRollbackDataLoadedLocked();
             List<RollbackInfo> rollbacks = new ArrayList<>();
@@ -1015,6 +1031,9 @@
 
     @Override
     public boolean notifyStagedSession(int sessionId) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("notifyStagedSession may only be called by the system.");
+        }
         final LinkedBlockingQueue<Boolean> result = new LinkedBlockingQueue<>();
 
         // NOTE: We post this runnable on the RollbackManager's binder thread because we'd prefer
@@ -1066,6 +1085,9 @@
 
     @Override
     public void notifyStagedApkSession(int originalSessionId, int apkSessionId) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("notifyStagedApkSession may only be called by the system.");
+        }
         getHandler().post(() -> {
             RollbackData rd = null;
             synchronized (mLock) {
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 9348806..d8f07fe 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -166,8 +166,7 @@
      * This may cause {@code packages} to be rolled back if they crash too freqeuntly.
      */
     public void startObservingHealth(List<String> packages, long durationMs) {
-        PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs,
-                false /* withExplicitHealthCheck */);
+        PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs);
     }
 
     /** Verifies the rollback state after a reboot. */
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 1800433..f83b3ea 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -44,6 +44,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PermissionInfo;
@@ -109,6 +110,7 @@
 import com.android.internal.os.BinderCallsStats.ExportedCallStat;
 import com.android.internal.os.KernelCpuSpeedReader;
 import com.android.internal.os.KernelCpuThreadReader;
+import com.android.internal.os.KernelCpuThreadReaderDiff;
 import com.android.internal.os.KernelCpuThreadReaderSettingsObserver;
 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader;
 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader;
@@ -149,6 +151,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
@@ -260,7 +263,7 @@
     private StoragedUidIoStatsReader mStoragedUidIoStatsReader =
             new StoragedUidIoStatsReader();
     @Nullable
-    private final KernelCpuThreadReader mKernelCpuThreadReader;
+    private final KernelCpuThreadReaderDiff mKernelCpuThreadReader;
 
     private long mDebugElapsedClockPreviousValue = 0;
     private long mDebugElapsedClockPullCount = 0;
@@ -1724,7 +1727,7 @@
             throw new IllegalStateException("mKernelCpuThreadReader is null");
         }
         ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
-                this.mKernelCpuThreadReader.getProcessCpuUsageByUids();
+                this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
         if (processCpuUsages == null) {
             throw new IllegalStateException("processCpuUsages is null");
         }
@@ -2010,6 +2013,40 @@
         }
     }
 
+    private void pullAppsOnExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        PackageManager pm = mContext.getPackageManager();
+        StorageManager storage = mContext.getSystemService(StorageManager.class);
+        List<ApplicationInfo> apps = pm.getInstalledApplications(/* flags = */ 0);
+        for (ApplicationInfo appInfo : apps) {
+            UUID storageUuid = appInfo.storageUuid;
+            if (storageUuid != null) {
+                VolumeInfo volumeInfo = storage.findVolumeByUuid(appInfo.storageUuid.toString());
+                if (volumeInfo != null) {
+                    DiskInfo diskInfo = volumeInfo.getDisk();
+                    if (diskInfo != null) {
+                        int externalStorageType = -1;
+                        if (diskInfo.isSd()) {
+                            externalStorageType = StorageEnums.SD_CARD;
+                        } else if (diskInfo.isUsb()) {
+                            externalStorageType = StorageEnums.USB;
+                        } else if (appInfo.isExternal()) {
+                            externalStorageType = StorageEnums.OTHER;
+                        }
+                        // App is installed on external storage.
+                        if (externalStorageType != -1) {
+                            StatsLogEventWrapper e =
+                                    new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+                            e.writeInt(externalStorageType);
+                            e.writeString(appInfo.packageName);
+                            pulledData.add(e);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Pulls various data.
      */
@@ -2210,6 +2247,10 @@
                 pullExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
+            case StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO: {
+                pullAppsOnExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
             default:
                 Slog.w(TAG, "No such tagId data as " + tagId);
                 return null;
diff --git a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
index 7a35bf7..2df7370 100644
--- a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
+++ b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
@@ -66,7 +66,6 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 /**
  * CacheQuotaStrategy is a strategy for determining cache quotas using usage stats and foreground
@@ -296,26 +295,24 @@
      * @return the number of bytes that were free on the device when the quotas were last calced.
      */
     public long setupQuotasFromFile() throws IOException {
-        FileInputStream stream;
-        try {
-            stream = mPreviousValuesFile.openRead();
+        Pair<Long, List<CacheQuotaHint>> cachedValues = null;
+        try (FileInputStream stream = mPreviousValuesFile.openRead()) {
+            try {
+                cachedValues = readFromXml(stream);
+            } catch (XmlPullParserException e) {
+                throw new IllegalStateException(e.getMessage());
+            }
         } catch (FileNotFoundException e) {
             // The file may not exist yet -- this isn't truly exceptional.
             return -1;
         }
 
-        Pair<Long, List<CacheQuotaHint>> cachedValues = null;
-        try {
-            cachedValues = readFromXml(stream);
-        } catch (XmlPullParserException e) {
-            throw new IllegalStateException(e.getMessage());
-        }
-
         if (cachedValues == null) {
             Slog.e(TAG, "An error occurred while parsing the cache quota file.");
             return -1;
         }
         pushProcessedQuotas(cachedValues.second);
+
         return cachedValues.first;
     }
 
diff --git a/services/core/java/com/android/server/testharness/TestHarnessModeService.java b/services/core/java/com/android/server/testharness/TestHarnessModeService.java
index 9f9b797..4f11887 100644
--- a/services/core/java/com/android/server/testharness/TestHarnessModeService.java
+++ b/services/core/java/com/android/server/testharness/TestHarnessModeService.java
@@ -71,7 +71,6 @@
     private static final String TEST_HARNESS_MODE_PROPERTY = "persist.sys.test_harness";
 
     private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal;
-    private boolean mShouldSetUpTestHarnessMode;
 
     public TestHarnessModeService(Context context) {
         super(context);
@@ -89,9 +88,8 @@
                 setUpTestHarnessMode();
                 break;
             case PHASE_BOOT_COMPLETED:
-                disableAutoSync();
-                configureSettings();
-                showNotification();
+                completeTestHarnessModeSetup();
+                showNotificationIfEnabled();
                 break;
         }
         super.onBootPhase(phase);
@@ -104,47 +102,45 @@
             // There's no data to apply, so leave it as-is.
             return;
         }
-        PersistentData persistentData;
-        try {
-            persistentData = PersistentData.fromBytes(testHarnessModeData);
-        } catch (SetUpTestHarnessModeException e) {
-            Slog.e(TAG, "Failed to set up Test Harness Mode. Bad data.", e);
-            return;
-        } finally {
-            // Clear out the Test Harness Mode data. It's now in memory if successful or we should
-            // skip setting up.
-            getPersistentDataBlock().clearTestHarnessModeData();
-        }
-        mShouldSetUpTestHarnessMode = true;
-        setUpAdb(persistentData);
+        // If there is data, we should set the device as provisioned, so that we skip the setup
+        // wizard.
         setDeviceProvisioned();
+        SystemProperties.set(TEST_HARNESS_MODE_PROPERTY, "1");
     }
 
-    private void setUpAdb(PersistentData persistentData) {
-        ContentResolver cr = getContext().getContentResolver();
-
-        // Disable the TTL for ADB keys before enabling ADB
-        Settings.Global.putLong(cr, Settings.Global.ADB_ALLOWED_CONNECTION_TIME, 0);
-
-        SystemProperties.set(TEST_HARNESS_MODE_PROPERTY, "1");
-        writeAdbKeysFile(persistentData);
+    private void completeTestHarnessModeSetup() {
+        Slog.d(TAG, "Completing Test Harness Mode setup.");
+        byte[] testHarnessModeData = getPersistentDataBlock().getTestHarnessModeData();
+        if (testHarnessModeData == null || testHarnessModeData.length == 0) {
+            // There's no data to apply, so leave it as-is.
+            return;
+        }
+        try {
+            setUpAdbFiles(PersistentData.fromBytes(testHarnessModeData));
+            disableAutoSync();
+            configureSettings();
+        } catch (SetUpTestHarnessModeException e) {
+            Slog.e(TAG, "Failed to set up Test Harness Mode. Bad data.", e);
+        } finally {
+            // Clear out the Test Harness Mode data so that we don't repeat the setup. If it failed
+            // to set up, then retrying without enabling Test Harness Mode should allow it to boot.
+            // If we succeeded setting up, we shouldn't be re-applying the THM steps every boot
+            // anyway.
+            getPersistentDataBlock().clearTestHarnessModeData();
+        }
     }
 
     private void disableAutoSync() {
-        if (!mShouldSetUpTestHarnessMode) {
-            return;
-        }
         UserInfo primaryUser = UserManager.get(getContext()).getPrimaryUser();
         ContentResolver
             .setMasterSyncAutomaticallyAsUser(false, primaryUser.getUserHandle().getIdentifier());
     }
 
     private void configureSettings() {
-        if (!mShouldSetUpTestHarnessMode) {
-            return;
-        }
         ContentResolver cr = getContext().getContentResolver();
 
+        // Disable the TTL for ADB keys before enabling ADB
+        Settings.Global.putLong(cr, Settings.Global.ADB_ALLOWED_CONNECTION_TIME, 0);
         Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1);
         Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
         Settings.Global.putInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
@@ -155,7 +151,7 @@
         Settings.Global.putInt(cr, Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE, 1);
     }
 
-    private void writeAdbKeysFile(PersistentData persistentData) {
+    private void setUpAdbFiles(PersistentData persistentData) {
         AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class);
 
         writeBytesToFile(persistentData.mAdbKeys, adbManager.getAdbKeysFile().toPath());
@@ -189,7 +185,7 @@
                 UserHandle.USER_CURRENT);
     }
 
-    private void showNotification() {
+    private void showNotificationIfEnabled() {
         if (!SystemProperties.getBoolean(TEST_HARNESS_MODE_PROPERTY, false)) {
             return;
         }
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index a5d291f..5f00148 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -425,9 +425,12 @@
         if (packageName == null) return;
 
         try {
-            final int uid = context.getPackageManager()
+            final int packageUid = context.getPackageManager()
                     .getPackageUidAsUser(packageName, UserHandle.getCallingUserId());
-            Preconditions.checkArgument(Binder.getCallingUid() == uid);
+            final int callingUid = Binder.getCallingUid();
+            Preconditions.checkArgument(callingUid == packageUid
+                    // Trust the system process:
+                    || callingUid == android.os.Process.SYSTEM_UID);
         } catch (Exception e) {
             throw new RemoteException(
                     String.format("Invalid package: name=%s, error=%s", packageName, e));
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index e53fde9..d52ba16 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -77,6 +77,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.storage.StorageManager;
 import android.service.wallpaper.IWallpaperConnection;
 import android.service.wallpaper.IWallpaperEngine;
 import android.service.wallpaper.IWallpaperService;
@@ -1718,6 +1719,7 @@
                     final WallpaperData systemWallpaper =
                             getWallpaperSafeLocked(userId, FLAG_SYSTEM);
                     switchWallpaper(systemWallpaper, null);
+                    notifyCallbacksLocked(systemWallpaper);
                 }
 
                 // Make sure that the SELinux labeling of all the relevant files is correct.
@@ -2089,28 +2091,14 @@
         }
     }
 
-    private void enforceCallingOrSelfPermissionAndAppOp(String permission, final String callingPkg,
-            final int callingUid, String message) {
-        mContext.enforceCallingOrSelfPermission(permission, message);
-
-        final String opName = AppOpsManager.permissionToOp(permission);
-        if (opName != null) {
-            final int appOpMode = mAppOpsManager.noteOp(opName, callingUid, callingPkg);
-            if (appOpMode != AppOpsManager.MODE_ALLOWED) {
-                throw new SecurityException(
-                        message + ": " + callingPkg + " is not allowed to " + permission);
-            }
-        }
-    }
-
     @Override
     public ParcelFileDescriptor getWallpaper(String callingPkg, IWallpaperManagerCallback cb,
             final int which, Bundle outParams, int wallpaperUserId) {
         final int hasPrivilege = mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.READ_WALLPAPER_INTERNAL);
         if (hasPrivilege != PackageManager.PERMISSION_GRANTED) {
-            enforceCallingOrSelfPermissionAndAppOp(android.Manifest.permission.READ_EXTERNAL_STORAGE,
-                    callingPkg, Binder.getCallingUid(), "read wallpaper");
+            mContext.getSystemService(StorageManager.class).checkPermissionReadImages(true,
+                    Binder.getCallingPid(), Binder.getCallingUid(), callingPkg);
         }
 
         wallpaperUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
@@ -2682,6 +2670,14 @@
                 }
                 wallpaper.connection.mReply = null;
             }
+            try {
+                // It can be null if user switching happens before service connection.
+                if (wallpaper.connection.mService != null) {
+                    wallpaper.connection.mService.detach();
+                }
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed detaching wallpaper service ", e);
+            }
             mContext.unbindService(wallpaper.connection);
             wallpaper.connection.forEachDisplayConnector(
                     WallpaperConnection.DisplayConnector::disconnectLocked);
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 4aa2b37..56a6c3c 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -19,19 +19,15 @@
 import android.app.ActivityManager;
 import android.app.AppGlobals;
 import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
 import android.content.res.XmlResourceParser;
-import android.database.ContentObserver;
 import android.os.Build;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.Settings.Global;
 import android.provider.Settings;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
@@ -42,12 +38,12 @@
 
 import com.android.internal.util.XmlUtils;
 
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.xmlpull.v1.XmlPullParserException;
-
 /**
  * Default implementation for the WebView preparation Utility interface.
  * @hide
@@ -77,7 +73,6 @@
     private SystemImpl() {
         int numFallbackPackages = 0;
         int numAvailableByDefaultPackages = 0;
-        int numAvByDefaultAndNotFallback = 0;
         XmlResourceParser parser = null;
         List<WebViewProviderInfo> webViewProviders = new ArrayList<WebViewProviderInfo>();
         try {
@@ -121,9 +116,6 @@
                     }
                     if (currentProvider.availableByDefault) {
                         numAvailableByDefaultPackages++;
-                        if (!currentProvider.isFallback) {
-                            numAvByDefaultAndNotFallback++;
-                        }
                     }
                     webViewProviders.add(currentProvider);
                 }
@@ -140,10 +132,6 @@
             throw new AndroidRuntimeException("There must be at least one WebView package "
                     + "that is available by default");
         }
-        if (numAvByDefaultAndNotFallback == 0) {
-            throw new AndroidRuntimeException("There must be at least one WebView package "
-                    + "that is available by default and not a fallback");
-        }
         mWebViewProviderPackages =
                 webViewProviders.toArray(new WebViewProviderInfo[webViewProviders.size()]);
     }
@@ -222,23 +210,6 @@
     }
 
     @Override
-    public void uninstallAndDisablePackageForAllUsers(Context context, String packageName) {
-        enablePackageForAllUsers(context, packageName, false);
-        try {
-            PackageManager pm = AppGlobals.getInitialApplication().getPackageManager();
-            ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, 0);
-            if (applicationInfo != null && applicationInfo.isUpdatedSystemApp()) {
-                pm.deletePackage(packageName, new IPackageDeleteObserver.Stub() {
-                        public void packageDeleted(String packageName, int returnCode) {
-                            enablePackageForAllUsers(context, packageName, false);
-                        }
-                    }, PackageManager.DELETE_SYSTEM_APP | PackageManager.DELETE_ALL_USERS);
-            }
-        } catch (NameNotFoundException e) {
-        }
-    }
-
-    @Override
     public void enablePackageForAllUsers(Context context, String packageName, boolean enable) {
         UserManager userManager = (UserManager)context.getSystemService(Context.USER_SERVICE);
         for(UserInfo userInfo : userManager.getUsers()) {
@@ -246,8 +217,7 @@
         }
     }
 
-    @Override
-    public void enablePackageForUser(String packageName, boolean enable, int userId) {
+    private void enablePackageForUser(String packageName, boolean enable, int userId) {
         try {
             AppGlobals.getPackageManager().setApplicationEnabledSetting(
                     packageName,
diff --git a/services/core/java/com/android/server/webkit/SystemInterface.java b/services/core/java/com/android/server/webkit/SystemInterface.java
index 405fe7d..3fb5279 100644
--- a/services/core/java/com/android/server/webkit/SystemInterface.java
+++ b/services/core/java/com/android/server/webkit/SystemInterface.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.database.ContentObserver;
 import android.webkit.UserPackage;
 import android.webkit.WebViewProviderInfo;
 
@@ -45,9 +44,7 @@
     public boolean isFallbackLogicEnabled();
     public void enableFallbackLogic(boolean enable);
 
-    public void uninstallAndDisablePackageForAllUsers(Context context, String packageName);
     public void enablePackageForAllUsers(Context context, String packageName, boolean enable);
-    public void enablePackageForUser(String packageName, boolean enable, int userId);
 
     public boolean systemIsDebuggable();
     public PackageInfo getPackageInfoForProvider(WebViewProviderInfo configInfo)
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index d7458f2..0abe68f 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -241,32 +241,6 @@
         }
 
         @Override // Binder call
-        public boolean isFallbackPackage(String packageName) {
-            return WebViewUpdateService.this.mImpl.isFallbackPackage(packageName);
-        }
-
-        @Override // Binder call
-        public void enableFallbackLogic(boolean enable) {
-            if (getContext().checkCallingPermission(
-                        android.Manifest.permission.WRITE_SECURE_SETTINGS)
-                    != PackageManager.PERMISSION_GRANTED) {
-                String msg = "Permission Denial: enableFallbackLogic() from pid="
-                        + Binder.getCallingPid()
-                        + ", uid=" + Binder.getCallingUid()
-                        + " requires " + android.Manifest.permission.WRITE_SECURE_SETTINGS;
-                Slog.w(TAG, msg);
-                throw new SecurityException(msg);
-            }
-
-            long callingId = Binder.clearCallingIdentity();
-            try {
-                WebViewUpdateService.this.mImpl.enableFallbackLogic(enable);
-            } finally {
-                Binder.restoreCallingIdentity(callingId);
-            }
-        }
-
-        @Override // Binder call
         public boolean isMultiProcessEnabled() {
             return WebViewUpdateService.this.mImpl.isMultiProcessEnabled();
         }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index d4949b6..f704c30 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -16,48 +16,36 @@
 package com.android.server.webkit;
 
 import android.content.Context;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
-import android.content.pm.Signature;
 import android.os.UserHandle;
-import android.util.Slog;
-import android.webkit.UserPackage;
 import android.webkit.WebViewProviderInfo;
 import android.webkit.WebViewProviderResponse;
 
 import java.io.PrintWriter;
-import java.lang.Integer;
-import java.util.List;
 
 /**
  * Implementation of the WebViewUpdateService.
  * This class doesn't depend on the android system like the actual Service does and can be used
  * directly by tests (as long as they implement a SystemInterface).
  *
- * This class implements two main features - handling WebView fallback packages and keeping track
- * of, and preparing, the current WebView implementation. The fallback mechanism is meant to be
- * uncoupled from the rest of the WebView preparation and does not store any state. The code for
- * choosing and preparing a WebView implementation needs to keep track of a couple of different
- * things such as what package is used as WebView implementation.
+ * This class keeps track of and prepares the current WebView implementation, and needs to keep
+ * track of a couple of different things such as what package is used as WebView implementation.
  *
  * The public methods in this class are accessed from WebViewUpdateService either on the UI thread
- * or on one of multiple Binder threads. This means that the code in this class needs to be
- * thread-safe. The fallback mechanism shares (almost) no information between threads which makes
- * it easier to argue about thread-safety (in theory, if timed badly, the fallback mechanism can
- * incorrectly enable/disable a fallback package but that fault will be corrected when we later
- * receive an intent for that enabling/disabling). On the other hand, the WebView preparation code
- * shares state between threads meaning that code that chooses a new WebView implementation or
- * checks which implementation is being used needs to hold a lock.
+ * or on one of multiple Binder threads. The WebView preparation code shares state between threads
+ * meaning that code that chooses a new WebView implementation or checks which implementation is
+ * being used needs to hold a lock.
  *
  * The WebViewUpdateService can be accessed in a couple of different ways.
  * 1. It is started from the SystemServer at boot - at that point we just initiate some state such
  * as the WebView preparation class.
  * 2. The SystemServer calls WebViewUpdateService.prepareWebViewInSystemServer. This happens at boot
  * and the WebViewUpdateService should not have been accessed before this call. In this call we
- * enable/disable fallback packages and then choose WebView implementation for the first time.
+ * migrate away from the old fallback logic if necessary and then choose WebView implementation for
+ * the first time.
  * 3. The update service listens for Intents related to package installs and removals. These intents
- * are received and processed on the UI thread. Each intent can result in enabling/disabling
- * fallback packages and changing WebView implementation.
+ * are received and processed on the UI thread. Each intent can result in changing WebView
+ * implementation.
  * 4. The update service can be reached through Binder calls which are handled on specific binder
  * threads. These calls can be made from any process. Generally they are used for changing WebView
  * implementation (from Settings), getting information about the current WebView implementation (for
@@ -86,35 +74,15 @@
         // We don't early out here in different cases where we could potentially early-out (e.g. if
         // we receive PACKAGE_CHANGED for another user than the system user) since that would
         // complicate this logic further and open up for more edge cases.
-        updateFallbackStateOnPackageChange(packageName, changedState);
         mWebViewUpdater.packageStateChanged(packageName, changedState);
     }
 
     void prepareWebViewInSystemServer() {
-        updateFallbackStateOnBoot();
+        migrateFallbackStateOnBoot();
         mWebViewUpdater.prepareWebViewInSystemServer();
         mSystemInterface.notifyZygote(isMultiProcessEnabled());
     }
 
-    private boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) {
-        for (WebViewProviderInfo provider : providers) {
-            if (provider.availableByDefault && !provider.isFallback) {
-                // userPackages can contain null objects.
-                List<UserPackage> userPackages =
-                        mSystemInterface.getPackageInfoForProviderAllUsers(mContext, provider);
-                if (WebViewUpdater.isInstalledAndEnabledForAllUsers(userPackages) &&
-                        // Checking validity of the package for the system user (rather than all
-                        // users) since package validity depends not on the user but on the package
-                        // itself.
-                        mWebViewUpdater.isValidProvider(provider,
-                                userPackages.get(UserHandle.USER_SYSTEM).getPackageInfo())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     void handleNewUser(int userId) {
         // The system user is always started at boot, and by that point we have already run one
         // round of the package-changing logic (through prepareWebViewInSystemServer()), so early
@@ -128,14 +96,11 @@
     }
 
     /**
-     * Called when a user was added or removed to ensure fallback logic and WebView preparation are
-     * triggered. This has to be done since the WebView package we use depends on the enabled-state
+     * Called when a user was added or removed to ensure WebView preparation is triggered.
+     * This has to be done since the WebView package we use depends on the enabled-state
      * of packages for all users (so adding or removing a user might cause us to change package).
      */
     private void handleUserChange() {
-        if (mSystemInterface.isFallbackLogicEnabled()) {
-            updateFallbackState(mSystemInterface.getWebViewPackages());
-        }
         // Potentially trigger package-changing logic.
         mWebViewUpdater.updateCurrentWebViewPackage(null);
     }
@@ -164,60 +129,22 @@
         return mWebViewUpdater.getCurrentWebViewPackage();
     }
 
-    void enableFallbackLogic(boolean enable) {
-        mSystemInterface.enableFallbackLogic(enable);
-    }
-
-    private void updateFallbackStateOnBoot() {
-        if (!mSystemInterface.isFallbackLogicEnabled()) return;
-
-        WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
-        updateFallbackState(webviewProviders);
-    }
-
     /**
-     * Handle the enabled-state of our fallback package, i.e. if there exists some non-fallback
-     * package that is valid (and available by default) then disable the fallback package,
-     * otherwise, enable the fallback package.
+     * If the fallback logic is enabled, re-enable any fallback package for all users, then
+     * disable the fallback logic.
+     *
+     * This migrates away from the old fallback mechanism to the new state where packages are never
+     * automatically enableenableisabled.
      */
-    private void updateFallbackStateOnPackageChange(String changedPackage, int changedState) {
+    private void migrateFallbackStateOnBoot() {
         if (!mSystemInterface.isFallbackLogicEnabled()) return;
 
         WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
-
-        // A package was changed / updated / downgraded, early out if it is not one of the
-        // webview packages that are available by default.
-        boolean changedPackageAvailableByDefault = false;
-        for (WebViewProviderInfo provider : webviewProviders) {
-            if (provider.packageName.equals(changedPackage)) {
-                if (provider.availableByDefault) {
-                    changedPackageAvailableByDefault = true;
-                }
-                break;
-            }
-        }
-        if (!changedPackageAvailableByDefault) return;
-        updateFallbackState(webviewProviders);
-    }
-
-    private void updateFallbackState(WebViewProviderInfo[] webviewProviders) {
-        // If there exists a valid and enabled non-fallback package - disable the fallback
-        // package, otherwise, enable it.
         WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
-        if (fallbackProvider == null) return;
-        boolean existsValidNonFallbackProvider = existsValidNonFallbackProvider(webviewProviders);
-
-        List<UserPackage> userPackages =
-                mSystemInterface.getPackageInfoForProviderAllUsers(mContext, fallbackProvider);
-        if (existsValidNonFallbackProvider && !isDisabledForAllUsers(userPackages)) {
-            mSystemInterface.uninstallAndDisablePackageForAllUsers(mContext,
-                    fallbackProvider.packageName);
-        } else if (!existsValidNonFallbackProvider
-                && !WebViewUpdater.isInstalledAndEnabledForAllUsers(userPackages)) {
-            // Enable the fallback package for all users.
-            mSystemInterface.enablePackageForAllUsers(mContext,
-                    fallbackProvider.packageName, true);
+        if (fallbackProvider != null) {
+            mSystemInterface.enablePackageForAllUsers(mContext, fallbackProvider.packageName, true);
         }
+        mSystemInterface.enableFallbackLogic(false);
     }
 
     /**
@@ -232,15 +159,6 @@
         return null;
     }
 
-    boolean isFallbackPackage(String packageName) {
-        if (packageName == null || !mSystemInterface.isFallbackLogicEnabled()) return false;
-
-        WebViewProviderInfo[] webviewPackages = mSystemInterface.getWebViewPackages();
-        WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewPackages);
-        return (fallbackProvider != null
-                && packageName.equals(fallbackProvider.packageName));
-    }
-
     boolean isMultiProcessEnabled() {
         int settingValue = mSystemInterface.getMultiProcessSetting(mContext);
         if (mSystemInterface.isMultiProcessDefaultEnabled()) {
@@ -262,15 +180,6 @@
         }
     }
 
-    private static boolean isDisabledForAllUsers(List<UserPackage> userPackages) {
-        for (UserPackage userPackage : userPackages) {
-            if (userPackage.getPackageInfo() != null && userPackage.isEnabledPackage()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     /**
      * Dump the state of this Service.
      */
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java
index 3199ed4..7529c41 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java
@@ -37,10 +37,6 @@
         final PrintWriter pw = getOutPrintWriter();
         try {
             switch(cmd) {
-                case "enable-redundant-packages":
-                    return enableFallbackLogic(false);
-                case "disable-redundant-packages":
-                    return enableFallbackLogic(true);
                 case "set-webview-implementation":
                     return setWebViewImplementation();
                 case "enable-multiprocess":
@@ -56,13 +52,6 @@
         return -1;
     }
 
-    private int enableFallbackLogic(boolean enable) throws RemoteException {
-        final PrintWriter pw = getOutPrintWriter();
-        mInterface.enableFallbackLogic(enable);
-        pw.println("Success");
-        return 0;
-    }
-
     private int setWebViewImplementation() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         String shellChosenPackage = getNextArg();
@@ -104,13 +93,6 @@
         pw.println("  help");
         pw.println("    Print this help text.");
         pw.println("");
-        pw.println("  enable-redundant-packages");
-        pw.println("    Allow a fallback package to be installed and enabled even when a");
-        pw.println("    more-preferred package is available. This command is useful when testing");
-        pw.println("    fallback packages.");
-        pw.println("  disable-redundant-packages");
-        pw.println("    Disallow installing and enabling fallback packages when a more-preferred");
-        pw.println("    package is available.");
         helpSetWebViewImplementation();
         pw.println("  enable-multiprocess");
         pw.println("    Enable multi-process mode for WebView");
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java
index f270715..a460040 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdater.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java
@@ -20,7 +20,6 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.Signature;
 import android.os.UserHandle;
-import android.util.Base64;
 import android.util.Slog;
 import android.webkit.UserPackage;
 import android.webkit.WebViewFactory;
@@ -29,7 +28,6 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -140,13 +138,17 @@
         try {
             synchronized(mLock) {
                 mCurrentWebViewPackage = findPreferredWebViewPackage();
-                // Don't persist the user-chosen setting across boots if the package being
-                // chosen is not used (could be disabled or uninstalled) so that the user won't
-                // be surprised by the device switching to using a certain webview package,
-                // that was uninstalled/disabled a long time ago, if it is installed/enabled
-                // again.
-                mSystemInterface.updateUserSetting(mContext,
-                        mCurrentWebViewPackage.packageName);
+                String userSetting = mSystemInterface.getUserChosenWebViewProvider(mContext);
+                if (userSetting != null
+                        && !userSetting.equals(mCurrentWebViewPackage.packageName)) {
+                    // Don't persist the user-chosen setting across boots if the package being
+                    // chosen is not used (could be disabled or uninstalled) so that the user won't
+                    // be surprised by the device switching to using a certain webview package,
+                    // that was uninstalled/disabled a long time ago, if it is installed/enabled
+                    // again.
+                    mSystemInterface.updateUserSetting(mContext,
+                            mCurrentWebViewPackage.packageName);
+                }
                 onWebViewProviderChanged(mCurrentWebViewPackage);
             }
         } catch (Throwable t) {
@@ -470,9 +472,9 @@
 
     /**
      * Gets the minimum version code allowed for a valid provider. It is the minimum versionCode
-     * of all available-by-default and non-fallback WebView provider packages. If there is no
-     * such WebView provider package on the system, then return -1, which means all positive
-     * versionCode WebView packages are accepted.
+     * of all available-by-default WebView provider packages. If there is no such WebView provider
+     * package on the system, then return -1, which means all positive versionCode WebView packages
+     * are accepted.
      *
      * Note that this is a private method in WebViewUpdater that handles a variable
      * (mMinimumVersionCode) which is shared between threads. Furthermore, this method does not
@@ -485,7 +487,7 @@
 
         long minimumVersionCode = -1;
         for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) {
-            if (provider.availableByDefault && !provider.isFallback) {
+            if (provider.availableByDefault) {
                 try {
                     long versionCode =
                         mSystemInterface.getFactoryPackageVersion(provider.packageName);
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 2d89bc7..d916e39 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -85,6 +85,7 @@
 
 import android.app.WaitResult;
 import android.app.WindowConfiguration.WindowingMode;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -876,6 +877,11 @@
         builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0);
         if (intent != null) {
             builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction());
+            ComponentName component = intent.getComponent();
+            if (component != null) {
+                builder.addTaggedData(FIELD_TARGET_SHORT_COMPONENT_NAME,
+                        component.flattenToShortString());
+            }
         }
         if (callerApp != null) {
             builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.mName);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 5bbabfc..91ec4a0 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1102,7 +1102,7 @@
                     ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this)
                             * 1000000L, fullscreen,
                     (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, appInfo.targetSdkVersion,
-                    info.screenOrientation, mRotationAnimationHint, info.configChanges,
+                    info.screenOrientation, mRotationAnimationHint,
                     mLaunchTaskBehind, isAlwaysFocusable());
             if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) {
                 Slog.v(TAG, "addAppToken: "
@@ -1151,11 +1151,11 @@
     AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
             boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
             boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
-            int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
+            int rotationAnimationHint, boolean launchTaskBehind,
             boolean alwaysFocusable) {
         return new AppWindowToken(service, token, mActivityComponent, voiceInteraction, dc,
                 inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
-                rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
+                rotationAnimationHint, launchTaskBehind, alwaysFocusable,
                 this);
     }
 
@@ -2730,30 +2730,40 @@
         final int appHeight = resolvedAppBounds.height();
         final int parentAppWidth = parentAppBounds.width();
         final int parentAppHeight = parentAppBounds.height();
+        if (parentAppWidth == appWidth && parentAppHeight == appHeight) {
+            // Matched the parent bounds.
+            return false;
+        }
+        if (parentAppWidth > appWidth && parentAppHeight > appHeight) {
+            // Both sides are smaller than the parent.
+            return true;
+        }
         if (parentAppWidth < appWidth || parentAppHeight < appHeight) {
             // One side is larger than the parent.
             return true;
         }
 
-        if (info.hasFixedAspectRatio()) {
+        // The rest of the condition is that only one side is smaller than the parent, but it still
+        // needs to exclude the cases where the size is limited by the fixed aspect ratio.
+        if (info.maxAspectRatio > 0) {
             final float aspectRatio = (0.5f + Math.max(appWidth, appHeight))
                     / Math.min(appWidth, appHeight);
-            final float parentAspectRatio = (0.5f + Math.max(parentAppWidth, parentAppHeight))
-                    / Math.min(parentAppWidth, parentAppHeight);
-            // Check if the parent still has available space in long side.
-            if (aspectRatio < parentAspectRatio
-                    && (aspectRatio < info.maxAspectRatio || info.minAspectRatio > 0)) {
-                return true;
+            if (aspectRatio >= info.maxAspectRatio) {
+                // The current size has reached the max aspect ratio.
+                return false;
             }
         }
-
-        final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
-        // If the width or height is the same as parent, it is already the best fit of the override
-        // bounds, therefore this condition is considered as not size compatibility mode. Here uses
-        // right and bottom as width and height of parent because the bounds may contain decor
-        // insets which has been accounted in override bounds. See {@link #computeBounds}.
-        return parentAppBounds.right != resolvedBounds.width()
-                && parentAppBounds.bottom != resolvedBounds.height();
+        if (info.minAspectRatio > 0) {
+            // The activity should have at least the min aspect ratio, so this checks if the parent
+            // still has available space to provide larger aspect ratio.
+            final float parentAspectRatio = (0.5f + Math.max(parentAppWidth, parentAppHeight))
+                    / Math.min(parentAppWidth, parentAppHeight);
+            if (parentAspectRatio <= info.minAspectRatio) {
+                // The long side has reached the parent.
+                return false;
+            }
+        }
+        return true;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 4c9b80b..6bc9fc8 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -3059,7 +3059,11 @@
             // activity in home stack.
             // See {@link #mInResumeTopActivity}.
             mService.mH.post(
-                    () -> mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId));
+                    () -> {
+                        synchronized (mService.mGlobalLock) {
+                            mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
+                        }
+                    });
             return true;
         } else {
             return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
@@ -4111,9 +4115,16 @@
         if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
 
         r.setState(FINISHING, "finishCurrentActivityLocked");
+
+        // Don't destroy activity immediately if the display contains home stack, although there is
+        // no next activity at the moment but another home activity should be started later. Keep
+        // this activity alive until next home activity is resumed then user won't see a temporary
+        // black screen.
+        final boolean noRunningStack = next == null && display.topRunningActivity() == null
+                && display.getHomeStack() == null;
+        final boolean noFocusedStack = r.getActivityStack() != display.getFocusedStack();
         final boolean finishingInNonFocusedStackOrNoRunning = mode == FINISH_AFTER_VISIBLE
-                && prevState == PAUSED && (r.getActivityStack() != display.getFocusedStack()
-                        || (next == null && display.topRunningActivity() == null));
+                && prevState == PAUSED && (noFocusedStack || noRunningStack);
 
         if (mode == FINISH_IMMEDIATELY
                 || (prevState == PAUSED
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 3acd4e7..3b358e8 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -114,6 +114,7 @@
 import android.os.UserManager;
 import android.service.voice.IVoiceInteractionSession;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.Pools.SynchronizedPool;
 import android.util.Slog;
@@ -607,6 +608,7 @@
             boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
             TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
             PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
+        mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
         int err = ActivityManager.START_SUCCESS;
         // Pull the optional Ephemeral Installer-only bundle out of the options early.
         final Bundle verificationBundle
@@ -927,8 +929,10 @@
         mService.onStartActivitySetDidAppSwitch();
         mController.doPendingActivityLaunches(false);
 
-        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
+        final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                 true /* doResume */, checkedOptions, inTask, outActivity);
+        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
+        return res;
     }
 
     private boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
@@ -945,7 +949,8 @@
         final boolean callingUidHasAnyVisibleWindow =
                 mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(callingUid);
         final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
-                || callingUidProcState == ActivityManager.PROCESS_STATE_TOP;
+                || callingUidProcState == ActivityManager.PROCESS_STATE_TOP
+                || callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
         final boolean isCallingUidPersistentSystemProcess = (callingUid == Process.SYSTEM_UID)
                 || callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
         if (isCallingUidForeground || isCallingUidPersistentSystemProcess) {
@@ -976,6 +981,11 @@
             if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
                 return false;
             }
+            // don't abort if the realCallingUid is an associated companion app
+            if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
+                    realCallingUid)) {
+                return false;
+            }
         }
         // If we don't have callerApp at this point, no caller was provided to startActivity().
         // That's the case for PendingIntent-based starts, since the creator's process might not be
@@ -997,6 +1007,14 @@
             if (callerApp.areBackgroundActivityStartsAllowed()) {
                 return false;
             }
+            // don't abort if the caller has an activity in any foreground task
+            if (callerApp.hasActivityInVisibleTask()) {
+                return false;
+            }
+            // don't abort if the caller is bound by a UID that's currently foreground
+            if (isBoundByForegroundUid(callerApp)) {
+                return false;
+            }
         }
         // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
         if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
@@ -1011,6 +1029,11 @@
         if (mService.isDeviceOwner(callingPackage)) {
             return false;
         }
+        // don't abort if the callingPackage has companion device
+        final int callingUserId = UserHandle.getUserId(callingUid);
+        if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
+            return false;
+        }
         // don't abort if the callingPackage is temporarily whitelisted
         if (mService.isPackageNameWhitelistedForBgActivityStarts(callingPackage)) {
             Slog.w(TAG, "Background activity start for " + callingPackage
@@ -1041,6 +1064,18 @@
         return true;
     }
 
+    private boolean isBoundByForegroundUid(WindowProcessController callerApp) {
+        final ArraySet<Integer> boundClientUids = callerApp.getBoundClientUids();
+        for (int i = boundClientUids.size() - 1; i >= 0; --i) {
+            final int uid = boundClientUids.valueAt(i);
+            if (mService.mWindowManager.mRoot.isAnyNonToastWindowVisibleForUid(uid)
+                    || mService.getUidState(uid) == ActivityManager.PROCESS_STATE_TOP) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Creates a launch intent for the given auxiliary resolution data.
      */
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index fc7646f..b2e5b6a 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -510,4 +510,7 @@
      * Called by DevicePolicyManagerService to set the package name of the device owner.
      */
     public abstract void setDeviceOwnerPackageName(String deviceOwnerPkg);
+
+    /** Set all associated companion app that belongs to an userId. */
+    public abstract void setCompanionAppPackages(int userId, Set<String> companionAppPackages);
 }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 7ea7cf1..b64abdb 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -191,6 +191,7 @@
 import android.os.PersistableBundle;
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
@@ -243,6 +244,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.AttributeCache;
+import com.android.server.DeviceIdleController;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.SystemServiceManager;
@@ -425,6 +427,9 @@
     private static final long START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT =
             START_AS_CALLER_TOKEN_TIMEOUT_IMPL + 20 * MINUTE_IN_MILLIS;
 
+    // How long to whitelist the Services for when requested.
+    private static final int SERVICE_LAUNCH_IDLE_WHITELIST_DURATION_MS = 5 * 1000;
+
     // Activity tokens of system activities that are delegating their call to
     // #startActivityByCaller, keyed by the permissionToken granted to the delegate.
     final HashMap<IBinder, IBinder> mStartActivitySources = new HashMap<>();
@@ -438,6 +443,9 @@
     // VoiceInteractionManagerService
     ComponentName mActiveVoiceInteractionServiceComponent;
 
+    // A map userId and all its companion app uids
+    private final Map<Integer, Set<Integer>> mCompanionAppUidsMap = new ArrayMap<>();
+
     VrController mVrController;
     KeyguardController mKeyguardController;
     private final ClientLifecycleManager mLifecycleManager;
@@ -2076,7 +2084,7 @@
         synchronized (mGlobalLock) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                getRecentTasks().removeAllVisibleTasks();
+                getRecentTasks().removeAllVisibleTasks(mAmInternal.getCurrentUserId());
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2967,7 +2975,8 @@
             if (TextUtils.equals(pae.intent.getAction(),
                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
                 pae.intent.putExtras(pae.extras);
-                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
+
+                startVoiceInteractionServiceAsUser(pae.intent, pae.userHandle, "AssistContext");
             } else {
                 pae.intent.replaceExtras(pae.extras);
                 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
@@ -2986,6 +2995,34 @@
         }
     }
 
+    /**
+     * Workaround for historical API which starts the Assist service with a non-foreground
+     * {@code startService()} call.
+     */
+    private void startVoiceInteractionServiceAsUser(
+            Intent intent, int userHandle, String reason) {
+        // Resolve the intent to find out which package we need to whitelist.
+        ResolveInfo resolveInfo =
+                mContext.getPackageManager().resolveServiceAsUser(intent, 0, userHandle);
+        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+            Slog.e(TAG, "VoiceInteractionService intent does not resolve. Not starting.");
+            return;
+        }
+        intent.setPackage(resolveInfo.serviceInfo.packageName);
+
+        // Whitelist background services temporarily.
+        LocalServices.getService(DeviceIdleController.LocalService.class)
+                .addPowerSaveTempWhitelistApp(Process.myUid(), intent.getPackage(),
+                        SERVICE_LAUNCH_IDLE_WHITELIST_DURATION_MS, userHandle, false, reason);
+
+        // Finally, try to start the service.
+        try {
+            mContext.startServiceAsUser(intent, UserHandle.of(userHandle));
+        } catch (RuntimeException e) {
+            Slog.e(TAG, "VoiceInteractionService failed to start.", e);
+        }
+    }
+
     @Override
     public int addAppTask(IBinder activityToken, Intent intent,
             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
@@ -5775,15 +5812,10 @@
     }
 
     WindowProcessController getProcessController(int pid, int uid) {
-        final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
-        for (int i = pmap.size()-1; i >= 0; i--) {
-            final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
-            for (int j = procs.size() - 1; j >= 0; j--) {
-                final WindowProcessController proc = procs.valueAt(j);
-                if (UserHandle.isApp(uid) && proc.getPid() == pid && proc.mUid == uid) {
-                    return proc;
-                }
-            }
+        final WindowProcessController proc = mPidMap.get(pid);
+        if (proc == null) return null;
+        if (UserHandle.isApp(uid) && proc.mUid == uid) {
+            return proc;
         }
         return null;
     }
@@ -5875,6 +5907,14 @@
         }
     }
 
+    boolean isAssociatedCompanionApp(int userId, int uid) {
+        final Set<Integer> allUids = mCompanionAppUidsMap.get(userId);
+        if (allUids == null) {
+            return false;
+        }
+        return allUids.contains(uid);
+    }
+
     final class H extends Handler {
         static final int REPORT_TIME_TRACKER_MSG = 1;
 
@@ -7248,5 +7288,20 @@
                 ActivityTaskManagerService.this.setDeviceOwnerPackageName(deviceOwnerPkg);
             }
         }
+
+        @Override
+        public void setCompanionAppPackages(int userId, Set<String> companionAppPackages) {
+            // Translate package names into UIDs
+            final Set<Integer> result = new HashSet<>();
+            for (String pkg : companionAppPackages) {
+                final int uid = getPackageManagerInternalLocked().getPackageUid(pkg, 0, userId);
+                if (uid >= 0) {
+                    result.add(uid);
+                }
+            }
+            synchronized (mGlobalLock) {
+                mCompanionAppUidsMap.put(userId, result);
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
index bbbf11d..9f7cb3d 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
@@ -49,7 +49,7 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowThumbnail" : TAG_WM;
 
     private final AppWindowToken mAppToken;
-    private final SurfaceControl mSurfaceControl;
+    private SurfaceControl mSurfaceControl;
     private final SurfaceAnimator mSurfaceAnimator;
     private final int mWidth;
     private final int mHeight;
@@ -68,10 +68,21 @@
      */
     AppWindowThumbnail(Transaction t, AppWindowToken appToken, GraphicBuffer thumbnailHeader,
             boolean relative) {
+        this(t, appToken, thumbnailHeader, relative, new Surface(), null);
+    }
+
+    AppWindowThumbnail(Transaction t, AppWindowToken appToken, GraphicBuffer thumbnailHeader,
+            boolean relative, Surface drawSurface, SurfaceAnimator animator) {
         mAppToken = appToken;
         mRelative = relative;
-        mSurfaceAnimator =
+        if (animator != null) {
+            mSurfaceAnimator = animator;
+        } else {
+            // We can't use a delegating constructor since we need to
+            // reference this::onAnimationFinished
+            mSurfaceAnimator =
                 new SurfaceAnimator(this, this::onAnimationFinished, appToken.mWmService);
+        }
         mWidth = thumbnailHeader.getWidth();
         mHeight = thumbnailHeader.getHeight();
 
@@ -95,7 +106,6 @@
         }
 
         // Transfer the thumbnail to the surface
-        Surface drawSurface = new Surface();
         drawSurface.copyFrom(mSurfaceControl);
         drawSurface.attachAndQueueBuffer(thumbnailHeader);
         drawSurface.release();
@@ -145,6 +155,7 @@
     void destroy() {
         mSurfaceAnimator.cancelAnimation();
         getPendingTransaction().remove(mSurfaceControl);
+        mSurfaceControl = null;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 1e1c482..a53f85d 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -153,7 +153,6 @@
 
     /** @see WindowContainer#fillsParent() */
     private boolean mFillsParent;
-    boolean layoutConfigChanges;
     boolean mShowForAllUsers;
     int mTargetSdk;
 
@@ -337,7 +336,7 @@
     AppWindowToken(WindowManagerService service, IApplicationToken token,
             ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
             long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
-            int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
+            int targetSdk, int orientation, int rotationAnimationHint,
             boolean launchTaskBehind, boolean alwaysFocusable,
             ActivityRecord activityRecord) {
         this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
@@ -348,7 +347,6 @@
         mShowForAllUsers = showForAllUsers;
         mTargetSdk = targetSdk;
         mOrientation = orientation;
-        layoutConfigChanges = (configChanges & (CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION)) != 0;
         mLaunchTaskBehind = launchTaskBehind;
         mAlwaysFocusable = alwaysFocusable;
         mRotationAnimationHint = rotationAnimationHint;
@@ -666,7 +664,7 @@
             }
         }
 
-        if (isSelfAnimating()) {
+        if (isReallyAnimating()) {
             delayed = true;
         } else {
 
@@ -1976,7 +1974,7 @@
         final boolean surfaceReady = w.isDrawnLw()  // Regular case
                 || w.mWinAnimator.mSurfaceDestroyDeferred  // The preserved surface is still ready.
                 || w.isDragResizeChanged();  // Waiting for relayoutWindow to call preserveSurface.
-        final boolean needsLetterbox = w.isLetterboxedAppWindow() && fillsParent() && surfaceReady;
+        final boolean needsLetterbox = surfaceReady && w.isLetterboxedAppWindow() && fillsParent();
         if (needsLetterbox) {
             if (mLetterbox == null) {
                 mLetterbox = new Letterbox(() -> makeChildSurface(null));
@@ -3132,8 +3130,17 @@
         }
     }
 
+    /** Gets the inner bounds of letterbox. The bounds will be empty if there is no letterbox. */
+    void getLetterboxInnerBounds(Rect outBounds) {
+        if (mLetterbox != null) {
+            outBounds.set(mLetterbox.getInnerFrame());
+        } else {
+            outBounds.setEmpty();
+        }
+    }
+
     /**
-     * @eturn true if there is a letterbox and any part of that letterbox overlaps with
+     * @return {@code true} if there is a letterbox and any part of that letterbox overlaps with
      * the given {@code rect}.
      */
     boolean isLetterboxOverlappingWith(Rect rect) {
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index 9bc8462..90bb494 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -51,6 +51,7 @@
     private static final int MSG_NAV_BAR_VISIBILITY_CHANGED = 1;
 
     protected final String mTag;
+    protected final int mDisplayId;
     private final int mTransientFlag;
     private final int mUnhideFlag;
     private final int mTranslucentFlag;
@@ -74,9 +75,10 @@
 
     private OnBarVisibilityChangedListener mVisibilityChangeListener;
 
-    BarController(String tag, int transientFlag, int unhideFlag, int translucentFlag,
+    BarController(String tag, int displayId, int transientFlag, int unhideFlag, int translucentFlag,
             int statusBarManagerId, int translucentWmFlag, int transparentFlag) {
         mTag = "BarController." + tag;
+        mDisplayId = displayId;
         mTransientFlag = transientFlag;
         mUnhideFlag = unhideFlag;
         mTranslucentFlag = translucentFlag;
@@ -173,8 +175,9 @@
         }
         final boolean wasVis = mWin.isVisibleLw();
         final boolean wasAnim = mWin.isAnimatingLw();
-        final boolean change = show ? mWin.showLw(!mNoAnimationOnNextShow && !skipAnimation())
-                : mWin.hideLw(!mNoAnimationOnNextShow && !skipAnimation());
+        final boolean skipAnim = skipAnimation();
+        final boolean change = show ? mWin.showLw(!mNoAnimationOnNextShow && !skipAnim)
+                : mWin.hideLw(!mNoAnimationOnNextShow && !skipAnim);
         mNoAnimationOnNextShow = false;
         final int state = computeStateLw(wasVis, wasAnim, mWin, change);
         final boolean stateChanged = updateStateLw(state);
@@ -229,7 +232,7 @@
                 public void run() {
                     StatusBarManagerInternal statusbar = getStatusBarInternal();
                     if (statusbar != null) {
-                        statusbar.setWindowState(mWin.getDisplayId(), mStatusBarManagerId, state);
+                        statusbar.setWindowState(mDisplayId, mStatusBarManagerId, state);
                     }
                 }
             });
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index bec72f5..e7dac9d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -28,6 +28,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
@@ -655,7 +656,7 @@
         if (DEBUG_LAYOUT && !w.mLayoutAttached) {
             Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame
                     + " mLayoutAttached=" + w.mLayoutAttached
-                    + " screen changed=" + w.isConfigChanged());
+                    + " config reported=" + w.isLastConfigReportedToClient());
             final AppWindowToken atoken = w.mAppToken;
             if (gone) Slog.v(TAG, "  GONE: mViewVisibility=" + w.mViewVisibility
                     + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.isHidden()
@@ -670,42 +671,34 @@
         // If this view is GONE, then skip it -- keep the current frame, and let the caller know
         // so they can ignore it if they want.  (We do the normal layout for INVISIBLE windows,
         // since that means "perform layout as normal, just don't display").
-        if (!gone || !w.mHaveFrame || w.mLayoutNeeded
-                || ((w.isConfigChanged() || w.setReportResizeHints())
-                && !w.isGoneForLayoutLw() &&
-                ((w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
-                        (w.mHasSurface && w.mAppToken != null &&
-                                w.mAppToken.layoutConfigChanges)))) {
-            if (!w.mLayoutAttached) {
-                if (mTmpInitial) {
-                    //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
-                    w.resetContentChanged();
-                }
-                if (w.mAttrs.type == TYPE_DREAM) {
-                    // Don't layout windows behind a dream, so that if it does stuff like hide
-                    // the status bar we won't get a bad transition when it goes away.
-                    mTmpWindow = w;
-                }
-                w.mLayoutNeeded = false;
-                w.prelayout();
-                final boolean firstLayout = !w.isLaidOut();
-                getDisplayPolicy().layoutWindowLw(w, null, mDisplayFrames);
-                w.mLayoutSeq = mLayoutSeq;
-
-                // If this is the first layout, we need to initialize the last inset values as
-                // otherwise we'd immediately cause an unnecessary resize.
-                if (firstLayout) {
-                    w.updateLastInsetValues();
-                }
-
-                if (w.mAppToken != null) {
-                    w.mAppToken.layoutLetterbox(w);
-                }
-
-                if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame=" + w.getFrameLw()
-                        + " mContainingFrame=" + w.getContainingFrame()
-                        + " mDisplayFrame=" + w.getDisplayFrameLw());
+        if ((!gone || !w.mHaveFrame || w.mLayoutNeeded) && !w.mLayoutAttached) {
+            if (mTmpInitial) {
+                w.resetContentChanged();
             }
+            if (w.mAttrs.type == TYPE_DREAM) {
+                // Don't layout windows behind a dream, so that if it does stuff like hide
+                // the status bar we won't get a bad transition when it goes away.
+                mTmpWindow = w;
+            }
+            w.mLayoutNeeded = false;
+            w.prelayout();
+            final boolean firstLayout = !w.isLaidOut();
+            getDisplayPolicy().layoutWindowLw(w, null, mDisplayFrames);
+            w.mLayoutSeq = mLayoutSeq;
+
+            // If this is the first layout, we need to initialize the last inset values as
+            // otherwise we'd immediately cause an unnecessary resize.
+            if (firstLayout) {
+                w.updateLastInsetValues();
+            }
+
+            if (w.mAppToken != null) {
+                w.mAppToken.layoutLetterbox(w);
+            }
+
+            if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame=" + w.getFrameLw()
+                    + " mContainingFrame=" + w.getContainingFrame()
+                    + " mDisplayFrame=" + w.getDisplayFrameLw());
         }
     };
 
@@ -1525,7 +1518,7 @@
         final int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
         final int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
 
-        mDisplayPolicy.configure(width, height, shortSizeDp);
+        mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
         mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp);
 
         mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
@@ -1734,7 +1727,7 @@
             mWmService.mH.sendEmptyMessage(REPORT_HARD_KEYBOARD_STATUS_CHANGE);
         }
 
-        mDisplayPolicy.updateConfigurationDependentBehaviors();
+        mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
 
         // Let the policy update hidden states.
         config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
@@ -3094,7 +3087,7 @@
 
     /** Updates the layer assignment of windows on this display. */
     void assignWindowLayers(boolean setLayoutNeeded) {
-        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers");
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers");
         assignChildLayers(getPendingTransaction());
         if (setLayoutNeeded) {
             setLayoutNeeded();
@@ -3105,7 +3098,7 @@
         // prepareSurfaces. This allows us to synchronize Z-ordering changes with
         // the hiding and showing of surfaces.
         scheduleAnimation();
-        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
     }
 
     // TODO: This should probably be called any time a visual change is made to the hierarchy like
@@ -3219,13 +3212,11 @@
                 "Proposed new IME target: " + target + " for display: " + getDisplayId());
 
         // Now, a special case -- if the last target's window is in the process of exiting, but
-        // not removed, and the new target is home, keep on the last target to avoid flicker.
-        // Home is a special case since its above other stacks in the ordering list, but layed
-        // out below the others.
+        // not removed, keep on the last target to avoid IME flicker.
         if (curTarget != null && !curTarget.mRemoved && curTarget.isDisplayedLw()
-                && curTarget.isClosing() && (target == null || target.isActivityTypeHome())) {
-            if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "New target is home while current target is "
-                    + "closing, not changing");
+                && curTarget.isClosing()) {
+            if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Not changing target till current window is"
+                    + " closing and not removed");
             return curTarget;
         }
 
@@ -3659,9 +3650,14 @@
             // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating.
             pendingLayoutChanges = 0;
 
-            mDisplayPolicy.beginPostLayoutPolicyLw();
-            forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */);
-            pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw();
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy");
+            try {
+                mDisplayPolicy.beginPostLayoutPolicyLw();
+                forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */);
+                pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw();
+            } finally {
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+            }
             if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
                     "after finishPostLayoutPolicyLw", pendingLayoutChanges);
                 mInsetsStateController.onPostLayout();
@@ -3670,7 +3666,13 @@
         mTmpApplySurfaceChangesTransactionState.reset();
 
         mTmpRecoveringMemory = recoveringMemory;
-        forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
+
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges");
+        try {
+            forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
         prepareSurfaces();
 
         mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent;
@@ -3720,11 +3722,6 @@
         out.set(left, top, left + width, top + height);
     }
 
-    @Override
-    public void getBounds(Rect out) {
-        calculateBounds(mDisplayInfo, out);
-    }
-
     private void getBounds(Rect out, int orientation) {
         getBounds(out);
 
@@ -3746,6 +3743,15 @@
     }
 
     void performLayout(boolean initial, boolean updateInputWindows) {
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performLayout");
+        try {
+            performLayoutNoTrace(initial, updateInputWindows);
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+    }
+
+    private void performLayoutNoTrace(boolean initial, boolean updateInputWindows) {
         if (!isLayoutNeeded()) {
             return;
         }
@@ -3755,13 +3761,14 @@
         final int dh = mDisplayInfo.logicalHeight;
         if (DEBUG_LAYOUT) {
             Slog.v(TAG, "-------------------------------------");
-            Slog.v(TAG, "performLayout: needed=" + isLayoutNeeded() + " dw=" + dw + " dh=" + dh);
+            Slog.v(TAG, "performLayout: needed=" + isLayoutNeeded() + " dw=" + dw
+                    + " dh=" + dh);
         }
 
         mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
                 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
-        // TODO: Not sure if we really need to set the rotation here since we are updating from the
-        // display info above...
+        // TODO: Not sure if we really need to set the rotation here since we are updating from
+        // the display info above...
         mDisplayFrames.mRotation = mRotation;
         mDisplayPolicy.beginLayoutLw(mDisplayFrames, getConfiguration().uiMode);
 
@@ -4801,20 +4808,25 @@
 
     @Override
     void prepareSurfaces() {
-        final ScreenRotationAnimation screenRotationAnimation =
-                mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
-        if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
-            screenRotationAnimation.getEnterTransformation().getMatrix().getValues(mTmpFloats);
-            mPendingTransaction.setMatrix(mWindowingLayer,
-                    mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
-                    mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
-            mPendingTransaction.setPosition(mWindowingLayer,
-                    mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
-            mPendingTransaction.setAlpha(mWindowingLayer,
-                    screenRotationAnimation.getEnterTransformation().getAlpha());
-        }
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareSurfaces");
+        try {
+            final ScreenRotationAnimation screenRotationAnimation =
+                    mWmService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
+            if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
+                screenRotationAnimation.getEnterTransformation().getMatrix().getValues(mTmpFloats);
+                mPendingTransaction.setMatrix(mWindowingLayer,
+                        mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
+                        mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
+                mPendingTransaction.setPosition(mWindowingLayer,
+                        mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
+                mPendingTransaction.setAlpha(mWindowingLayer,
+                        screenRotationAnimation.getEnterTransformation().getAlpha());
+            }
 
-        super.prepareSurfaces();
+            super.prepareSurfaces();
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
     }
 
     void assignStackOrdering() {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 6605f3c6..bbb857f 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -26,6 +26,8 @@
 import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
 import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.InsetsState.TYPE_TOP_GESTURES;
+import static android.view.InsetsState.TYPE_TOP_TAPPABLE_ELEMENT;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
 import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
@@ -40,6 +42,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
@@ -103,13 +106,16 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.localLOGV;
 
+import android.Manifest.permission;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.Px;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.StatusBarManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.graphics.Insets;
 import android.graphics.PixelFormat;
@@ -149,6 +155,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ScreenShapeHelper;
 import com.android.internal.util.ScreenshotHelper;
+import com.android.internal.util.function.TriConsumer;
 import com.android.internal.widget.PointerLocationView;
 import com.android.server.LocalServices;
 import com.android.server.UiThread;
@@ -212,6 +219,12 @@
     private final Object mServiceAcquireLock = new Object();
     private StatusBarManagerInternal mStatusBarManagerInternal;
 
+    @Px
+    private int mBottomGestureAdditionalInset;
+    @Px
+    private int mSideGestureInset;
+    private boolean mNavigationBarLetsThroughTaps;
+
     private StatusBarManagerInternal getStatusBarManagerInternal() {
         synchronized (mServiceAcquireLock) {
             if (mStatusBarManagerInternal == null) {
@@ -255,15 +268,12 @@
     private int[] mNavigationBarHeightForRotationInCarMode = new int[4];
     private int[] mNavigationBarWidthForRotationInCarMode = new int[4];
 
-    private final StatusBarController mStatusBarController = new StatusBarController();
+    /** Cached value of {@link ScreenShapeHelper#getWindowOutsetBottomPx} */
+    @Px private int mWindowOutsetBottom;
 
-    private final BarController mNavigationBarController = new BarController("NavigationBar",
-            View.NAVIGATION_BAR_TRANSIENT,
-            View.NAVIGATION_BAR_UNHIDE,
-            View.NAVIGATION_BAR_TRANSLUCENT,
-            StatusBarManager.WINDOW_NAVIGATION_BAR,
-            FLAG_TRANSLUCENT_NAVIGATION,
-            View.NAVIGATION_BAR_TRANSPARENT);
+    private final StatusBarController mStatusBarController;
+
+    private final BarController mNavigationBarController;
 
     private final BarController.OnBarVisibilityChangedListener mNavBarVisibilityListener =
             new BarController.OnBarVisibilityChangedListener() {
@@ -410,12 +420,22 @@
         mDisplayContent = displayContent;
         mLock = service.getWindowManagerLock();
 
+        final int displayId = displayContent.getDisplayId();
+        mStatusBarController = new StatusBarController(displayId);
+        mNavigationBarController = new BarController("NavigationBar",
+                displayId,
+                View.NAVIGATION_BAR_TRANSIENT,
+                View.NAVIGATION_BAR_UNHIDE,
+                View.NAVIGATION_BAR_TRANSLUCENT,
+                StatusBarManager.WINDOW_NAVIGATION_BAR,
+                FLAG_TRANSLUCENT_NAVIGATION,
+                View.NAVIGATION_BAR_TRANSPARENT);
+
         final Resources r = mContext.getResources();
         mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer);
         mDeskDockEnablesAccelerometer = r.getBoolean(R.bool.config_deskDockEnablesAccelerometer);
         mTranslucentDecorEnabled = r.getBoolean(R.bool.config_enableTranslucentDecor);
         mForceShowSystemBarsFromExternal = r.getBoolean(R.bool.config_forceShowSystemBars);
-        updateConfigurationDependentBehaviors();
 
         mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(
                 Context.ACCESSIBILITY_SERVICE);
@@ -522,7 +542,6 @@
             if (mWindowSleepToken != null) {
                 return;
             }
-            final int displayId = displayContent.getDisplayId();
             mWindowSleepToken = service.mAtmInternal.acquireSleepToken(
                     "WindowSleepTokenOnDisplay" + displayId, displayId);
         };
@@ -567,15 +586,6 @@
         return mDisplayContent.getDisplayId();
     }
 
-    void configure(int width, int height, int shortSizeDp) {
-        // Allow the navigation bar to move on non-square small devices (phones).
-        mNavigationBarCanMove = width != height && shortSizeDp < 600;
-    }
-
-    void updateConfigurationDependentBehaviors() {
-        mNavBarOpacityMode = mContext.getResources().getInteger(R.integer.config_navBarOpacityMode);
-    }
-
     public void setHdmiPlugged(boolean plugged) {
         setHdmiPlugged(plugged, false /* force */);
     }
@@ -741,6 +751,11 @@
         return true;
     }
 
+    private boolean hasStatusBarServicePermission(int pid, int uid) {
+        return mContext.checkPermission(permission.STATUS_BAR_SERVICE, pid, uid)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
     /**
      * Sanitize the layout parameters coming from a client.  Allows the policy
      * to do things like ensure that windows of a specific type can't take
@@ -750,7 +765,7 @@
      * are modified in-place.
      */
     public void adjustWindowParamsLw(WindowState win, WindowManager.LayoutParams attrs,
-            boolean hasStatusBarServicePermission) {
+            int callingPid, int callingUid) {
 
         final boolean isScreenDecor = (attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0;
         if (mScreenDecorWindows.contains(win)) {
@@ -758,7 +773,7 @@
                 // No longer has the flag set, so remove from the set.
                 mScreenDecorWindows.remove(win);
             }
-        } else if (isScreenDecor && hasStatusBarServicePermission) {
+        } else if (isScreenDecor && hasStatusBarServicePermission(callingPid, callingUid)) {
             mScreenDecorWindows.add(win);
         }
 
@@ -856,11 +871,14 @@
                 if (mDisplayContent.isDefaultDisplay) {
                     mService.mPolicy.setKeyguardCandidateLw(win);
                 }
-                mDisplayContent.setInsetProvider(TYPE_TOP_BAR, win,
+                final TriConsumer<DisplayFrames, WindowState, Rect> frameProvider =
                         (displayFrames, windowState, rect) -> {
                             rect.top = 0;
                             rect.bottom = getStatusBarHeight(displayFrames);
-                        });
+                        };
+                mDisplayContent.setInsetProvider(TYPE_TOP_BAR, win, frameProvider);
+                mDisplayContent.setInsetProvider(TYPE_TOP_GESTURES, win, frameProvider);
+                mDisplayContent.setInsetProvider(TYPE_TOP_TAPPABLE_ELEMENT, win, frameProvider);
                 break;
             case TYPE_NAVIGATION_BAR:
                 mContext.enforceCallingOrSelfPermission(
@@ -877,6 +895,31 @@
                         mNavBarVisibilityListener, true);
                 mDisplayContent.setInsetProvider(InsetsState.TYPE_NAVIGATION_BAR,
                         win, null /* frameProvider */);
+                mDisplayContent.setInsetProvider(InsetsState.TYPE_BOTTOM_GESTURES, win,
+                        (displayFrames, windowState, inOutFrame) -> {
+                            inOutFrame.top -= mBottomGestureAdditionalInset;
+                        });
+                mDisplayContent.setInsetProvider(InsetsState.TYPE_LEFT_GESTURES, win,
+                        (displayFrames, windowState, inOutFrame) -> {
+                            inOutFrame.left = 0;
+                            inOutFrame.top = 0;
+                            inOutFrame.bottom = displayFrames.mDisplayHeight;
+                            inOutFrame.right = displayFrames.mUnrestricted.left + mSideGestureInset;
+                        });
+                mDisplayContent.setInsetProvider(InsetsState.TYPE_RIGHT_GESTURES, win,
+                        (displayFrames, windowState, inOutFrame) -> {
+                            inOutFrame.left = displayFrames.mUnrestricted.right - mSideGestureInset;
+                            inOutFrame.top = 0;
+                            inOutFrame.bottom = displayFrames.mDisplayHeight;
+                            inOutFrame.right = displayFrames.mDisplayWidth;
+                        });
+                mDisplayContent.setInsetProvider(InsetsState.TYPE_BOTTOM_TAPPABLE_ELEMENT, win,
+                        (displayFrames, windowState, inOutFrame) -> {
+                            if ((windowState.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0
+                                    || mNavigationBarLetsThroughTaps) {
+                                inOutFrame.setEmpty();
+                            }
+                        });
                 if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                 break;
             case TYPE_NAVIGATION_BAR_PANEL:
@@ -1169,7 +1212,7 @@
 
         final boolean useOutsets = outOutsets != null && shouldUseOutsets(attrs, fl);
         if (useOutsets) {
-            int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
+            int outset = mWindowOutsetBottom;
             if (outset > 0) {
                 if (displayRotation == Surface.ROTATION_0) {
                     outOutsets.bottom += outset;
@@ -1489,12 +1532,13 @@
         }
         // apply any navigation bar insets
         sTmpRect.setEmpty();
-        mStatusBar.getWindowFrames().setFrames(displayFrames.mUnrestricted /* parentFrame */,
+        final WindowFrames windowFrames = mStatusBar.getWindowFrames();
+        windowFrames.setFrames(displayFrames.mUnrestricted /* parentFrame */,
                 displayFrames.mUnrestricted /* displayFrame */,
                 displayFrames.mStable /* overscanFrame */, displayFrames.mStable /* contentFrame */,
                 displayFrames.mStable /* visibleFrame */, sTmpRect /* decorFrame */,
                 displayFrames.mStable /* stableFrame */, displayFrames.mStable /* outsetFrame */);
-        mStatusBar.getWindowFrames().setDisplayCutout(displayFrames.mDisplayCutout);
+        windowFrames.setDisplayCutout(displayFrames.mDisplayCutout);
 
         // Let the status bar determine its size.
         mStatusBar.computeFrameLw();
@@ -1534,8 +1578,9 @@
                     "dock=%s content=%s cur=%s", dockFrame.toString(),
                     displayFrames.mContent.toString(), displayFrames.mCurrent.toString()));
 
-            if (!mStatusBar.isAnimatingLw() && !statusBarTranslucent
-                    && !mStatusBarController.wasRecentlyTranslucent()) {
+            if (!statusBarTranslucent && !mStatusBarController.wasRecentlyTranslucent()
+                    && !mStatusBar.isAnimatingLw()) {
+
                 // If the opaque status bar is currently requested to be visible, and not in the
                 // process of animating on or off, then we can tell the app that it is covered by
                 // it.
@@ -2190,7 +2235,7 @@
             final Rect osf = windowFrames.mOutsetFrame;
             osf.set(cf.left, cf.top, cf.right, cf.bottom);
             windowFrames.setHasOutsets(true);
-            int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
+            int outset = mWindowOutsetBottom;
             if (outset > 0) {
                 int rotation = displayFrames.mRotation;
                 if (rotation == Surface.ROTATION_0) {
@@ -2346,7 +2391,7 @@
         }
 
         // Voice interaction overrides both top fullscreen and top docked.
-        if (affectsSystemUi && win.getAttrs().type == TYPE_VOICE_INTERACTION) {
+        if (affectsSystemUi && attrs.type == TYPE_VOICE_INTERACTION) {
             if (mTopFullscreenOpaqueWindowState == null) {
                 mTopFullscreenOpaqueWindowState = win;
                 if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
@@ -2541,6 +2586,7 @@
      */
     public void onOverlayChangedLw() {
         onConfigurationChanged();
+        mSystemGestures.onConfigurationChanged();
     }
 
     /**
@@ -2602,9 +2648,31 @@
                     res.getDimensionPixelSize(R.dimen.navigation_bar_width_car_mode);
         }
 
+        mNavBarOpacityMode = res.getInteger(R.integer.config_navBarOpacityMode);
+        mSideGestureInset = res.getDimensionPixelSize(R.dimen.config_backGestureInset);
+        mNavigationBarLetsThroughTaps = res.getBoolean(R.bool.config_navBarTapThrough);
+
         // EXPERIMENT TODO(b/113952590): Remove once experiment in bug is completed
         mExperiments.onConfigurationChanged(uiContext);
         // EXPERIMENT END
+
+        // EXPERIMENT: TODO(b/113952590): Replace with real code after experiment.
+        // This should calculate how much above the frame we accept gestures. Currently,
+        // we extend the frame to capture the gestures, so this is 0.
+        mBottomGestureAdditionalInset = mExperiments.getNavigationBarFrameHeight()
+                - mExperiments.getNavigationBarFrameHeight();
+        // EXPERIMENT END
+
+        updateConfigurationAndScreenSizeDependentBehaviors();
+        mWindowOutsetBottom = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
+    }
+
+    void updateConfigurationAndScreenSizeDependentBehaviors() {
+        final Context uiContext = getSystemUiContext();
+        final Resources res = uiContext.getResources();
+        mNavigationBarCanMove =
+                mDisplayContent.mBaseDisplayWidth != mDisplayContent.mBaseDisplayHeight
+                        && res.getBoolean(R.bool.config_navBarCanMove);
     }
 
     @VisibleForTesting
@@ -2960,6 +3028,8 @@
         mLastDockedStackSysUiFlags = dockedVisibility;
         mLastFocusNeedsMenu = needsMenu;
         mFocusedApp = win.getAppToken();
+        mLastNonDockedStackBounds.set(mNonDockedStackBounds);
+        mLastDockedStackBounds.set(mDockedStackBounds);
         final Rect fullscreenStackBounds = new Rect(mNonDockedStackBounds);
         final Rect dockedStackBounds = new Rect(mDockedStackBounds);
         mHandler.post(() -> {
@@ -3411,6 +3481,10 @@
         }
         if (mNavigationBar != null) {
             pw.print(prefix); pw.print("mNavigationBar="); pw.println(mNavigationBar);
+            pw.print(prefix); pw.print("mNavBarOpacityMode="); pw.println(mNavBarOpacityMode);
+            pw.print(prefix); pw.print("mNavigationBarCanMove="); pw.println(mNavigationBarCanMove);
+            pw.print(prefix); pw.print("mNavigationBarPosition=");
+            pw.println(mNavigationBarPosition);
         }
         if (mFocusedWindow != null) {
             pw.print(prefix); pw.print("mFocusedWindow="); pw.println(mFocusedWindow);
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index db96847..a46fa13 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -26,6 +26,8 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.app.WindowConfiguration;
 import android.os.Environment;
 import android.provider.Settings;
@@ -33,6 +35,7 @@
 import android.util.Slog;
 import android.util.Xml;
 import android.view.Display;
+import android.view.DisplayAddress;
 import android.view.DisplayInfo;
 import android.view.Surface;
 
@@ -47,10 +50,11 @@
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 
@@ -60,9 +64,33 @@
 class DisplayWindowSettings {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayWindowSettings" : TAG_WM;
 
+    private static final int IDENTIFIER_UNIQUE_ID = 0;
+    private static final int IDENTIFIER_PORT = 1;
+    @IntDef(prefix = { "IDENTIFIER_" }, value = {
+            IDENTIFIER_UNIQUE_ID,
+            IDENTIFIER_PORT,
+    })
+    @interface DisplayIdentifierType {}
+
     private final WindowManagerService mService;
-    private final AtomicFile mFile;
-    private final HashMap<String, Entry> mEntries = new HashMap<String, Entry>();
+    private final HashMap<String, Entry> mEntries = new HashMap<>();
+    private final SettingPersister mStorage;
+
+    /**
+     * The preferred type of a display identifier to use when storing and retrieving entries.
+     * {@link #getIdentifier(DisplayInfo)} must be used to get current preferred identifier for each
+     * display. It will fall back to using {@link #IDENTIFIER_UNIQUE_ID} if the currently selected
+     * one is not applicable to a particular display.
+     */
+    @DisplayIdentifierType
+    private int mIdentifier = IDENTIFIER_UNIQUE_ID;
+
+    /** Interface for persisting the display window settings. */
+    interface SettingPersister {
+        InputStream openRead() throws IOException;
+        OutputStream startWrite() throws IOException;
+        void finishWrite(OutputStream os, boolean success);
+    }
 
     private static class Entry {
         private final String mName;
@@ -88,6 +116,26 @@
             mName = name;
         }
 
+        private Entry(String name, Entry copyFrom) {
+            this(name);
+            mOverscanLeft = copyFrom.mOverscanLeft;
+            mOverscanTop = copyFrom.mOverscanTop;
+            mOverscanRight = copyFrom.mOverscanRight;
+            mOverscanBottom = copyFrom.mOverscanBottom;
+            mWindowingMode = copyFrom.mWindowingMode;
+            mUserRotationMode = copyFrom.mUserRotationMode;
+            mUserRotation = copyFrom.mUserRotation;
+            mForcedWidth = copyFrom.mForcedWidth;
+            mForcedHeight = copyFrom.mForcedHeight;
+            mForcedDensity = copyFrom.mForcedDensity;
+            mForcedScalingMode = copyFrom.mForcedScalingMode;
+            mRemoveContentMode = copyFrom.mRemoveContentMode;
+            mShouldShowWithInsecureKeyguard = copyFrom.mShouldShowWithInsecureKeyguard;
+            mShouldShowSystemDecors = copyFrom.mShouldShowSystemDecors;
+            mShouldShowIme = copyFrom.mShouldShowIme;
+            mFixedToUserRotation = copyFrom.mFixedToUserRotation;
+        }
+
         /** @return {@code true} if all values are default. */
         private boolean isEmpty() {
             return mOverscanLeft == 0 && mOverscanTop == 0 && mOverscanRight == 0
@@ -106,29 +154,46 @@
     }
 
     DisplayWindowSettings(WindowManagerService service) {
-        this(service, new File(Environment.getDataDirectory(), "system"));
+        this(service, new AtomicFileStorage());
     }
 
     @VisibleForTesting
-    DisplayWindowSettings(WindowManagerService service, File folder) {
+    DisplayWindowSettings(WindowManagerService service, SettingPersister storageImpl) {
         mService = service;
-        mFile = new AtomicFile(new File(folder, "display_settings.xml"), "wm-displays");
+        mStorage = storageImpl;
         readSettings();
     }
 
-    private Entry getEntry(DisplayInfo displayInfo) {
-        // Try to get the entry with the unique if possible.
-        // Else, fall back on the display name.
+    private @Nullable Entry getEntry(DisplayInfo displayInfo) {
+        final String identifier = getIdentifier(displayInfo);
         Entry entry;
-        if (displayInfo.uniqueId == null || (entry = mEntries.get(displayInfo.uniqueId)) == null) {
-            entry = mEntries.get(displayInfo.name);
+        // Try to get corresponding entry using preferred identifier for the current config.
+        if ((entry = mEntries.get(identifier)) != null) {
+            return entry;
         }
-        return entry;
+        // Else, fall back to the display name.
+        if ((entry = mEntries.get(displayInfo.name)) != null) {
+            // Found an entry stored with old identifier - upgrade to the new type now.
+            return updateIdentifierForEntry(entry, displayInfo);
+        }
+        return null;
     }
 
     private Entry getOrCreateEntry(DisplayInfo displayInfo) {
         final Entry entry = getEntry(displayInfo);
-        return entry != null ? entry : new Entry(displayInfo.uniqueId);
+        return entry != null ? entry : new Entry(getIdentifier(displayInfo));
+    }
+
+    /**
+     * Upgrades the identifier of a legacy entry. Does it by copying the data from the old record
+     * and clearing the old key in memory. The entry will be written to storage next time when a
+     * setting changes.
+     */
+    private Entry updateIdentifierForEntry(Entry entry, DisplayInfo displayInfo) {
+        final Entry newEntry = new Entry(getIdentifier(displayInfo), entry);
+        removeEntry(displayInfo);
+        mEntries.put(newEntry.mName, newEntry);
+        return newEntry;
     }
 
     void setOverscanLocked(DisplayInfo displayInfo, int left, int top, int right, int bottom) {
@@ -371,12 +436,11 @@
     }
 
     private void readSettings() {
-        FileInputStream stream;
+        InputStream stream;
         try {
-            stream = mFile.openRead();
-        } catch (FileNotFoundException e) {
-            Slog.i(TAG, "No existing display settings " + mFile.getBaseFile()
-                    + "; starting empty");
+            stream = mStorage.openRead();
+        } catch (IOException e) {
+            Slog.i(TAG, "No existing display settings, starting empty");
             return;
         }
         boolean success = false;
@@ -403,6 +467,8 @@
                 String tagName = parser.getName();
                 if (tagName.equals("display")) {
                     readDisplay(parser);
+                } else if (tagName.equals("config")) {
+                    readConfig(parser);
                 } else {
                     Slog.w(TAG, "Unknown element under <display-settings>: "
                             + parser.getName());
@@ -491,22 +557,26 @@
         XmlUtils.skipCurrentTag(parser);
     }
 
+    private void readConfig(XmlPullParser parser) throws NumberFormatException,
+            XmlPullParserException, IOException {
+        mIdentifier = getIntAttribute(parser, "identifier");
+        XmlUtils.skipCurrentTag(parser);
+    }
+
     private void writeSettingsIfNeeded(Entry changedEntry, DisplayInfo displayInfo) {
-        if (changedEntry.isEmpty()) {
-            boolean removed = mEntries.remove(displayInfo.uniqueId) != null;
-            // Legacy name might have been in used, so we need to clear it.
-            removed |= mEntries.remove(displayInfo.name) != null;
-            if (!removed) {
-                // The entry didn't exist so nothing is changed and no need to update the file.
-                return;
-            }
-        } else {
-            mEntries.put(displayInfo.uniqueId, changedEntry);
+        if (changedEntry.isEmpty() && !removeEntry(displayInfo)) {
+            // The entry didn't exist so nothing is changed and no need to update the file.
+            return;
         }
 
-        FileOutputStream stream;
+        mEntries.put(getIdentifier(displayInfo), changedEntry);
+        writeSettings();
+    }
+
+    private void writeSettings() {
+        OutputStream stream;
         try {
-            stream = mFile.startWrite();
+            stream = mStorage.startWrite();
         } catch (IOException e) {
             Slog.w(TAG, "Failed to write display settings: " + e);
             return;
@@ -516,8 +586,13 @@
             XmlSerializer out = new FastXmlSerializer();
             out.setOutput(stream, StandardCharsets.UTF_8.name());
             out.startDocument(null, true);
+
             out.startTag(null, "display-settings");
 
+            out.startTag(null, "config");
+            out.attribute(null, "identifier", Integer.toString(mIdentifier));
+            out.endTag(null, "config");
+
             for (Entry entry : mEntries.values()) {
                 out.startTag(null, "display");
                 out.attribute(null, "name", entry.mName);
@@ -578,10 +653,66 @@
 
             out.endTag(null, "display-settings");
             out.endDocument();
-            mFile.finishWrite(stream);
+            mStorage.finishWrite(stream, true /* success */);
         } catch (IOException e) {
-            Slog.w(TAG, "Failed to write display settings, restoring backup.", e);
-            mFile.failWrite(stream);
+            Slog.w(TAG, "Failed to write display window settings.", e);
+            mStorage.finishWrite(stream, false /* success */);
+        }
+    }
+
+    /**
+     * Removes an entry from {@link #mEntries} cache. Looks up by new and previously used
+     * identifiers.
+     */
+    private boolean removeEntry(DisplayInfo displayInfo) {
+        // Remove entry based on primary identifier.
+        boolean removed = mEntries.remove(getIdentifier(displayInfo)) != null;
+        // Ensure that legacy entries are cleared as well.
+        removed |= mEntries.remove(displayInfo.uniqueId) != null;
+        removed |= mEntries.remove(displayInfo.name) != null;
+        return removed;
+    }
+
+    /** Gets the identifier of choice for the current config. */
+    private String getIdentifier(DisplayInfo displayInfo) {
+        if (mIdentifier == IDENTIFIER_PORT && displayInfo.address != null) {
+            // Config suggests using port as identifier for physical displays.
+            if (displayInfo.address instanceof DisplayAddress.Physical) {
+                return "port:" + ((DisplayAddress.Physical) displayInfo.address).getPort();
+            }
+        }
+        return displayInfo.uniqueId;
+    }
+
+    private static class AtomicFileStorage implements SettingPersister {
+        private final AtomicFile mAtomicFile;
+
+        AtomicFileStorage() {
+            final File folder = new File(Environment.getDataDirectory(), "system");
+            mAtomicFile = new AtomicFile(new File(folder, "display_settings.xml"), "wm-displays");
+        }
+
+        @Override
+        public InputStream openRead() throws FileNotFoundException {
+            return mAtomicFile.openRead();
+        }
+
+        @Override
+        public OutputStream startWrite() throws IOException {
+            return mAtomicFile.startWrite();
+        }
+
+        @Override
+        public void finishWrite(OutputStream os, boolean success) {
+            if (!(os instanceof FileOutputStream)) {
+                throw new IllegalArgumentException("Unexpected OutputStream as argument: " + os);
+            }
+            FileOutputStream fos = (FileOutputStream) os;
+            if (success) {
+                mAtomicFile.finishWrite(fos);
+            } else {
+                mAtomicFile.failWrite(fos);
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index ab95e4b..8dae016 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.IBinder;
@@ -43,6 +44,9 @@
 
     final SurfaceControl mInputSurface;
     Rect mTmpClipRect = new Rect();
+    private final Rect mTmpRect = new Rect();
+    private final Point mOldPosition = new Point();
+    private final Rect mOldWindowCrop = new Rect();
 
     InputConsumerImpl(WindowManagerService service, IBinder token, String name,
             InputChannel inputChannel, int clientPid, UserHandle clientUser, int displayId) {
@@ -112,16 +116,22 @@
     }
 
     void layout(SurfaceControl.Transaction t, int dw, int dh) {
-        t.setPosition(mInputSurface, 0, 0);
-
-        mTmpClipRect.set(0, 0, dw, dh);
-        t.setWindowCrop(mInputSurface, mTmpClipRect);
+        mTmpRect.set(0, 0, dw, dh);
+        layout(t, mTmpRect);
     }
 
     void layout(SurfaceControl.Transaction t, Rect r) {
-        t.setPosition(mInputSurface, r.left, r.top);
         mTmpClipRect.set(0, 0, r.width(), r.height());
+
+        if (mOldPosition.equals(r.left, r.top) && mOldWindowCrop.equals(mTmpClipRect)) {
+            return;
+        }
+
+        t.setPosition(mInputSurface, r.left, r.top);
         t.setWindowCrop(mInputSurface, mTmpClipRect);
+
+        mOldPosition.set(r.left, r.top);
+        mOldWindowCrop.set(mTmpClipRect);
     }
 
     void hide(SurfaceControl.Transaction t) {
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index f46835e..6b500967 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -6,6 +6,7 @@
 
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.H.ON_POINTER_DOWN_OUTSIDE_FOCUS;
 
 import android.os.Debug;
 import android.os.IBinder;
@@ -232,6 +233,11 @@
         }
     }
 
+    @Override
+    public void onPointerDownOutsideFocus(IBinder touchedToken) {
+        mService.mH.obtainMessage(ON_POINTER_DOWN_OUTSIDE_FOCUS, touchedToken).sendToTarget();
+    }
+
     /** Waits until the built-in input devices have been configured. */
     public boolean waitForInputDevicesReady(long timeoutMillis) {
         synchronized (mInputDevicesReadyMonitor) {
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 5669451..d3dba90 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
 import static android.view.WindowManager.INPUT_CONSUMER_PIP;
 import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
@@ -62,6 +63,7 @@
     // When true, need to call updateInputWindowsLw().
     private boolean mUpdateInputWindowsNeeded = true;
     private boolean mUpdateInputWindowsPending;
+    private boolean mApplyImmediately;
 
     // Currently focused input window handle.
     private InputWindowHandle mFocusedInputWindowHandle;
@@ -151,7 +153,7 @@
         mService = service;
         mDisplayContent = mService.mRoot.getDisplayContent(displayId);
         mDisplayId = displayId;
-        mInputTransaction = mDisplayContent.getPendingTransaction();
+        mInputTransaction = mService.mTransactionFactory.make();
         mHandler = AnimationThread.getHandler();
         mUpdateInputForAllWindowsConsumer = new UpdateInputForAllWindowsConsumer();
     }
@@ -190,8 +192,13 @@
     }
 
     void layoutInputConsumers(int dw, int dh) {
-        for (int i = mInputConsumers.size() - 1; i >= 0; i--) {
-            mInputConsumers.valueAt(i).layout(mInputTransaction, dw, dh);
+        try {
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "layoutInputConsumer");
+            for (int i = mInputConsumers.size() - 1; i >= 0; i--) {
+                mInputConsumers.valueAt(i).layout(mInputTransaction, dw, dh);
+            }
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
     }
 
@@ -245,7 +252,7 @@
             final boolean hasFocus, final boolean hasWallpaper) {
         // Add a window to our list of input windows.
         inputWindowHandle.name = child.toString();
-        flags = child.getSurfaceTouchableRegion(inputWindowHandle.touchableRegion, flags);
+        flags = child.getSurfaceTouchableRegion(inputWindowHandle, flags);
         inputWindowHandle.layoutParamsFlags = flags;
         inputWindowHandle.layoutParamsType = type;
         inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
@@ -313,6 +320,14 @@
         }
     }
 
+    void updateInputWindowsImmediately() {
+        if (mUpdateInputWindowsPending) {
+            mApplyImmediately = true;
+            mUpdateInputWindows.run();
+            mApplyImmediately = false;
+        }
+    }
+
     /* Called when the current input focus changes.
      * Layer assignment is assumed to be complete by the time this is called.
      */
@@ -401,7 +416,7 @@
         final InputWindowHandle mInvalidInputWindow = new InputWindowHandle(null, null, mDisplayId);
 
         private void updateInputWindows(boolean inDrag) {
-            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "updateInputWindows");
+            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateInputWindows");
 
             navInputConsumer = getInputConsumer(INPUT_CONSUMER_NAVIGATION);
             pipInputConsumer = getInputConsumer(INPUT_CONSUMER_PIP);
@@ -427,9 +442,14 @@
                 wallpaperInputConsumer.show(mInputTransaction, 0);
             }
 
-            mDisplayContent.scheduleAnimation();
+            if (mApplyImmediately) {
+                mInputTransaction.apply();
+            } else {
+                mDisplayContent.getPendingTransaction().merge(mInputTransaction);
+                mDisplayContent.scheduleAnimation();
+            }
 
-            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 3110fb9..c3ea72f 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -92,6 +92,11 @@
                 mBottom.getHeight());
     }
 
+    /** @return The frame that used to place the content. */
+    Rect getInnerFrame() {
+        return mInner;
+    }
+
     /**
      * Returns true if any part of the letterbox overlaps with the given {@code rect}.
      */
@@ -162,6 +167,7 @@
         final InputWindowHandle mWindowHandle;
         final InputEventReceiver mInputEventReceiver;
         final WindowManagerService mWmService;
+        final Binder mToken = new Binder();
 
         InputInterceptor(String namePrefix, WindowState win) {
             mWmService = win.mWmService;
@@ -171,13 +177,12 @@
             mClientChannel = channels[1];
             mInputEventReceiver = new SimpleInputReceiver(mClientChannel);
 
-            final Binder token = new Binder();
-            mWmService.mInputManager.registerInputChannel(mServerChannel, token);
+            mWmService.mInputManager.registerInputChannel(mServerChannel, mToken);
 
             mWindowHandle = new InputWindowHandle(null /* inputApplicationHandle */,
                     null /* clientWindow */, win.getDisplayId());
             mWindowHandle.name = name;
-            mWindowHandle.token = token;
+            mWindowHandle.token = mToken;
             mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                     | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
@@ -192,6 +197,14 @@
         }
 
         void updateTouchableRegion(Rect frame) {
+            if (frame.isEmpty()) {
+                // Use null token to indicate the surface doesn't need to receive input event (see
+                // the usage of Layer.hasInput in SurfaceFlinger), so InputDispatcher won't keep the
+                // unnecessary records.
+                mWindowHandle.token = null;
+                return;
+            }
+            mWindowHandle.token = mToken;
             mWindowHandle.touchableRegion.set(frame);
             mWindowHandle.touchableRegion.translate(-frame.left, -frame.top);
         }
@@ -289,14 +302,14 @@
                 t.setPosition(mSurface, mSurfaceFrameRelative.left, mSurfaceFrameRelative.top);
                 t.setWindowCrop(mSurface, mSurfaceFrameRelative.width(),
                         mSurfaceFrameRelative.height());
-                if (mInputInterceptor != null) {
-                    mInputInterceptor.updateTouchableRegion(mSurfaceFrameRelative);
-                    t.setInputWindowInfo(mSurface, mInputInterceptor.mWindowHandle);
-                }
                 t.show(mSurface);
             } else if (mSurface != null) {
                 t.hide(mSurface);
             }
+            if (mSurface != null && mInputInterceptor != null) {
+                mInputInterceptor.updateTouchableRegion(mSurfaceFrameRelative);
+                t.setInputWindowInfo(mSurface, mInputInterceptor.mWindowHandle);
+            }
         }
 
         public boolean needsApplySurfaceChanges() {
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 24b0213..d6c7b21 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -653,10 +653,10 @@
         }
     }
 
-    void removeAllVisibleTasks() {
+    void removeAllVisibleTasks(int userId) {
         for (int i = mTasks.size() - 1; i >= 0; --i) {
             final TaskRecord tr = mTasks.get(i);
-            if (isVisibleRecentTask(tr)) {
+            if (tr.userId == userId && isVisibleRecentTask(tr)) {
                 mTasks.remove(i);
                 notifyTaskRemoved(tr, true /* wasTrimmed */, true /* killProcess */);
             }
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index f1560d9..144efb4 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -17,8 +17,6 @@
 package com.android.server.wm;
 
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
-import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
-import static android.app.AppOpsManager.OP_NONE;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -34,25 +32,16 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
 
 import android.app.ActivityOptions;
-import android.app.AppOpsManager;
 import android.app.IAssistDataReceiver;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
-import android.os.Bundle;
-import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.Trace;
 import android.util.Slog;
 import android.view.IRecentsAnimationRunner;
 
-import com.android.server.LocalServices;
-import com.android.server.am.AssistDataRequester;
-import com.android.server.contentcapture.ContentCaptureManagerInternal;
 import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallbacks;
 
-import java.util.List;
-
 /**
  * Manages the recents animation, including the reordering of the stacks for the transition and
  * cleanup. See {@link com.android.server.wm.RecentsAnimationController}.
@@ -70,7 +59,6 @@
     private final int mCallingPid;
 
     private int mTargetActivityType;
-    private AssistDataRequester mAssistDataRequester;
 
     // The stack to restore the target stack behind when the animation is finished
     private ActivityStack mRestoreTargetBehindStack;
@@ -135,9 +123,6 @@
 
         mWindowManager.deferSurfaceLayout();
         try {
-            // Kick off the assist data request in the background before showing the target activity
-            requestAssistData(recentsComponent, recentsUid, assistDataReceiver);
-
             if (hasExistingActivity) {
                 // Move the recents activity into place for the animation if it is not top most
                 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
@@ -216,78 +201,12 @@
         }
     }
 
-    /**
-     * Requests assist data for the top visible activities.
-     */
-    private void requestAssistData(ComponentName recentsComponent, int recentsUid,
-            @Deprecated IAssistDataReceiver assistDataReceiver) {
-        final AppOpsManager appOpsManager = (AppOpsManager)
-                mService.mContext.getSystemService(Context.APP_OPS_SERVICE);
-        final List<IBinder> topActivities =
-                mService.mRootActivityContainer.getTopVisibleActivities();
-        final AssistDataRequester.AssistDataRequesterCallbacks assistDataCallbacks;
-        if (assistDataReceiver != null) {
-            assistDataCallbacks = new AssistDataReceiverProxy(assistDataReceiver,
-                    recentsComponent.getPackageName()) {
-                @Override
-                public void onAssistDataReceivedLocked(Bundle data, int activityIndex,
-                        int activityCount) {
-                    // Try to notify the intelligence service first
-                    final ContentCaptureManagerInternal imService =
-                            LocalServices.getService(ContentCaptureManagerInternal.class);
-                    final IBinder activityToken = topActivities.get(activityIndex);
-                    final ActivityRecord r = ActivityRecord.forTokenLocked(activityToken);
-                    if (r != null && (imService == null
-                            || !imService.sendActivityAssistData(r.mUserId, activityToken, data))) {
-                        // Otherwise, use the provided assist data receiver
-                        super.onAssistDataReceivedLocked(data, activityIndex, activityCount);
-                    }
-                }
-            };
-        } else {
-            final ContentCaptureManagerInternal imService =
-                    LocalServices.getService(ContentCaptureManagerInternal.class);
-            if (imService == null) {
-                // There is no intelligence service, so there is no point requesting assist data
-                return;
-            }
-
-            assistDataCallbacks = new AssistDataRequester.AssistDataRequesterCallbacks() {
-                @Override
-                public boolean canHandleReceivedAssistDataLocked() {
-                    return true;
-                }
-
-                @Override
-                public void onAssistDataReceivedLocked(Bundle data, int activityIndex,
-                        int activityCount) {
-                    // Try to notify the intelligence service
-                    final IBinder activityToken = topActivities.get(activityIndex);
-                    final ActivityRecord r = ActivityRecord.forTokenLocked(activityToken);
-                    if (r != null) {
-                        imService.sendActivityAssistData(r.mUserId, activityToken, data);
-                    }
-                }
-            };
-        }
-        mAssistDataRequester = new AssistDataRequester(mService.mContext, mWindowManager,
-                appOpsManager, assistDataCallbacks, this, OP_ASSIST_STRUCTURE, OP_NONE);
-        mAssistDataRequester.requestAutofillData(topActivities,
-                recentsUid, recentsComponent.getPackageName());
-    }
-
     private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
         synchronized (mService.mGlobalLock) {
             if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller="
                     + mWindowManager.getRecentsAnimationController()
                     + " reorderMode=" + reorderMode);
 
-            // Cancel the associated assistant data request
-            if (mAssistDataRequester != null) {
-                mAssistDataRequester.cancel();
-                mAssistDataRequester = null;
-            }
-
             // Unregister for stack order changes
             mDefaultDisplay.unregisterStackOrderChangedListener(this);
 
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index ed5f665..1ca31f1 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
@@ -65,6 +66,7 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.util.ArraySet;
 import android.util.EventLog;
@@ -551,18 +553,26 @@
         return leakedSurface || killedApps;
     }
 
+    void performSurfacePlacement(boolean recoveringMemory) {
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement");
+        try {
+            performSurfacePlacementNoTrace(recoveringMemory);
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
+    }
+
     // "Something has changed!  Let's make it correct now."
     // TODO: Super crazy long method that should be broken down...
-    void performSurfacePlacement(boolean recoveringMemory) {
+    void performSurfacePlacementNoTrace(boolean recoveringMemory) {
         if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
                 + Debug.getCallers(3));
 
         int i;
-        boolean updateInputWindowsNeeded = false;
 
         if (mWmService.mFocusMayChange) {
             mWmService.mFocusMayChange = false;
-            updateInputWindowsNeeded = mWmService.updateFocusedWindowLocked(
+            mWmService.updateFocusedWindowLocked(
                     UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
         }
 
@@ -586,6 +596,7 @@
 
         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
         mWmService.openSurfaceTransaction();
         try {
             applySurfaceChangesTransaction(recoveringMemory);
@@ -593,6 +604,7 @@
             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
         } finally {
             mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                     "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
         }
@@ -621,10 +633,8 @@
 
         if (mWmService.mFocusMayChange) {
             mWmService.mFocusMayChange = false;
-            if (mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
-                    false /*updateInputWindows*/)) {
-                updateInputWindowsNeeded = true;
-            }
+            mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
+                    false /*updateInputWindows*/);
         }
 
         if (isLayoutNeeded()) {
@@ -679,12 +689,6 @@
             }
         }
 
-        // Finally update all input windows now that the window changes have stabilized.
-        forAllDisplays(dc -> {
-            dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
-            dc.updateSystemGestureExclusion();
-        });
-
         mWmService.setHoldScreenLocked(mHoldScreen);
         if (!mWmService.mDisplayFrozen) {
             final int brightness = mScreenBrightness < 0 || mScreenBrightness > 1.0f
@@ -710,7 +714,7 @@
 
         if (mWmService.mWaitingForDrawnCallback != null
                 || (mOrientationChangeComplete && !isLayoutNeeded()
-                        && !mUpdateRotation)) {
+                && !mUpdateRotation)) {
             mWmService.checkDrawnWindowsLocked();
         }
 
@@ -742,12 +746,11 @@
             mChildren.get(displayNdx).checkCompleteDeferredRemoval();
         }
 
-        if (updateInputWindowsNeeded) {
-            forAllDisplays(dc -> {
-                dc.getInputMonitor().updateInputWindowsLw(false /*force*/);
-            });
-        }
-        forAllDisplays(DisplayContent::updateTouchExcludeRegion);
+        forAllDisplays(dc -> {
+            dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
+            dc.updateSystemGestureExclusion();
+            dc.updateTouchExcludeRegion();
+        });
 
         // Check to see if we are now in a state where the screen should
         // be enabled, because the window obscured flags have changed.
@@ -776,7 +779,7 @@
                 }
             }
 
-            if (!curDisplay.isAppAnimating() && curDisplay.mAppTransition.isRunning()) {
+            if (curDisplay.mAppTransition.isRunning() && !curDisplay.isAppAnimating()) {
                 // We have finished the animation of an app transition. To do this, we have
                 // delayed a lot of operations like showing and hiding apps, moving apps in
                 // Z-order, etc.
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 9b634f9..22b030d 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -426,11 +426,10 @@
     }
 
     @Override
-    public void updateTapExcludeRegion(IWindow window, int regionId, int left, int top, int width,
-            int height) {
+    public void updateTapExcludeRegion(IWindow window, int regionId, Region region) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            mService.updateTapExcludeRegion(window, regionId, left, top, width, height);
+            mService.updateTapExcludeRegion(window, regionId, region);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/services/core/java/com/android/server/wm/StatusBarController.java b/services/core/java/com/android/server/wm/StatusBarController.java
index 6db606d..f4260d3 100644
--- a/services/core/java/com/android/server/wm/StatusBarController.java
+++ b/services/core/java/com/android/server/wm/StatusBarController.java
@@ -36,22 +36,22 @@
 
         private Runnable mAppTransitionPending = () -> {
             StatusBarManagerInternal statusBar = getStatusBarInternal();
-            if (statusBar != null && mWin != null) {
-                statusBar.appTransitionPending(mWin.getDisplayId());
+            if (statusBar != null) {
+                statusBar.appTransitionPending(mDisplayId);
             }
         };
 
         private Runnable mAppTransitionCancelled = () -> {
             StatusBarManagerInternal statusBar = getStatusBarInternal();
-            if (statusBar != null && mWin != null) {
-                statusBar.appTransitionCancelled(mWin.getDisplayId());
+            if (statusBar != null) {
+                statusBar.appTransitionCancelled(mDisplayId);
             }
         };
 
         private Runnable mAppTransitionFinished = () -> {
             StatusBarManagerInternal statusBar = getStatusBarInternal();
-            if (statusBar != null && mWin != null) {
-                statusBar.appTransitionFinished(mWin.getDisplayId());
+            if (statusBar != null) {
+                statusBar.appTransitionFinished(mDisplayId);
             }
         };
 
@@ -65,8 +65,8 @@
                 long statusBarAnimationStartTime, long statusBarAnimationDuration) {
             mHandler.post(() -> {
                 StatusBarManagerInternal statusBar = getStatusBarInternal();
-                if (statusBar != null && mWin != null) {
-                    statusBar.appTransitionStarting(mWin.getDisplayId(),
+                if (statusBar != null) {
+                    statusBar.appTransitionStarting(mDisplayId,
                             statusBarAnimationStartTime, statusBarAnimationDuration);
                 }
             });
@@ -84,8 +84,9 @@
         }
     };
 
-    StatusBarController() {
+    StatusBarController(int displayId) {
         super("StatusBar",
+                displayId,
                 View.STATUS_BAR_TRANSIENT,
                 View.STATUS_BAR_UNHIDE,
                 View.STATUS_BAR_TRANSLUCENT,
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 35b8641..67686a5 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -82,6 +82,11 @@
                     return;
                 }
                 final Runnable resetAndInvokeFinish = () -> {
+                    // We need to check again if the animation has been replaced with a new
+                    // animation because the animatable may defer to finish.
+                    if (anim != mAnimation) {
+                        return;
+                    }
                     reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */);
                     if (animationFinishedCallback != null) {
                         animationFinishedCallback.run();
diff --git a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
index bd4e542..35afaed 100644
--- a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
@@ -17,9 +17,13 @@
 package com.android.server.wm;
 
 import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManagerGlobal;
 import android.os.Handler;
 import android.os.SystemClock;
 import android.util.Slog;
+import android.view.Display;
+import android.view.DisplayCutout;
 import android.view.GestureDetector;
 import android.view.InputDevice;
 import android.view.MotionEvent;
@@ -46,8 +50,9 @@
 
     private final Context mContext;
     private final Handler mHandler;
-    private final int mSwipeStartThreshold;
-    private final int mSwipeDistanceThreshold;
+    private int mDisplayCutoutTouchableRegionSize;
+    private int mSwipeStartThreshold;
+    private int mSwipeDistanceThreshold;
     private final Callbacks mCallbacks;
     private final int[] mDownPointerId = new int[MAX_TRACKED_POINTERS];
     private final float[] mDownX = new float[MAX_TRACKED_POINTERS];
@@ -65,14 +70,33 @@
     private long mLastFlingTime;
 
     SystemGesturesPointerEventListener(Context context, Handler handler, Callbacks callbacks) {
-        mContext = context;
+        mContext = checkNull("context", context);
         mHandler = handler;
         mCallbacks = checkNull("callbacks", callbacks);
-        mSwipeStartThreshold = checkNull("context", context).getResources()
+
+        onConfigurationChanged();
+    }
+
+    void onConfigurationChanged() {
+        mSwipeStartThreshold = mContext.getResources()
                 .getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+
+        final Display display = DisplayManagerGlobal.getInstance()
+                .getRealDisplay(Display.DEFAULT_DISPLAY);
+        final DisplayCutout displayCutout = display.getCutout();
+        if (displayCutout != null) {
+            final Rect bounds = displayCutout.getBoundingRectTop();
+            if (!bounds.isEmpty()) {
+                // Expand swipe start threshold such that we can catch touches that just start below
+                // the notch area
+                mDisplayCutoutTouchableRegionSize = mContext.getResources().getDimensionPixelSize(
+                        com.android.internal.R.dimen.display_cutout_touchable_region_size);
+                mSwipeStartThreshold += mDisplayCutoutTouchableRegionSize;
+            }
+        }
         mSwipeDistanceThreshold = mSwipeStartThreshold;
         if (DEBUG) Slog.d(TAG,  "mSwipeStartThreshold=" + mSwipeStartThreshold
-                + " mSwipeDistanceThreshold=" + mSwipeDistanceThreshold);
+            + " mSwipeDistanceThreshold=" + mSwipeDistanceThreshold);
     }
 
     private static <T> T checkNull(String name, T arg) {
diff --git a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java b/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
index 0a4ab67..22f529b 100644
--- a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
+++ b/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
@@ -21,38 +21,35 @@
 import android.util.SparseArray;
 
 /**
- * A holder that contains a collection of rectangular areas identified by int id. Each individual
- * region can be updated separately.
+ * A holder that contains a collection of regions identified by int id. Each individual region can
+ * be updated separately.
  */
 class TapExcludeRegionHolder {
-    private SparseArray<Rect> mTapExcludeRects = new SparseArray<>();
+    private SparseArray<Region> mTapExcludeRegions = new SparseArray<>();
 
     /** Update the specified region with provided position and size. */
-    void updateRegion(int regionId, int left, int top, int width, int height) {
-        if (width <= 0 || height <= 0) {
-            // A region became empty - remove it.
-            mTapExcludeRects.remove(regionId);
+    void updateRegion(int regionId, Region region) {
+        // Remove the previous one because there is a new one incoming.
+        mTapExcludeRegions.remove(regionId);
+
+        if (region == null || region.isEmpty()) {
+            // The incoming region is invalid. Don't use it.
             return;
         }
 
-        Rect region = mTapExcludeRects.get(regionId);
-        if (region == null) {
-            region = new Rect();
-        }
-        region.set(left, top, left + width, top + height);
-        mTapExcludeRects.put(regionId, region);
+        mTapExcludeRegions.put(regionId, region);
     }
 
     /**
      * Union the provided region with current region formed by this container.
      */
-    void amendRegion(Region region, Rect boundingRegion) {
-        for (int i = mTapExcludeRects.size() - 1; i>= 0 ; --i) {
-            final Rect rect = mTapExcludeRects.valueAt(i);
-            if (boundingRegion != null) {
-                rect.intersect(boundingRegion);
+    void amendRegion(Region region, Rect bounds) {
+        for (int i = mTapExcludeRegions.size() - 1; i >= 0; --i) {
+            final Region r = mTapExcludeRegions.valueAt(i);
+            if (bounds != null) {
+                r.op(bounds, Region.Op.INTERSECT);
             }
-            region.union(rect);
+            region.op(r, Region.Op.UNION);
         }
     }
 }
diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index 4ff552e..79baab6 100644
--- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -22,12 +22,9 @@
 import static android.view.PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW;
 import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
 
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
-
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.input.InputManager;
-import android.os.Handler;
 import android.view.MotionEvent;
 import android.view.WindowManagerPolicyConstants.PointerEventListener;
 
@@ -40,67 +37,15 @@
 public class TaskTapPointerEventListener implements PointerEventListener {
 
     private final Region mTouchExcludeRegion = new Region();
-    private final Region mTmpRegion = new Region();
     private final WindowManagerService mService;
     private final DisplayContent mDisplayContent;
-    private final Handler mHandler;
-    private final Runnable mMoveDisplayToTop;
     private final Rect mTmpRect = new Rect();
     private int mPointerIconType = TYPE_NOT_SPECIFIED;
-    private int mLastDownX;
-    private int mLastDownY;
 
     public TaskTapPointerEventListener(WindowManagerService service,
             DisplayContent displayContent) {
         mService = service;
         mDisplayContent = displayContent;
-        mHandler = new Handler(mService.mH.getLooper());
-        mMoveDisplayToTop = () -> {
-            int x;
-            int y;
-            synchronized (this) {
-                x = mLastDownX;
-                y = mLastDownY;
-            }
-            synchronized (mService.mGlobalLock) {
-                if (!mService.mPerDisplayFocusEnabled
-                        && mService.mRoot.getTopFocusedDisplayContent() != mDisplayContent
-                        && inputMethodWindowContains(x, y)) {
-                    // In a single focus system, if the input method window and the input method
-                    // target window are on the different displays, when the user is tapping on the
-                    // input method window, we don't move its display to top. Otherwise, the input
-                    // method target window will lose the focus.
-                    return;
-                }
-                final Region windowTapExcludeRegion = Region.obtain();
-                mDisplayContent.amendWindowTapExcludeRegion(windowTapExcludeRegion);
-                if (windowTapExcludeRegion.contains(x, y)) {
-                    windowTapExcludeRegion.recycle();
-                    // The user is tapping on the window tap exclude region. We don't move this
-                    // display to top. A window tap exclude region, for example, may be set by an
-                    // ActivityView, and the region would match the bounds of both the ActivityView
-                    // and the virtual display in it. In this case, we would take the tap that is on
-                    // the embedded virtual display instead of this display.
-                    return;
-                }
-                windowTapExcludeRegion.recycle();
-                WindowContainer parent = mDisplayContent.getParent();
-                if (parent != null && parent.getTopChild() != mDisplayContent) {
-                    parent.positionChildAt(WindowContainer.POSITION_TOP, mDisplayContent,
-                            true /* includingParents */);
-                    // For compatibility, only the topmost activity is allowed to be resumed for
-                    // pre-Q app. Ensure the topmost activities are resumed whenever a display is
-                    // moved to top.
-                    // TODO(b/123761773): Investigate whether we can move this into
-                    // RootActivityContainer#updateTopResumedActivityIfNeeded(). Currently, it is
-                    // risky to do so because it seems possible to resume activities as part of a
-                    // larger transaction and it's too early to resume based on current order
-                    // when performing updateTopResumedActivityIfNeeded().
-                    mDisplayContent.mAcitvityDisplay.ensureActivitiesVisible(null /* starting */,
-                            0 /* configChanges */, !PRESERVE_WINDOWS, true /* notifyClients */);
-                }
-            }
-        };
     }
 
     @Override
@@ -115,9 +60,6 @@
                         mService.mTaskPositioningController.handleTapOutsideTask(
                                 mDisplayContent, x, y);
                     }
-                    mLastDownX = x;
-                    mLastDownY = y;
-                    mHandler.post(mMoveDisplayToTop);
                 }
             }
             break;
@@ -178,17 +120,4 @@
            mTouchExcludeRegion.set(newRegion);
         }
     }
-
-    private int getDisplayId() {
-        return mDisplayContent.getDisplayId();
-    }
-
-    private boolean inputMethodWindowContains(int x, int y) {
-        final WindowState inputMethodWindow = mDisplayContent.mInputMethodWindow;
-        if (inputMethodWindow == null || !inputMethodWindow.isVisibleLw()) {
-            return false;
-        }
-        inputMethodWindow.getTouchableRegion(mTmpRegion);
-        return mTmpRegion.contains(x, y);
-    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java
index 20a874b..9fe4760 100644
--- a/services/core/java/com/android/server/wm/WindowFrames.java
+++ b/services/core/java/com/android/server/wm/WindowFrames.java
@@ -244,8 +244,6 @@
     void calculateOutsets() {
         if (mHasOutsets) {
             InsetUtils.insetsBetweenFrames(mOutsetFrame, mContentFrame, mOutsets);
-        } else {
-            mOutsets.setEmpty();
         }
     }
 
@@ -373,7 +371,13 @@
      * Sets whether the frame has outsets.
      */
     public void setHasOutsets(boolean hasOutsets) {
+        if (mHasOutsets == hasOutsets) {
+            return;
+        }
         mHasOutsets = hasOutsets;
+        if (!hasOutsets) {
+            mOutsets.setEmpty();
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index d3f3711..9d80425 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -414,7 +414,7 @@
         OnHardKeyboardStatusChangeListener listener);
 
     /** Returns true if a stack in the windowing mode is currently visible. */
-    public abstract boolean isStackVisible(int windowingMode);
+    public abstract boolean isStackVisibleLw(int windowingMode);
 
     /**
      * Requests the window manager to resend the windows for accessibility.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4aa844f..8dfb02e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -73,6 +73,7 @@
 import static com.android.server.LockGuard.INDEX_WINDOW;
 import static com.android.server.LockGuard.installLock;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
@@ -1392,11 +1393,9 @@
                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
             }
 
-            final boolean hasStatusBarServicePermission =
-                    mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE)
-                            == PackageManager.PERMISSION_GRANTED;
             final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
-            displayPolicy.adjustWindowParamsLw(win, win.mAttrs, hasStatusBarServicePermission);
+            displayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(),
+                    Binder.getCallingUid());
             win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
 
             res = displayPolicy.prepareAddWindowLw(win, attrs);
@@ -1932,6 +1931,11 @@
         }
     }
 
+    private boolean hasStatusBarPermission(int pid, int uid) {
+        return mContext.checkPermission(permission.STATUS_BAR, pid, uid)
+                        == PackageManager.PERMISSION_GRANTED;
+    }
+
     public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewVisibility, int flags,
             long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
@@ -1940,13 +1944,8 @@
             SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
         int result = 0;
         boolean configChanged;
-        final boolean hasStatusBarPermission =
-                mContext.checkCallingOrSelfPermission(permission.STATUS_BAR)
-                        == PackageManager.PERMISSION_GRANTED;
-        final boolean hasStatusBarServicePermission =
-                mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE)
-                        == PackageManager.PERMISSION_GRANTED;
-
+        final int pid = Binder.getCallingPid();
+        final int uid = Binder.getCallingUid();
         long origId = Binder.clearCallingIdentity();
         final int displayId;
         synchronized (mGlobalLock) {
@@ -1973,13 +1972,13 @@
             int attrChanges = 0;
             int flagChanges = 0;
             if (attrs != null) {
-                displayPolicy.adjustWindowParamsLw(win, attrs, hasStatusBarServicePermission);
+                displayPolicy.adjustWindowParamsLw(win, attrs, pid, uid);
                 // if they don't have the permission, mask out the status bar bits
                 if (seq == win.mSeq) {
                     int systemUiVisibility = attrs.systemUiVisibility
                             | attrs.subtreeSystemUiVisibility;
                     if ((systemUiVisibility & DISABLE_MASK) != 0) {
-                        if (!hasStatusBarPermission) {
+                        if (!hasStatusBarPermission(pid, uid)) {
                             systemUiVisibility &= ~DISABLE_MASK;
                         }
                     }
@@ -2050,7 +2049,6 @@
                             && viewVisibility == View.VISIBLE;
             boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0
                     || becameVisible;
-            final boolean isDefaultDisplay = win.isDefaultDisplay();
             boolean focusMayChange = win.mViewVisibility != viewVisibility
                     || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
                     || (!win.mRelayoutCalled);
@@ -4522,6 +4520,7 @@
         public static final int SET_RUNNING_REMOTE_ANIMATION = 59;
         public static final int ANIMATION_FAILSAFE = 60;
         public static final int RECOMPUTE_FOCUS = 61;
+        public static final int ON_POINTER_DOWN_OUTSIDE_FOCUS = 62;
 
         /**
          * Used to denote that an integer field in a message will not be used.
@@ -4913,6 +4912,13 @@
                     }
                     break;
                 }
+                case ON_POINTER_DOWN_OUTSIDE_FOCUS: {
+                    synchronized (mGlobalLock) {
+                        final IBinder touchedToken = (IBinder) msg.obj;
+                        onPointerDownOutsideFocusLocked(touchedToken);
+                    }
+                    break;
+                }
             }
             if (DEBUG_WINDOW_TRACE) {
                 Slog.v(TAG_WM, "handleMessage: exit");
@@ -6696,24 +6702,23 @@
     }
 
     /**
-     * Update a tap exclude region with a rectangular area in the window identified by the provided
-     * id. Touches down on this region will not:
+     * Update a tap exclude region in the window identified by the provided id. Touches down on this
+     * region will not:
      * <ol>
      * <li>Switch focus to this window.</li>
      * <li>Move the display of this window to top.</li>
      * <li>Send the touch events to this window.</li>
      * </ol>
-     * Passing an empty rect will remove the area from the exclude region of this window.
+     * Passing an invalid region will remove the area from the exclude region of this window.
      */
-    void updateTapExcludeRegion(IWindow client, int regionId, int left, int top, int width,
-            int height) {
+    void updateTapExcludeRegion(IWindow client, int regionId, Region region) {
         synchronized (mGlobalLock) {
             final WindowState callingWin = windowForClientLocked(null, client, false);
             if (callingWin == null) {
                 Slog.w(TAG_WM, "Bad requesting window " + client);
                 return;
             }
-            callingWin.updateTapExcludeRegion(regionId, left, top, width, height);
+            callingWin.updateTapExcludeRegion(regionId, region);
         }
     }
 
@@ -7216,11 +7221,9 @@
         }
 
         @Override
-        public boolean isStackVisible(int windowingMode) {
-            synchronized (mGlobalLock) {
-                final DisplayContent dc = getDefaultDisplayContentLocked();
-                return dc.isStackVisible(windowingMode);
-            }
+        public boolean isStackVisibleLw(int windowingMode) {
+            final DisplayContent dc = getDefaultDisplayContentLocked();
+            return dc.isStackVisible(windowingMode);
         }
 
         @Override
@@ -7528,22 +7531,24 @@
 
     @Override
     public boolean injectInputAfterTransactionsApplied(InputEvent ev, int mode) {
-        boolean shouldWaitForAnimComplete = false;
+        boolean shouldWaitForAnimToComplete = false;
         if (ev instanceof KeyEvent) {
             KeyEvent keyEvent = (KeyEvent) ev;
-            shouldWaitForAnimComplete = keyEvent.getSource() == InputDevice.SOURCE_MOUSE
+            shouldWaitForAnimToComplete = keyEvent.getSource() == InputDevice.SOURCE_MOUSE
                     || keyEvent.getAction() == KeyEvent.ACTION_DOWN;
         } else if (ev instanceof MotionEvent) {
             MotionEvent motionEvent = (MotionEvent) ev;
-            shouldWaitForAnimComplete = motionEvent.getSource() == InputDevice.SOURCE_MOUSE
+            shouldWaitForAnimToComplete = motionEvent.getSource() == InputDevice.SOURCE_MOUSE
                     || motionEvent.getAction() == MotionEvent.ACTION_DOWN;
         }
 
-        if (shouldWaitForAnimComplete) {
+        if (shouldWaitForAnimToComplete) {
             waitForAnimationsToComplete();
 
             synchronized (mGlobalLock) {
                 mWindowPlacerLocked.performSurfacePlacementIfScheduled();
+                mRoot.forAllDisplays(displayContent ->
+                        displayContent.getInputMonitor().updateInputWindowsImmediately());
             }
 
             new SurfaceControl.Transaction().syncInputWindows().apply(true);
@@ -7575,4 +7580,37 @@
             mGlobalLock.notifyAll();
         }
     }
+
+    private void onPointerDownOutsideFocusLocked(IBinder touchedToken) {
+        final WindowState touchedWindow = windowForClientLocked(null, touchedToken, false);
+        if (touchedWindow == null) {
+            return;
+        }
+
+        final DisplayContent displayContent = touchedWindow.getDisplayContent();
+        if (displayContent == null) {
+            return;
+        }
+
+        if (!touchedWindow.canReceiveKeys()) {
+            // If the window that received the input event cannot receive keys, don't move the
+            // display it's on to the top since that window won't be able to get focus anyway.
+            return;
+        }
+
+        final WindowContainer parent = displayContent.getParent();
+        if (parent != null && parent.getTopChild() != displayContent) {
+            parent.positionChildAt(WindowContainer.POSITION_TOP, displayContent,
+                    true /* includingParents */);
+            // For compatibility, only the topmost activity is allowed to be resumed for pre-Q
+            // app. Ensure the topmost activities are resumed whenever a display is moved to top.
+            // TODO(b/123761773): Investigate whether we can move this into
+            // RootActivityContainer#updateTopResumedActivityIfNeeded(). Currently, it is risky
+            // to do so because it seems possible to resume activities as part of a larger
+            // transaction and it's too early to resume based on current order when performing
+            // updateTopResumedActivityIfNeeded().
+            displayContent.mAcitvityDisplay.ensureActivitiesVisible(null /* starting */,
+                    0 /* configChanges */, !PRESERVE_WINDOWS, true /* notifyClients */);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index dceed28..33561d3a 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -149,6 +149,8 @@
     // Set to true if this process is currently temporarily whitelisted to start activities even if
     // it's not in the foreground
     private volatile boolean mAllowBackgroundActivityStarts;
+    // Set of UIDs of clients currently bound to this process
+    private volatile ArraySet<Integer> mBoundClientUids = new ArraySet<Integer>();
 
     // Thread currently set for VR scheduling
     int mVrThreadTid;
@@ -297,6 +299,11 @@
         return mPendingUiClean;
     }
 
+    /** @return {@code true} if the process registered to a display as a config listener. */
+    boolean registeredForDisplayConfigChanges() {
+        return mDisplayId != INVALID_DISPLAY;
+    }
+
     void postPendingUiCleanMsg(boolean pendingUiClean) {
         if (mListener == null) return;
         // Posting on handler so WM lock isn't held when we call into AM.
@@ -368,6 +375,14 @@
         return mAllowBackgroundActivityStarts;
     }
 
+    public void setBoundClientUids(ArraySet<Integer> boundClientUids) {
+        mBoundClientUids = boundClientUids;
+    }
+
+    public ArraySet<Integer> getBoundClientUids() {
+        return mBoundClientUids;
+    }
+
     public void setInstrumenting(boolean instrumenting,
             boolean hasBackgroundActivityStartPrivileges) {
         mInstrumenting = instrumenting;
@@ -471,6 +486,20 @@
         }
     }
 
+    boolean hasActivityInVisibleTask() {
+        for (int i = mActivities.size() - 1; i >= 0; --i) {
+            TaskRecord task = mActivities.get(i).getTaskRecord();
+            if (task == null) {
+                continue;
+            }
+            ActivityRecord topActivity = task.getTopActivity();
+            if (topActivity != null && topActivity.visible) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Update the top resuming activity in process for pre-Q apps, only the top-most visible
      * activities are allowed to be resumed per process.
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 6a21327..08ade37 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -72,6 +72,7 @@
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
 
+import static com.android.server.am.ActivityManagerService.MY_PID;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.policy.WindowManagerPolicy.TRANSIT_ENTER;
 import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT;
@@ -213,7 +214,7 @@
     static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM;
 
     // The minimal size of a window within the usable area of the freeform stack.
-    // TODO(multi-window): fix the min sizes when we have mininum width/height support,
+    // TODO(multi-window): fix the min sizes when we have minimum width/height support,
     //                     use hard-coded min sizes for now.
     static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48;
     static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32;
@@ -307,6 +308,9 @@
      */
     private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration();
 
+    /** @see #isLastConfigReportedToClient() */
+    private boolean mLastConfigReportedToClient;
+
     private final Configuration mTempConfiguration = new Configuration();
 
     /**
@@ -1200,7 +1204,7 @@
         }
 
         boolean didFrameInsetsChange = setReportResizeHints();
-        boolean configChanged = isConfigChanged();
+        boolean configChanged = !isLastConfigReportedToClient();
         if (DEBUG_CONFIGURATION && configChanged) {
             Slog.v(TAG_WM, "Win " + this + " config changed: " + getConfiguration());
         }
@@ -1780,9 +1784,18 @@
         return getDisplayContent().getBounds().equals(getBounds());
     }
 
-    /** Returns true if last applied config was not yet requested by client. */
-    boolean isConfigChanged() {
-        return !getLastReportedConfiguration().equals(getConfiguration());
+    /**
+     * @return {@code true} if last applied config was reported to the client already, {@code false}
+     *         otherwise.
+     */
+    boolean isLastConfigReportedToClient() {
+        return mLastConfigReportedToClient;
+    }
+
+    @Override
+    void onMergedOverrideConfigurationChanged() {
+        super.onMergedOverrideConfigurationChanged();
+        mLastConfigReportedToClient = false;
     }
 
     void onWindowReplacementTimeout() {
@@ -2183,8 +2196,11 @@
         }
     }
 
-    int getSurfaceTouchableRegion(Region region, int flags) {
+    int getSurfaceTouchableRegion(InputWindowHandle inputWindowHandle, int flags) {
         final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
+        final Region region = inputWindowHandle.touchableRegion;
+        setTouchableRegionCropIfNeeded(inputWindowHandle);
+
         if (mAppToken != null && !mAppToken.getResolvedOverrideBounds().isEmpty()) {
             // There may have touchable letterboxes around the activity, so in order to let the
             // letterboxes are able to receive touch event and slip to activity, the activity with
@@ -2209,16 +2225,22 @@
         if (modal && mAppToken != null) {
             // Limit the outer touch to the activity stack region.
             flags |= FLAG_NOT_TOUCH_MODAL;
-            // If this is a modal window we need to dismiss it if it's not full screen and the
-            // touch happens outside of the frame that displays the content. This means we
-            // need to intercept touches outside of that window. The dim layer user
-            // associated with the window (task or stack) will give us the good bounds, as
-            // they would be used to display the dim layer.
-            final Task task = getTask();
-            if (task != null) {
-                task.getDimBounds(mTmpRect);
-            } else {
-                getStack().getDimBounds(mTmpRect);
+            // If the inner bounds of letterbox is available, then it will be used as the touchable
+            // region so it won't cover the touchable letterbox and the touch events can slip to
+            // activity from letterbox.
+            mAppToken.getLetterboxInnerBounds(mTmpRect);
+            if (mTmpRect.isEmpty()) {
+                // If this is a modal window we need to dismiss it if it's not full screen and the
+                // touch happens outside of the frame that displays the content. This means we need
+                // to intercept touches outside of that window. The dim layer user associated with
+                // the window (task or stack) will give us the good bounds, as they would be used to
+                // display the dim layer.
+                final Task task = getTask();
+                if (task != null) {
+                    task.getDimBounds(mTmpRect);
+                } else {
+                    getStack().getDimBounds(mTmpRect);
+                }
             }
             if (inFreeformWindowingMode()) {
                 // For freeform windows we the touch region to include the whole surface for the
@@ -2246,6 +2268,7 @@
                 region.set(-dw, -dh, dw + dw, dh + dh);
                 // Subtract the area that cannot be touched.
                 region.op(touchExcludeRegion, Region.Op.DIFFERENCE);
+                inputWindowHandle.setTouchableRegionCrop(null);
             }
             touchExcludeRegion.recycle();
         } else {
@@ -2292,11 +2315,6 @@
     void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
         // We need to turn on screen regardless of visibility.
         boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0;
-        boolean allowTheaterMode =
-                mWmService.mAllowTheaterModeWakeFromLayout || Settings.Global.getInt(
-                        mWmService.mContext.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0)
-                        == 0;
-        boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn();
 
         // The screen will turn on if the following conditions are met
         // 1. The window has the flag FLAG_TURN_SCREEN_ON
@@ -2310,6 +2328,11 @@
         // be occurring while turning off the screen. This would lead to the screen incorrectly
         // turning back on.
         if (hasTurnScreenOnFlag) {
+            boolean allowTheaterMode = mWmService.mAllowTheaterModeWakeFromLayout
+                    || Settings.Global.getInt(mWmService.mContext.getContentResolver(),
+                            Settings.Global.THEATER_MODE_ON, 0) == 0;
+            boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn();
+
             if (allowTheaterMode && canTurnScreenOn && !mPowerManagerWrapper.isInteractive()) {
                 if (DEBUG_VISIBILITY || DEBUG_POWER) {
                     Slog.v(TAG, "Relayout window turning screen on: " + this);
@@ -2343,12 +2366,11 @@
     private Configuration getProcessGlobalConfiguration() {
         // For child windows we want to use the pid for the parent window in case the the child
         // window was added from another process.
-        final int pid = getParentWindow() != null ? getParentWindow().mSession.mPid : mSession.mPid;
+        final WindowState parentWindow = getParentWindow();
+        final int pid = parentWindow != null ? parentWindow.mSession.mPid : mSession.mPid;
         final Configuration processConfig =
                 mWmService.mAtmService.getGlobalConfigurationForPid(pid);
-        mTempConfiguration.setTo(processConfig == null
-                ? mWmService.mRoot.getConfiguration() : processConfig);
-        return mTempConfiguration;
+        return processConfig;
     }
 
     void getMergedConfiguration(MergedConfiguration outConfiguration) {
@@ -2359,6 +2381,7 @@
 
     void setLastReportedMergedConfiguration(MergedConfiguration config) {
         mLastReportedConfiguration.setTo(config);
+        mLastConfigReportedToClient = true;
     }
 
     void getLastReportedMergedConfiguration(MergedConfiguration config) {
@@ -2506,6 +2529,10 @@
     }
 
     boolean showLw(boolean doAnimation, boolean requestAnim) {
+        if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
+            // Already showing.
+            return false;
+        }
         if (isHiddenFromUserLocked()) {
             return false;
         }
@@ -2526,10 +2553,6 @@
             // This is an alert window that is currently force hidden.
             return false;
         }
-        if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
-            // Already showing.
-            return false;
-        }
         if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
         if (doAnimation) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
@@ -2920,6 +2943,20 @@
         subtractTouchExcludeRegionIfNeeded(outRegion);
     }
 
+    private void setTouchableRegionCropIfNeeded(InputWindowHandle handle) {
+        final Task task = getTask();
+        if (task == null || !task.cropWindowsToStackBounds()) {
+            return;
+        }
+
+        final TaskStack stack = task.mStack;
+        if (stack == null) {
+            return;
+        }
+
+        handle.setTouchableRegionCrop(stack.getSurfaceControl());
+    }
+
     private void cropRegionToStackBoundsIfNeeded(Region region) {
         final Task task = getTask();
         if (task == null || !task.cropWindowsToStackBounds()) {
@@ -2983,11 +3020,29 @@
             return mAppToken.mFrozenMergedConfig.peek();
         }
 
+        // If the process has not registered to any display to listen to the configuration change,
+        // we can simply return the mFullConfiguration as default.
+        if (!registeredForDisplayConfigChanges()) {
+            return super.getConfiguration();
+        }
+
         // We use the process config this window is associated with as the based global config since
-        // the process can override it config, but isn't part of the window hierarchy.
-        final Configuration config = getProcessGlobalConfiguration();
-        config.updateFrom(getMergedOverrideConfiguration());
-        return config;
+        // the process can override its config, but isn't part of the window hierarchy.
+        mTempConfiguration.setTo(getProcessGlobalConfiguration());
+        mTempConfiguration.updateFrom(getMergedOverrideConfiguration());
+        return mTempConfiguration;
+    }
+
+    /** @return {@code true} if the process registered to a display as a config listener. */
+    private boolean registeredForDisplayConfigChanges() {
+        final WindowState parentWindow = getParentWindow();
+        final Session session = parentWindow != null ? parentWindow.mSession : mSession;
+        // System process or invalid process cannot register to display config change.
+        if (session.mPid == MY_PID || session.mPid < 0) return false;
+        WindowProcessController app =
+                mWmService.mAtmService.getProcessController(session.mPid, session.mUid);
+        if (app == null || !app.registeredForDisplayConfigChanges()) return false;
+        return true;
     }
 
     void reportResized() {
@@ -3505,7 +3560,10 @@
     }
 
     void transformClipRectFromScreenToSurfaceSpace(Rect clipRect) {
-         if (mHScale >= 0) {
+        if (mHScale == 1 && mVScale == 1) {
+            return;
+        }
+        if (mHScale >= 0) {
             clipRect.left = (int) (clipRect.left / mHScale);
             clipRect.right = (int) Math.ceil(clipRect.right / mHScale);
         }
@@ -4361,7 +4419,7 @@
         // scale function because we want to round things to make the crop
         // always round to a larger rect to ensure we don't crop too
         // much and hide part of the window that should be seen.
-        if (inSizeCompatMode() && mInvGlobalScale != 1.0f) {
+        if (mInvGlobalScale != 1.0f && inSizeCompatMode()) {
             final float scale = mInvGlobalScale;
             systemDecorRect.left = (int) (systemDecorRect.left * scale - 0.5f);
             systemDecorRect.top = (int) (systemDecorRect.top * scale - 0.5f);
@@ -4416,7 +4474,12 @@
 
         mWinAnimator.mEnteringAnimation = true;
 
-        prepareWindowToDisplayDuringRelayout(wasVisible);
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareToDisplay");
+        try {
+            prepareWindowToDisplayDuringRelayout(wasVisible);
+        } finally {
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        }
 
         if ((attrChanges & FORMAT_CHANGED) != 0) {
             // If the format can't be changed in place, preserve the old surface until the app draws
@@ -4831,10 +4894,10 @@
     }
 
     /**
-     * Update a tap exclude region with a rectangular area identified by provided id. The requested
-     * area will be clipped to the window bounds.
+     * Update a tap exclude region identified by provided id. The requested area will be clipped to
+     * the window bounds.
      */
-    void updateTapExcludeRegion(int regionId, int left, int top, int width, int height) {
+    void updateTapExcludeRegion(int regionId, Region region) {
         final DisplayContent currentDisplay = getDisplayContent();
         if (currentDisplay == null) {
             throw new IllegalStateException("Trying to update window not attached to any display.");
@@ -4848,7 +4911,7 @@
             currentDisplay.mTapExcludeProvidingWindows.add(this);
         }
 
-        mTapExcludeRegionHolder.updateRegion(regionId, left, top, width, height);
+        mTapExcludeRegionHolder.updateRegion(regionId, region);
         // Trigger touch exclude region update on current display.
         currentDisplay.updateTouchExcludeRegion();
         // Trigger touchable region update for this window.
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index acb9823..bef0f81 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -56,6 +56,7 @@
     private float mSurfaceY = 0;
     private int mSurfaceW = 0;
     private int mSurfaceH = 0;
+    private Rect mSurfaceCrop = new Rect(0, 0, -1, -1);
 
     // Initialize to the identity matrix.
     private float mLastDsdx = 1;
@@ -171,26 +172,15 @@
         }
     }
 
-    void disconnectInTransaction() {
-        if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
-            Slog.i(TAG, "Disconnecting client: " + this);
-        }
-
-        try {
-            if (mSurfaceControl != null) {
-                mSurfaceControl.disconnect();
-            }
-        } catch (RuntimeException e) {
-            Slog.w(TAG, "Error disconnecting surface in: " + this, e);
-        }
-    }
-
     void setCropInTransaction(Rect clipRect, boolean recoveringMemory) {
         if (SHOW_TRANSACTIONS) logSurface(
                 "CROP " + clipRect.toShortString(), null);
         try {
             if (clipRect.width() > 0 && clipRect.height() > 0) {
-                mSurfaceControl.setWindowCrop(clipRect);
+                if (!clipRect.equals(mSurfaceCrop)) {
+                    mSurfaceControl.setWindowCrop(clipRect);
+                    mSurfaceCrop.set(clipRect);
+                }
                 mHiddenForCrop = false;
                 updateVisibility();
             } else {
@@ -212,7 +202,11 @@
                 "CLEAR CROP", null);
         try {
             Rect clipRect = new Rect(0, 0, -1, -1);
+            if (mSurfaceCrop.equals(clipRect)) {
+                return;
+            }
             mSurfaceControl.setWindowCrop(clipRect);
+            mSurfaceCrop.set(clipRect);
         } catch (RuntimeException e) {
             Slog.w(TAG, "Error setting clearing crop of " + this, e);
             if (!recoveringMemory) {
@@ -221,12 +215,6 @@
         }
     }
 
-    void setLayerStackInTransaction(int layerStack) {
-        if (mSurfaceControl != null) {
-            mSurfaceControl.setLayerStack(layerStack);
-        }
-    }
-
     void setPositionInTransaction(float left, float top, boolean recoveringMemory) {
         setPosition(null, left, top, recoveringMemory);
     }
diff --git a/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java b/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java
index 98bad93..3be5d31 100644
--- a/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java
+++ b/services/core/java/com/android/server/wm/utils/WmDisplayCutout.java
@@ -81,11 +81,24 @@
      * @hide
      */
     public WmDisplayCutout calculateRelativeTo(Rect frame) {
+        if (mFrameSize == null) {
+            return this;
+        }
+        final int insetRight = mFrameSize.getWidth() - frame.right;
+        final int insetBottom = mFrameSize.getHeight() - frame.bottom;
+        if (frame.left == 0 && frame.top == 0 && insetRight == 0 && insetBottom == 0) {
+            return this;
+        }
+        if (frame.left >= mInner.getSafeInsetLeft()
+                && frame.top >= mInner.getSafeInsetTop()
+                && insetRight >= mInner.getSafeInsetRight()
+                && insetBottom >= mInner.getSafeInsetBottom()) {
+            return NO_CUTOUT;
+        }
         if (mInner.isEmpty()) {
             return this;
         }
-        return inset(frame.left, frame.top,
-                mFrameSize.getWidth() - frame.right, mFrameSize.getHeight() - frame.bottom);
+        return inset(frame.left, frame.top, insetRight, insetBottom);
     }
 
     /**
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 3d84bd4..204a1ea 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -47,6 +47,7 @@
 
 #include <input/PointerController.h>
 #include <input/SpriteController.h>
+#include <ui/Region.h>
 
 #include <inputflinger/InputManager.h>
 
@@ -96,6 +97,7 @@
     jmethodID interceptKeyBeforeDispatching;
     jmethodID dispatchUnhandledKey;
     jmethodID checkInjectEventsPermission;
+    jmethodID onPointerDownOutsideFocus;
     jmethodID getVirtualKeyQuietTimeMillis;
     jmethodID getExcludedDeviceNames;
     jmethodID getInputPortAssociations;
@@ -136,8 +138,6 @@
     jmethodID getAffineTransform;
 } gTouchCalibrationClassInfo;
 
-
-
 // --- Global functions ---
 
 template<typename T>
@@ -187,7 +187,6 @@
     return result;
 }
 
-
 // --- NativeInputManager ---
 
 class NativeInputManager : public virtual RefBase,
@@ -206,8 +205,12 @@
 
     void setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray);
 
-    status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel, int32_t displayId);
+    status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
+            int32_t displayId);
+    status_t registerInputMonitor(JNIEnv* env, const sp<InputChannel>& inputChannel,
+            int32_t displayId, bool isGestureMonitor);
     status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
+    status_t pilferPointers(const sp<IBinder>& token);
 
     void setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray, int32_t displayId);
     void setFocusedApplication(JNIEnv* env, int32_t displayId, jobject applicationHandleObj);
@@ -259,6 +262,7 @@
     virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
     virtual bool checkInjectEventsPermissionNonReentrant(
             int32_t injectorPid, int32_t injectorUid);
+    virtual void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken);
 
     /* --- PointerControllerPolicyInterface implementation --- */
 
@@ -441,12 +445,24 @@
             inputChannel, displayId);
 }
 
+status_t NativeInputManager::registerInputMonitor(JNIEnv* /* env */,
+        const sp<InputChannel>& inputChannel, int32_t displayId, bool isGestureMonitor) {
+    ATRACE_CALL();
+    return mInputManager->getDispatcher()->registerInputMonitor(
+            inputChannel, displayId, isGestureMonitor);
+}
+
 status_t NativeInputManager::unregisterInputChannel(JNIEnv* /* env */,
         const sp<InputChannel>& inputChannel) {
     ATRACE_CALL();
     return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
 }
 
+status_t NativeInputManager::pilferPointers(const sp<IBinder>& token) {
+    ATRACE_CALL();
+    return mInputManager->getDispatcher()->pilferPointers(token);
+}
+
 void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
     ATRACE_CALL();
     JNIEnv* env = jniEnv();
@@ -1205,6 +1221,15 @@
     return result;
 }
 
+void NativeInputManager::onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) {
+    ATRACE_CALL();
+    JNIEnv* env = jniEnv();
+
+    jobject touchedTokenObj = javaObjectForIBinder(env, touchedToken);
+    env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDownOutsideFocus, touchedTokenObj);
+    checkAndClearExceptionFromCallback(env, "onPointerDownOutsideFocus");
+}
+
 void NativeInputManager::loadPointerIcon(SpriteIcon* icon, int32_t displayId) {
     ATRACE_CALL();
     JNIEnv* env = jniEnv();
@@ -1385,7 +1410,6 @@
         throwInputChannelNotInitialized(env);
         return;
     }
-    bool monitor = inputChannel->getToken() == nullptr && displayId != ADISPLAY_ID_NONE;
 
     status_t status = im->registerInputChannel(env, inputChannel, displayId);
 
@@ -1396,10 +1420,33 @@
         return;
     }
 
-    // If inputWindowHandle is null and displayId >= 0, treat inputChannel as monitor.
-    if (!monitor) {
-        android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
-                handleInputChannelDisposed, im);
+    android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
+            handleInputChannelDisposed, im);
+}
+
+static void nativeRegisterInputMonitor(JNIEnv* env, jclass /* clazz */,
+        jlong ptr, jobject inputChannelObj, jint displayId, jboolean isGestureMonitor) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
+            inputChannelObj);
+    if (inputChannel == nullptr) {
+        throwInputChannelNotInitialized(env);
+        return;
+    }
+
+    if (displayId == ADISPLAY_ID_NONE) {
+        std::string message = "InputChannel used as a monitor must be associated with a display";
+        jniThrowRuntimeException(env, message.c_str());
+        return;
+    }
+
+    status_t status = im->registerInputMonitor(env, inputChannel, displayId, isGestureMonitor);
+
+    if (status) {
+        std::string message = StringPrintf("Failed to register input channel.  status=%d", status);
+        jniThrowRuntimeException(env, message.c_str());
+        return;
     }
 }
 
@@ -1424,6 +1471,13 @@
     }
 }
 
+static void nativePilferPointers(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    sp<IBinder> token = ibinderForJavaObject(env, tokenObj);
+    im->pilferPointers(token);
+}
+
+
 static void nativeSetInputFilterEnabled(JNIEnv* /* env */, jclass /* clazz */,
         jlong ptr, jboolean enabled) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1686,8 +1740,13 @@
     { "nativeRegisterInputChannel",
             "(JLandroid/view/InputChannel;I)V",
             (void*) nativeRegisterInputChannel },
+    { "nativeRegisterInputMonitor",
+            "(JLandroid/view/InputChannel;IZ)V",
+            (void*) nativeRegisterInputMonitor},
     { "nativeUnregisterInputChannel", "(JLandroid/view/InputChannel;)V",
             (void*) nativeUnregisterInputChannel },
+    { "nativePilferPointers", "(JLandroid/os/IBinder;)V",
+            (void*) nativePilferPointers },
     { "nativeSetInputFilterEnabled", "(JZ)V",
             (void*) nativeSetInputFilterEnabled },
     { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I",
@@ -1781,7 +1840,7 @@
 
     GET_METHOD_ID(gServiceClassInfo.notifyInputChannelBroken, clazz,
             "notifyInputChannelBroken", "(Landroid/os/IBinder;)V");
-    
+
     GET_METHOD_ID(gServiceClassInfo.notifyFocusChanged, clazz,
             "notifyFocusChanged", "(Landroid/os/IBinder;Landroid/os/IBinder;)V");
 
@@ -1809,6 +1868,9 @@
     GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz,
             "checkInjectEventsPermission", "(II)Z");
 
+    GET_METHOD_ID(gServiceClassInfo.onPointerDownOutsideFocus, clazz,
+            "onPointerDownOutsideFocus", "(Landroid/os/IBinder;)V");
+
     GET_METHOD_ID(gServiceClassInfo.getVirtualKeyQuietTimeMillis, clazz,
             "getVirtualKeyQuietTimeMillis", "()I");
 
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 7df7ef3..f447f47 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -52,7 +52,7 @@
 static jmethodID method_reportSvStatus;
 static jmethodID method_reportAGpsStatus;
 static jmethodID method_reportNmea;
-static jmethodID method_setEngineCapabilities;
+static jmethodID method_setTopHalCapabilities;
 static jmethodID method_setGnssYearOfHardware;
 static jmethodID method_setGnssHardwareModelName;
 static jmethodID method_xtraDownloadRequest;
@@ -71,7 +71,7 @@
 static jmethodID method_reportNavigationMessages;
 static jmethodID method_reportLocationBatch;
 static jmethodID method_reportGnssServiceDied;
-static jmethodID method_setMeasurementCorrectionsCapabilities;
+static jmethodID method_setSubHalMeasurementCorrectionsCapabilities;
 static jmethodID method_correctionsGetLatitudeDegrees;
 static jmethodID method_correctionsGetLongitudeDegrees;
 static jmethodID method_correctionsGetAltitudeMeters;
@@ -754,7 +754,7 @@
     ALOGD("%s: capabilities=%du, hasSubHalCapabilityFlags=%d\n", __func__, capabilities,
         hasSubHalCapabilityFlags);
     JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities,
+    env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities,
             boolToJbool(hasSubHalCapabilityFlags));
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
     return Void();
@@ -1237,7 +1237,8 @@
 Return<void> MeasurementCorrectionsCallback::setCapabilitiesCb(uint32_t capabilities) {
     ALOGD("%s: %du\n", __func__, capabilities);
     JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_setMeasurementCorrectionsCapabilities, capabilities);
+    env->CallVoidMethod(mCallbacksObj, method_setSubHalMeasurementCorrectionsCapabilities,
+                        capabilities);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
     return Void();
 }
@@ -1541,7 +1542,7 @@
     method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
     method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
     method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
-    method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(IZ)V");
+    method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(IZ)V");
     method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
     method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
             "(Ljava/lang/String;)V");
@@ -1581,8 +1582,8 @@
             "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
     method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z");
 
-    method_setMeasurementCorrectionsCapabilities = env->GetMethodID(clazz,
-            "setMeasurementCorrectionsCapabilities", "(I)V");
+    method_setSubHalMeasurementCorrectionsCapabilities = env->GetMethodID(clazz,
+            "setSubHalMeasurementCorrectionsCapabilities", "(I)V");
 
     jclass measCorrClass = env->FindClass("android/location/GnssMeasurementCorrections");
     method_correctionsGetLatitudeDegrees = env->GetMethodID(
@@ -1700,8 +1701,12 @@
         gnssNavigationMessageIface = gnssNavigationMessage;
     }
 
-    if (gnssHal_V2_0 != nullptr) {
-        // TODO: getExtensionGnssMeasurement_1_1 from gnssHal_V2_0
+    // Allow all causal combinations between IGnss.hal and IGnssMeasurement.hal. That means,
+    // 2.0@IGnss can be paired with {1.0, 1,1, 2.0}@IGnssMeasurement
+    // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement
+    // 1.0@IGnss is paired with 1.0@IGnssMeasurement
+    gnssMeasurementIface = nullptr;
+    if (gnssHal_V2_0 != nullptr && gnssMeasurementIface == nullptr) {
         auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
         if (!gnssMeasurement.isOk()) {
             ALOGD("Unable to get a handle to GnssMeasurement_V2_0");
@@ -1710,13 +1715,8 @@
             gnssMeasurementIface_V1_1 = gnssMeasurementIface_V2_0;
             gnssMeasurementIface = gnssMeasurementIface_V2_0;
         }
-        auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections();
-        if (!gnssCorrections.isOk()) {
-            ALOGD("Unable to get a handle to GnssMeasurementCorrections interface");
-        } else {
-            gnssCorrectionsIface = gnssCorrections;
-        }
-    } else if (gnssHal_V1_1 != nullptr) {
+    }
+    if (gnssHal_V1_1 != nullptr && gnssMeasurementIface == nullptr) {
          auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
          if (!gnssMeasurement.isOk()) {
              ALOGD("Unable to get a handle to GnssMeasurement_V1_1");
@@ -1724,16 +1724,26 @@
              gnssMeasurementIface_V1_1 = gnssMeasurement;
              gnssMeasurementIface = gnssMeasurementIface_V1_1;
          }
-    } else {
-         auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
-         if (!gnssMeasurement_V1_0.isOk()) {
+    }
+    if (gnssMeasurementIface == nullptr) {
+         auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
+         if (!gnssMeasurement.isOk()) {
              ALOGD("Unable to get a handle to GnssMeasurement");
          } else {
-             gnssMeasurementIface = gnssMeasurement_V1_0;
+             gnssMeasurementIface = gnssMeasurement;
          }
     }
 
     if (gnssHal_V2_0 != nullptr) {
+        auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections();
+        if (!gnssCorrections.isOk()) {
+            ALOGD("Unable to get a handle to GnssMeasurementCorrections interface");
+        } else {
+            gnssCorrectionsIface = gnssCorrections;
+        }
+    }
+
+    if (gnssHal_V2_0 != nullptr) {
         auto gnssDebug = gnssHal_V2_0->getExtensionGnssDebug_2_0();
         if (!gnssDebug.isOk()) {
             ALOGD("Unable to get a handle to GnssDebug_V2_0");
diff --git a/services/core/xsd/Android.bp b/services/core/xsd/Android.bp
index 5e1ea89..98e4343 100644
--- a/services/core/xsd/Android.bp
+++ b/services/core/xsd/Android.bp
@@ -2,5 +2,5 @@
     name: "default-permissions",
     srcs: ["default-permissions.xsd"],
     api_dir: "schema",
-    package_name: "com.android.server.pm.permission",
+    package_name: "com.android.server.pm.permission.configfile",
 }
diff --git a/services/core/xsd/default-permissions.xsd b/services/core/xsd/default-permissions.xsd
index d800a26..2e32be0 100644
--- a/services/core/xsd/default-permissions.xsd
+++ b/services/core/xsd/default-permissions.xsd
@@ -27,7 +27,7 @@
     </xs:element>
     <xs:complexType name="exception">
         <xs:sequence>
-            <xs:element name="permission" type="permission"/>
+            <xs:element name="permission" type="permission" maxOccurs="unbounded"/>
         </xs:sequence>
         <xs:attribute name="package" type="xs:string"/>
         <xs:attribute name="sha256-cert-digest" type="xs:string"/>
diff --git a/services/core/xsd/schema/current.txt b/services/core/xsd/schema/current.txt
index 4e67e5c..a2092e3 100644
--- a/services/core/xsd/schema/current.txt
+++ b/services/core/xsd/schema/current.txt
@@ -1,21 +1,20 @@
 // Signature format: 2.0
-package com.android.server.pm.permission {
+package com.android.server.pm.permission.configfile {
 
   public class Exception {
     ctor public Exception();
     method public String getBrand();
-    method public com.android.server.pm.permission.Permission getPermission();
+    method public java.util.List<com.android.server.pm.permission.configfile.Permission> getPermission();
     method public String getSha256CertDigest();
     method public String get_package();
     method public void setBrand(String);
-    method public void setPermission(com.android.server.pm.permission.Permission);
     method public void setSha256CertDigest(String);
     method public void set_package(String);
   }
 
   public class Exceptions {
     ctor public Exceptions();
-    method public java.util.List<com.android.server.pm.permission.Exception> getException();
+    method public java.util.List<com.android.server.pm.permission.configfile.Exception> getException();
   }
 
   public class Permission {
@@ -28,7 +27,7 @@
 
   public class XmlParser {
     ctor public XmlParser();
-    method public static com.android.server.pm.permission.Exceptions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static com.android.server.pm.permission.configfile.Exceptions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
   }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index 2bf6f35..cfa9944 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -15,17 +15,10 @@
  */
 package com.android.server.devicepolicy;
 
-import android.app.admin.DevicePolicyManager;
 import android.app.admin.IDevicePolicyManager;
-import android.app.admin.StartInstallingUpdateCallback;
-import android.content.ComponentName;
-import android.os.ParcelFileDescriptor;
 
 import com.android.server.SystemService;
 
-import java.util.Collections;
-import java.util.List;
-
 /**
  * Defines the required interface for IDevicePolicyManager implemenation.
  *
@@ -63,83 +56,4 @@
 
     public void clearSystemUpdatePolicyFreezePeriodRecord() {
     }
-
-    @Override
-    public long forceNetworkLogs() {
-        return 0;
-    }
-
-    @Override
-    public long forceSecurityLogs() {
-        return 0;
-    }
-
-    @Override
-    public boolean checkDeviceIdentifierAccess(String packageName, int userHandle, int pid,
-            int uid) {
-        return false;
-    }
-
-    @Override
-    public int setGlobalPrivateDns(ComponentName who, int mode, String privateDnsHost) {
-        return DevicePolicyManager.PRIVATE_DNS_SET_ERROR_FAILURE_SETTING;
-    }
-
-    @Override
-    public int getGlobalPrivateDnsMode(ComponentName who) {
-        return DevicePolicyManager.PRIVATE_DNS_MODE_UNKNOWN;
-    }
-
-    @Override
-    public String getGlobalPrivateDnsHost(ComponentName who) {
-        return null;
-    }
-
-    @Override
-    public void grantDeviceIdsAccessToProfileOwner(ComponentName who, int userId) { }
-
-    @Override
-    public int getPasswordComplexity() {
-        return DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
-    }
-
-    @Override
-    public void installUpdateFromFile(ComponentName admin,
-            ParcelFileDescriptor updateFileDescriptor, StartInstallingUpdateCallback listener) {}
-
-    @Override
-    public void setCrossProfileCalendarPackages(ComponentName admin, List<String> packageNames) {
-    }
-
-    @Override
-    public List<String> getCrossProfileCalendarPackages(ComponentName admin) {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public boolean isPackageAllowedToAccessCalendarForUser(String packageName,
-            int userHandle) {
-        return false;
-    }
-
-    @Override
-    public List<String> getCrossProfileCalendarPackagesForUser(int userHandle) {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public boolean isManagedKiosk() {
-        return false;
-    }
-
-    @Override
-    public boolean isUnattendedManagedKiosk() {
-        return false;
-    }
-
-    @Override
-    public boolean startViewCalendarEventInManagedProfile(String packageName, long eventId,
-            long start, long end, boolean allDay, int flags) {
-        return false;
-    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 633367a..d014c0a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -8398,13 +8398,40 @@
     }
 
     @Override
-    public boolean checkDeviceIdentifierAccess(String packageName, int userHandle, int pid,
-            int uid) {
+    public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) {
         // If the caller is not a system app then it should only be able to check its own device
         // identifier access.
-        int callingAppId = UserHandle.getAppId(mInjector.binderGetCallingUid());
-        if (callingAppId >= Process.FIRST_APPLICATION_UID
-                && callingAppId != UserHandle.getAppId(uid)) {
+        int callingUid = mInjector.binderGetCallingUid();
+        int callingPid = mInjector.binderGetCallingPid();
+        if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID
+                && (callingUid != uid || callingPid != pid)) {
+            String message = String.format(
+                    "Calling uid %d, pid %d cannot check device identifier access for package %s "
+                            + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid);
+            Log.w(LOG_TAG, message);
+            throw new SecurityException(message);
+        }
+        // Verify that the specified packages matches the provided uid.
+        int userId = UserHandle.getUserId(uid);
+        try {
+            ApplicationInfo appInfo = mIPackageManager.getApplicationInfo(packageName, 0, userId);
+            // Since this call goes directly to PackageManagerService a NameNotFoundException is not
+            // thrown but null data can be returned; if the appInfo for the specified package cannot
+            // be found then return false to prevent crashing the app.
+            if (appInfo == null) {
+                Log.w(LOG_TAG,
+                        String.format("appInfo could not be found for package %s", packageName));
+                return false;
+            } else if (uid != appInfo.uid) {
+                String message = String.format("Package %s (uid=%d) does not match provided uid %d",
+                        packageName, appInfo.uid, uid);
+                Log.w(LOG_TAG, message);
+                throw new SecurityException(message);
+            }
+        } catch (RemoteException e) {
+            // If an exception is caught obtaining the appInfo just return false to prevent crashing
+            // apps due to an internal error.
+            Log.e(LOG_TAG, "Exception caught obtaining appInfo for package " + packageName, e);
             return false;
         }
         // A device or profile owner must also have the READ_PHONE_STATE permission to access device
@@ -8421,7 +8448,7 @@
             return true;
         }
         // Allow access to the profile owner for the specified user, or delegate cert installer
-        ComponentName profileOwner = getProfileOwnerAsUser(userHandle);
+        ComponentName profileOwner = getProfileOwnerAsUser(userId);
         if (profileOwner != null && (profileOwner.getPackageName().equals(packageName)
                     || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
             return true;
@@ -11180,48 +11207,51 @@
 
         @Override
         public Intent createUserRestrictionSupportIntent(int userId, String userRestriction) {
-            int source;
-            long ident = mInjector.binderClearCallingIdentity();
+            final long ident = mInjector.binderClearCallingIdentity();
             try {
-                source = mUserManager.getUserRestrictionSource(userRestriction,
-                        UserHandle.of(userId));
+                final List<UserManager.EnforcingUser> sources = mUserManager
+                        .getUserRestrictionSources(userRestriction, UserHandle.of(userId));
+                if (sources == null || sources.isEmpty()) {
+                    // The restriction is not enforced.
+                    return null;
+                } else if (sources.size() > 1) {
+                    // In this case, we'll show an admin support dialog that does not
+                    // specify the admin.
+                    // TODO(b/128928355): if this restriction is enforced by multiple DPCs, return
+                    // the admin for the calling user.
+                    return DevicePolicyManagerService.this.createShowAdminSupportIntent(
+                            null, userId);
+                }
+                final UserManager.EnforcingUser enforcingUser = sources.get(0);
+                final int sourceType = enforcingUser.getUserRestrictionSource();
+                final int enforcingUserId = enforcingUser.getUserHandle().getIdentifier();
+                if (sourceType == UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) {
+                    // Restriction was enforced by PO
+                    final ComponentName profileOwner = mOwners.getProfileOwnerComponent(
+                            enforcingUserId);
+                    if (profileOwner != null) {
+                        return DevicePolicyManagerService.this.createShowAdminSupportIntent(
+                                profileOwner, enforcingUserId);
+                    }
+                } else if (sourceType == UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) {
+                    // Restriction was enforced by DO
+                    final Pair<Integer, ComponentName> deviceOwner =
+                            mOwners.getDeviceOwnerUserIdAndComponent();
+                    if (deviceOwner != null) {
+                        return DevicePolicyManagerService.this.createShowAdminSupportIntent(
+                                deviceOwner.second, deviceOwner.first);
+                    }
+                } else if (sourceType == UserManager.RESTRICTION_SOURCE_SYSTEM) {
+                    /*
+                     * In this case, the user restriction is enforced by the system.
+                     * So we won't show an admin support intent, even if it is also
+                     * enforced by a profile/device owner.
+                     */
+                    return null;
+                }
             } finally {
                 mInjector.binderRestoreCallingIdentity(ident);
             }
-            if ((source & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
-                /*
-                 * In this case, the user restriction is enforced by the system.
-                 * So we won't show an admin support intent, even if it is also
-                 * enforced by a profile/device owner.
-                 */
-                return null;
-            }
-            boolean enforcedByDo = (source & UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) != 0;
-            boolean enforcedByPo = (source & UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) != 0;
-            if (enforcedByDo && enforcedByPo) {
-                // In this case, we'll show an admin support dialog that does not
-                // specify the admin.
-                return DevicePolicyManagerService.this.createShowAdminSupportIntent(null, userId);
-            } else if (enforcedByPo) {
-                final ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId);
-                if (profileOwner != null) {
-                    return DevicePolicyManagerService.this
-                            .createShowAdminSupportIntent(profileOwner, userId);
-                }
-                // This could happen if another thread has changed the profile owner since we called
-                // getUserRestrictionSource
-                return null;
-            } else if (enforcedByDo) {
-                final Pair<Integer, ComponentName> deviceOwner
-                        = mOwners.getDeviceOwnerUserIdAndComponent();
-                if (deviceOwner != null) {
-                    return DevicePolicyManagerService.this
-                            .createShowAdminSupportIntent(deviceOwner.second, deviceOwner.first);
-                }
-                // This could happen if another thread has changed the device owner since we called
-                // getUserRestrictionSource
-                return null;
-            }
             return null;
         }
 
@@ -14093,6 +14123,11 @@
     @Override
     public void installUpdateFromFile(ComponentName admin,
             ParcelFileDescriptor updateFileDescriptor, StartInstallingUpdateCallback callback) {
+        DevicePolicyEventLogger
+                .createEvent(DevicePolicyEnums.INSTALL_SYSTEM_UPDATE)
+                .setAdmin(admin)
+                .setBoolean(isDeviceAB())
+                .write();
         enforceDeviceOwner(admin);
         final long id = mInjector.binderClearCallingIdentity();
         try {
@@ -14105,11 +14140,6 @@
                         mContext, updateFileDescriptor, callback, mInjector, mConstants);
             }
             updateInstaller.startInstallUpdate();
-            DevicePolicyEventLogger
-                    .createEvent(DevicePolicyEnums.INSTALL_SYSTEM_UPDATE)
-                    .setAdmin(admin)
-                    .setBoolean(isDeviceAB())
-                    .write();
         } finally {
             mInjector.binderRestoreCallingIdentity(id);
         }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d4ccb0b..9d09c4c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2133,6 +2133,11 @@
 
             traceBeginAndSlog("StartNetworkStack");
             try {
+                // Note : the network stack is creating on-demand objects that need to send
+                // broadcasts, which means it currently depends on being started after
+                // ActivityManagerService.mSystemReady and ActivityManagerService.mProcessesReady
+                // are set to true. Be careful if moving this to a different place in the
+                // startup sequence.
                 NetworkStackClient.getInstance().start(context);
             } catch (Throwable e) {
                 reportWtf("starting Network Stack", e);
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 9e1d44b..f73a285 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -25,7 +25,6 @@
     local_include_dir: "java",
     include_dirs: ["frameworks/base/core/java"],  // For framework parcelables.
     srcs: [
-        "java/android/net/ApfCapabilitiesParcelable.aidl",
         "java/android/net/DhcpResultsParcelable.aidl",
         "java/android/net/IIpMemoryStore.aidl",
         "java/android/net/IIpMemoryStoreCallbacks.aidl",
@@ -36,7 +35,6 @@
         "java/android/net/InitialConfigurationParcelable.aidl",
         "java/android/net/PrivateDnsConfigParcel.aidl",
         "java/android/net/ProvisioningConfigurationParcelable.aidl",
-        "java/android/net/StaticIpConfigurationParcelable.aidl",
         "java/android/net/TcpKeepalivePacketDataParcelable.aidl",
         "java/android/net/dhcp/DhcpServingParamsParcel.aidl",
         "java/android/net/dhcp/IDhcpServer.aidl",
@@ -60,6 +58,8 @@
     name: "services.net",
     srcs: ["java/**/*.java"],
     static_libs: [
+        "dnsresolver_aidl_interface-java",
+        "ipmemorystore-client",
         "netd_aidl_interface-java",
         "networkstack-aidl-interfaces-java",
     ]
@@ -71,7 +71,7 @@
     srcs: [
         ":framework-annotations",
         "java/android/net/IpMemoryStoreClient.java",
-        "java/android/net/ipmemorystore/**.java",
+        "java/android/net/ipmemorystore/**/*.java",
     ],
     static_libs: [
         "ipmemorystore-aidl-interfaces-java",
diff --git a/services/net/java/android/net/ApfCapabilitiesParcelable.aidl b/services/net/java/android/net/ApfCapabilitiesParcelable.aidl
deleted file mode 100644
index f0645d2..0000000
--- a/services/net/java/android/net/ApfCapabilitiesParcelable.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-parcelable ApfCapabilitiesParcelable {
-    int apfVersionSupported;
-    int maximumApfProgramSize;
-    int apfPacketFormat;
-}
\ No newline at end of file
diff --git a/services/net/java/android/net/DhcpResultsParcelable.aidl b/services/net/java/android/net/DhcpResultsParcelable.aidl
index cf5629b..978638b 100644
--- a/services/net/java/android/net/DhcpResultsParcelable.aidl
+++ b/services/net/java/android/net/DhcpResultsParcelable.aidl
@@ -16,10 +16,10 @@
 
 package android.net;
 
-import android.net.StaticIpConfigurationParcelable;
+import android.net.StaticIpConfiguration;
 
 parcelable DhcpResultsParcelable {
-    StaticIpConfigurationParcelable baseConfiguration;
+    StaticIpConfiguration baseConfiguration;
     int leaseDuration;
     int mtu;
     String serverAddress;
diff --git a/services/net/java/android/net/IIpMemoryStore.aidl b/services/net/java/android/net/IIpMemoryStore.aidl
index 6f88dec..63feae6 100644
--- a/services/net/java/android/net/IIpMemoryStore.aidl
+++ b/services/net/java/android/net/IIpMemoryStore.aidl
@@ -20,8 +20,8 @@
 import android.net.ipmemorystore.NetworkAttributesParcelable;
 import android.net.ipmemorystore.IOnBlobRetrievedListener;
 import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
+import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
 import android.net.ipmemorystore.IOnStatusListener;
 
 /** {@hide} */
@@ -84,7 +84,7 @@
      * @param listener The listener that will be invoked to return the answer.
      * @return (through the listener) A SameL3NetworkResponse containing the answer and confidence.
      */
-    void isSameNetwork(String l2Key1, String l2Key2, IOnSameNetworkResponseListener listener);
+    void isSameNetwork(String l2Key1, String l2Key2, IOnSameL3NetworkResponseListener listener);
 
     /**
      * Retrieve the network attributes for a key.
@@ -95,7 +95,7 @@
      * @return (through the listener) The network attributes and the L2 key associated with
      *         the query.
      */
-    void retrieveNetworkAttributes(String l2Key, IOnNetworkAttributesRetrieved listener);
+    void retrieveNetworkAttributes(String l2Key, IOnNetworkAttributesRetrievedListener listener);
 
     /**
      * Retrieve previously stored private data.
diff --git a/services/net/java/android/net/INetworkMonitor.aidl b/services/net/java/android/net/INetworkMonitor.aidl
index 1b0e1d7..b32ef12 100644
--- a/services/net/java/android/net/INetworkMonitor.aidl
+++ b/services/net/java/android/net/INetworkMonitor.aidl
@@ -15,6 +15,8 @@
  */
 package android.net;
 
+import android.net.LinkProperties;
+import android.net.NetworkCapabilities;
 import android.net.PrivateDnsConfigParcel;
 
 /** @hide */
@@ -45,9 +47,8 @@
     void forceReevaluation(int uid);
     void notifyPrivateDnsChanged(in PrivateDnsConfigParcel config);
     void notifyDnsResponse(int returnCode);
-    void notifySystemReady();
-    void notifyNetworkConnected();
+    void notifyNetworkConnected(in LinkProperties lp, in NetworkCapabilities nc);
     void notifyNetworkDisconnected();
-    void notifyLinkPropertiesChanged();
-    void notifyNetworkCapabilitiesChanged();
-}
\ No newline at end of file
+    void notifyLinkPropertiesChanged(in LinkProperties lp);
+    void notifyNetworkCapabilitiesChanged(in NetworkCapabilities nc);
+}
diff --git a/services/net/java/android/net/IpMemoryStoreClient.java b/services/net/java/android/net/IpMemoryStoreClient.java
index 2f4fdbd..379c017 100644
--- a/services/net/java/android/net/IpMemoryStoreClient.java
+++ b/services/net/java/android/net/IpMemoryStoreClient.java
@@ -20,14 +20,13 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.IOnBlobRetrievedListener;
-import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrieved;
-import android.net.ipmemorystore.IOnSameNetworkResponseListener;
-import android.net.ipmemorystore.IOnStatusListener;
 import android.net.ipmemorystore.NetworkAttributes;
+import android.net.ipmemorystore.OnBlobRetrievedListener;
+import android.net.ipmemorystore.OnL2KeyResponseListener;
+import android.net.ipmemorystore.OnNetworkAttributesRetrievedListener;
+import android.net.ipmemorystore.OnSameL3NetworkResponseListener;
+import android.net.ipmemorystore.OnStatusListener;
 import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -50,12 +49,6 @@
     @NonNull
     protected abstract IIpMemoryStore getService() throws InterruptedException, ExecutionException;
 
-    protected StatusParcelable internalErrorStatus() {
-        final StatusParcelable error = new StatusParcelable();
-        error.resultCode = Status.ERROR_UNKNOWN;
-        return error;
-    }
-
     /**
      * Store network attributes for a given L2 key.
      * If L2Key is null, choose automatically from the attributes ; passing null is equivalent to
@@ -74,12 +67,13 @@
      */
     public void storeNetworkAttributes(@NonNull final String l2Key,
             @NonNull final NetworkAttributes attributes,
-            @Nullable final IOnStatusListener listener) {
+            @Nullable final OnStatusListener listener) {
         try {
             try {
-                getService().storeNetworkAttributes(l2Key, attributes.toParcelable(), listener);
+                getService().storeNetworkAttributes(l2Key, attributes.toParcelable(),
+                        OnStatusListener.toAIDL(listener));
             } catch (InterruptedException | ExecutionException m) {
-                listener.onComplete(internalErrorStatus());
+                listener.onComplete(new Status(Status.ERROR_UNKNOWN));
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error storing network attributes", e);
@@ -99,12 +93,13 @@
      */
     public void storeBlob(@NonNull final String l2Key, @NonNull final String clientId,
             @NonNull final String name, @NonNull final Blob data,
-            @Nullable final IOnStatusListener listener) {
+            @Nullable final OnStatusListener listener) {
         try {
             try {
-                getService().storeBlob(l2Key, clientId, name, data, listener);
+                getService().storeBlob(l2Key, clientId, name, data,
+                        OnStatusListener.toAIDL(listener));
             } catch (InterruptedException | ExecutionException m) {
-                listener.onComplete(internalErrorStatus());
+                listener.onComplete(new Status(Status.ERROR_UNKNOWN));
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error storing blob", e);
@@ -126,12 +121,13 @@
      * Through the listener, returns the L2 key if one matched, or null.
      */
     public void findL2Key(@NonNull final NetworkAttributes attributes,
-            @NonNull final IOnL2KeyResponseListener listener) {
+            @NonNull final OnL2KeyResponseListener listener) {
         try {
             try {
-                getService().findL2Key(attributes.toParcelable(), listener);
+                getService().findL2Key(attributes.toParcelable(),
+                        OnL2KeyResponseListener.toAIDL(listener));
             } catch (InterruptedException | ExecutionException m) {
-                listener.onL2KeyResponse(internalErrorStatus(), null);
+                listener.onL2KeyResponse(new Status(Status.ERROR_UNKNOWN), null);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error finding L2 Key", e);
@@ -148,12 +144,13 @@
      * Through the listener, a SameL3NetworkResponse containing the answer and confidence.
      */
     public void isSameNetwork(@NonNull final String l2Key1, @NonNull final String l2Key2,
-            @NonNull final IOnSameNetworkResponseListener listener) {
+            @NonNull final OnSameL3NetworkResponseListener listener) {
         try {
             try {
-                getService().isSameNetwork(l2Key1, l2Key2, listener);
+                getService().isSameNetwork(l2Key1, l2Key2,
+                        OnSameL3NetworkResponseListener.toAIDL(listener));
             } catch (InterruptedException | ExecutionException m) {
-                listener.onSameNetworkResponse(internalErrorStatus(), null);
+                listener.onSameL3NetworkResponse(new Status(Status.ERROR_UNKNOWN), null);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error checking for network sameness", e);
@@ -170,12 +167,13 @@
      *         the query.
      */
     public void retrieveNetworkAttributes(@NonNull final String l2Key,
-            @NonNull final IOnNetworkAttributesRetrieved listener) {
+            @NonNull final OnNetworkAttributesRetrievedListener listener) {
         try {
             try {
-                getService().retrieveNetworkAttributes(l2Key, listener);
+                getService().retrieveNetworkAttributes(l2Key,
+                        OnNetworkAttributesRetrievedListener.toAIDL(listener));
             } catch (InterruptedException | ExecutionException m) {
-                listener.onNetworkAttributesRetrieved(internalErrorStatus(), null, null);
+                listener.onNetworkAttributesRetrieved(new Status(Status.ERROR_UNKNOWN), null, null);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error retrieving network attributes", e);
@@ -194,12 +192,13 @@
      *         and the name of the data associated with the query.
      */
     public void retrieveBlob(@NonNull final String l2Key, @NonNull final String clientId,
-            @NonNull final String name, @NonNull final IOnBlobRetrievedListener listener) {
+            @NonNull final String name, @NonNull final OnBlobRetrievedListener listener) {
         try {
             try {
-                getService().retrieveBlob(l2Key, clientId, name, listener);
+                getService().retrieveBlob(l2Key, clientId, name,
+                        OnBlobRetrievedListener.toAIDL(listener));
             } catch (InterruptedException | ExecutionException m) {
-                listener.onBlobRetrieved(internalErrorStatus(), null, null, null);
+                listener.onBlobRetrieved(new Status(Status.ERROR_UNKNOWN), null, null, null);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error retrieving blob", e);
diff --git a/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl
index 5b46d7f..99606fb 100644
--- a/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl
+++ b/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl
@@ -17,10 +17,10 @@
 
 package android.net;
 
-import android.net.ApfCapabilitiesParcelable;
 import android.net.InitialConfigurationParcelable;
 import android.net.Network;
-import android.net.StaticIpConfigurationParcelable;
+import android.net.StaticIpConfiguration;
+import android.net.apf.ApfCapabilities;
 
 parcelable ProvisioningConfigurationParcelable {
     boolean enableIPv4;
@@ -29,8 +29,8 @@
     boolean usingIpReachabilityMonitor;
     int requestedPreDhcpActionMs;
     InitialConfigurationParcelable initialConfig;
-    StaticIpConfigurationParcelable staticIpConfig;
-    ApfCapabilitiesParcelable apfCapabilities;
+    StaticIpConfiguration staticIpConfig;
+    ApfCapabilities apfCapabilities;
     int provisioningTimeoutMs;
     int ipv6AddrGenMode;
     Network network;
diff --git a/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl b/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
similarity index 94%
rename from services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl
rename to services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
index fb4ca3b..870e217 100644
--- a/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrieved.aidl
+++ b/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -20,7 +20,7 @@
 import android.net.ipmemorystore.StatusParcelable;
 
 /** {@hide} */
-oneway interface IOnNetworkAttributesRetrieved {
+oneway interface IOnNetworkAttributesRetrievedListener {
     /**
      * Network attributes were fetched for the specified L2 key. While the L2 key will never
      * be null, the attributes may be if no data is stored about this L2 key.
diff --git a/services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl b/services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
similarity index 89%
rename from services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl
rename to services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
index 294bd3b..b8ccfb9 100644
--- a/services/net/java/android/net/ipmemorystore/IOnSameNetworkResponseListener.aidl
+++ b/services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -20,10 +20,10 @@
 import android.net.ipmemorystore.StatusParcelable;
 
 /** {@hide} */
-oneway interface IOnSameNetworkResponseListener {
+oneway interface IOnSameL3NetworkResponseListener {
     /**
      * The memory store has come up with the answer to a query that was sent.
      */
-     void onSameNetworkResponse(in StatusParcelable status,
+     void onSameL3NetworkResponse(in StatusParcelable status,
              in SameL3NetworkResponseParcelable response);
 }
diff --git a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java b/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
index 6a9eae0..e769769 100644
--- a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
+++ b/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
@@ -60,6 +60,13 @@
     public final Inet4Address assignedV4Address;
     private static final float WEIGHT_ASSIGNEDV4ADDR = 300.0f;
 
+    // The lease expiry timestamp of v4 address allocated from DHCP server, in milliseconds.
+    @Nullable
+    public final Long assignedV4AddressExpiry;
+    // lease expiry doesn't imply any correlation between "the same lease expiry value" and "the
+    // same L3 network".
+    private static final float WEIGHT_ASSIGNEDV4ADDREXPIRY = 0.0f;
+
     // Optionally supplied by the client if it has an opinion on L3 network. For example, this
     // could be a hash of the SSID + security type on WiFi.
     @Nullable
@@ -81,6 +88,7 @@
     /** @hide */
     @VisibleForTesting
     public static final float TOTAL_WEIGHT = WEIGHT_ASSIGNEDV4ADDR
+            + WEIGHT_ASSIGNEDV4ADDREXPIRY
             + WEIGHT_GROUPHINT
             + WEIGHT_DNSADDRESSES
             + WEIGHT_MTU;
@@ -89,11 +97,16 @@
     @VisibleForTesting
     public NetworkAttributes(
             @Nullable final Inet4Address assignedV4Address,
+            @Nullable final Long assignedV4AddressExpiry,
             @Nullable final String groupHint,
             @Nullable final List<InetAddress> dnsAddresses,
             @Nullable final Integer mtu) {
         if (mtu != null && mtu < 0) throw new IllegalArgumentException("MTU can't be negative");
+        if (assignedV4AddressExpiry != null && assignedV4AddressExpiry <= 0) {
+            throw new IllegalArgumentException("lease expiry can't be negative or zero");
+        }
         this.assignedV4Address = assignedV4Address;
+        this.assignedV4AddressExpiry = assignedV4AddressExpiry;
         this.groupHint = groupHint;
         this.dnsAddresses = null == dnsAddresses ? null :
                 Collections.unmodifiableList(new ArrayList<>(dnsAddresses));
@@ -105,6 +118,8 @@
         // The call to the other constructor must be the first statement of this constructor,
         // so everything has to be inline
         this((Inet4Address) getByAddressOrNull(parcelable.assignedV4Address),
+                parcelable.assignedV4AddressExpiry > 0
+                        ? parcelable.assignedV4AddressExpiry : null,
                 parcelable.groupHint,
                 blobArrayToInetAddressList(parcelable.dnsAddresses),
                 parcelable.mtu >= 0 ? parcelable.mtu : null);
@@ -150,6 +165,8 @@
         final NetworkAttributesParcelable parcelable = new NetworkAttributesParcelable();
         parcelable.assignedV4Address =
                 (null == assignedV4Address) ? null : assignedV4Address.getAddress();
+        parcelable.assignedV4AddressExpiry =
+                (null == assignedV4AddressExpiry) ? 0 : assignedV4AddressExpiry;
         parcelable.groupHint = groupHint;
         parcelable.dnsAddresses = inetAddressListToBlobArray(dnsAddresses);
         parcelable.mtu = (null == mtu) ? -1 : mtu;
@@ -168,6 +185,8 @@
     public float getNetworkGroupSamenessConfidence(@NonNull final NetworkAttributes o) {
         final float samenessScore =
                 samenessContribution(WEIGHT_ASSIGNEDV4ADDR, assignedV4Address, o.assignedV4Address)
+                + samenessContribution(WEIGHT_ASSIGNEDV4ADDREXPIRY, assignedV4AddressExpiry,
+                      o.assignedV4AddressExpiry)
                 + samenessContribution(WEIGHT_GROUPHINT, groupHint, o.groupHint)
                 + samenessContribution(WEIGHT_DNSADDRESSES, dnsAddresses, o.dnsAddresses)
                 + samenessContribution(WEIGHT_MTU, mtu, o.mtu);
@@ -189,6 +208,8 @@
         @Nullable
         private Inet4Address mAssignedAddress;
         @Nullable
+        private Long mAssignedAddressExpiry;
+        @Nullable
         private String mGroupHint;
         @Nullable
         private List<InetAddress> mDnsAddresses;
@@ -206,6 +227,20 @@
         }
 
         /**
+         * Set the lease expiry timestamp of assigned v4 address.
+         * @param assignedV4AddressExpiry The lease expiry timestamp of assigned v4 address.
+         * @return This builder.
+         */
+        public Builder setAssignedV4AddressExpiry(
+                @Nullable final Long assignedV4AddressExpiry) {
+            if (null != assignedV4AddressExpiry && assignedV4AddressExpiry <= 0) {
+                throw new IllegalArgumentException("lease expiry can't be negative or zero");
+            }
+            mAssignedAddressExpiry = assignedV4AddressExpiry;
+            return this;
+        }
+
+        /**
          * Set the group hint.
          * @param groupHint The group hint.
          * @return This builder.
@@ -248,14 +283,15 @@
          * @return The built NetworkAttributes object.
          */
         public NetworkAttributes build() {
-            return new NetworkAttributes(mAssignedAddress, mGroupHint, mDnsAddresses, mMtu);
+            return new NetworkAttributes(mAssignedAddress, mAssignedAddressExpiry,
+                  mGroupHint, mDnsAddresses, mMtu);
         }
     }
 
     /** @hide */
     public boolean isEmpty() {
-        return (null == assignedV4Address) && (null == groupHint)
-                && (null == dnsAddresses) && (null == mtu);
+        return (null == assignedV4Address) && (null == assignedV4AddressExpiry)
+                && (null == groupHint) && (null == dnsAddresses) && (null == mtu);
     }
 
     @Override
@@ -263,6 +299,7 @@
         if (!(o instanceof NetworkAttributes)) return false;
         final NetworkAttributes other = (NetworkAttributes) o;
         return Objects.equals(assignedV4Address, other.assignedV4Address)
+                && Objects.equals(assignedV4AddressExpiry, other.assignedV4AddressExpiry)
                 && Objects.equals(groupHint, other.groupHint)
                 && Objects.equals(dnsAddresses, other.dnsAddresses)
                 && Objects.equals(mtu, other.mtu);
@@ -270,7 +307,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(assignedV4Address, groupHint, dnsAddresses, mtu);
+        return Objects.hash(assignedV4Address, assignedV4AddressExpiry,
+                groupHint, dnsAddresses, mtu);
     }
 
     /** Pretty print */
@@ -286,6 +324,13 @@
             nullFields.add("assignedV4Addr");
         }
 
+        if (null != assignedV4AddressExpiry) {
+            resultJoiner.add("assignedV4AddressExpiry :");
+            resultJoiner.add(assignedV4AddressExpiry.toString());
+        } else {
+            nullFields.add("assignedV4AddressExpiry");
+        }
+
         if (null != groupHint) {
             resultJoiner.add("groupHint :");
             resultJoiner.add(groupHint);
diff --git a/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
index 0894d72..997eb2b 100644
--- a/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ b/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -30,6 +30,7 @@
  */
 parcelable NetworkAttributesParcelable {
     byte[] assignedV4Address;
+    long assignedV4AddressExpiry;
     String groupHint;
     Blob[] dnsAddresses;
     int mtu;
diff --git a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
new file mode 100644
index 0000000..9685ff6
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a blob.
+ * @hide
+ */
+public interface OnBlobRetrievedListener {
+    /**
+     * The memory store has come up with the answer to a query that was sent.
+     */
+    void onBlobRetrieved(Status status, String l2Key, String name, Blob blob);
+
+    /** Converts this OnBlobRetrievedListener to a parcelable object */
+    @NonNull
+    static IOnBlobRetrievedListener toAIDL(final OnBlobRetrievedListener listener) {
+        return new IOnBlobRetrievedListener.Stub() {
+            @Override
+            public void onBlobRetrieved(final StatusParcelable statusParcelable, final String l2Key,
+                    final String name, final Blob blob) {
+                listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob);
+            }
+        };
+    }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
new file mode 100644
index 0000000..80209c5
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a L2 key.
+ * @hide
+ */
+public interface OnL2KeyResponseListener {
+    /**
+     * The operation has completed with the specified status.
+     */
+    void onL2KeyResponse(Status status, String l2Key);
+
+    /** Converts this OnL2KeyResponseListener to a parcelable object */
+    @NonNull
+    static IOnL2KeyResponseListener toAIDL(final OnL2KeyResponseListener listener) {
+        return new IOnL2KeyResponseListener.Stub() {
+            @Override
+            public void onL2KeyResponse(final StatusParcelable statusParcelable,
+                    final String l2Key) {
+                listener.onL2KeyResponse(new Status(statusParcelable), l2Key);
+            }
+        };
+    }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
new file mode 100644
index 0000000..f0f6f40
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return network attributes.
+ * @hide
+ */
+public interface OnNetworkAttributesRetrievedListener {
+    /**
+     * The memory store has come up with the answer to a query that was sent.
+     */
+    void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attributes);
+
+    /** Converts this OnNetworkAttributesRetrievedListener to a parcelable object */
+    @NonNull
+    static IOnNetworkAttributesRetrievedListener toAIDL(
+            final OnNetworkAttributesRetrievedListener listener) {
+        return new IOnNetworkAttributesRetrievedListener.Stub() {
+            @Override
+            public void onNetworkAttributesRetrieved(final StatusParcelable statusParcelable,
+                    final String l2Key,
+                    final NetworkAttributesParcelable networkAttributesParcelable) {
+                listener.onNetworkAttributesRetrieved(
+                        new Status(statusParcelable), l2Key,
+                        new NetworkAttributes(networkAttributesParcelable));
+            }
+        };
+    }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
new file mode 100644
index 0000000..ba1e0e6
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a response about network sameness.
+ * @hide
+ */
+public interface OnSameL3NetworkResponseListener {
+    /**
+     * The memory store has come up with the answer to a query that was sent.
+     */
+    void onSameL3NetworkResponse(Status status, SameL3NetworkResponse response);
+
+    /** Converts this OnSameL3NetworkResponseListener to a parcelable object */
+    @NonNull
+    static IOnSameL3NetworkResponseListener toAIDL(final OnSameL3NetworkResponseListener listener) {
+        return new IOnSameL3NetworkResponseListener.Stub() {
+            @Override
+            public void onSameL3NetworkResponse(final StatusParcelable statusParcelable,
+                    final SameL3NetworkResponseParcelable sameL3NetworkResponseParcelable) {
+                listener.onSameL3NetworkResponse(
+                        new Status(statusParcelable),
+                        new SameL3NetworkResponse(sameL3NetworkResponseParcelable));
+            }
+        };
+    }
+}
diff --git a/services/net/java/android/net/ipmemorystore/OnStatusListener.java b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
new file mode 100644
index 0000000..0de1666
--- /dev/null
+++ b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/**
+ * A listener for the IpMemoryStore to return a status to a client.
+ * @hide
+ */
+public interface OnStatusListener {
+    /**
+     * The operation has completed with the specified status.
+     */
+    void onComplete(Status status);
+
+    /** Converts this OnStatusListener to a parcelable object */
+    @NonNull
+    static IOnStatusListener toAIDL(final OnStatusListener listener) {
+        return new IOnStatusListener.Stub() {
+            @Override
+            public void onComplete(final StatusParcelable statusParcelable) {
+                listener.onComplete(new Status(statusParcelable));
+            }
+        };
+    }
+}
diff --git a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
index 6b5826f..44d8e0c 100644
--- a/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
+++ b/services/net/java/android/net/shared/IpConfigurationParcelableUtil.java
@@ -16,17 +16,10 @@
 
 package android.net.shared;
 
-import static android.net.shared.ParcelableUtil.fromParcelableArray;
-import static android.net.shared.ParcelableUtil.toParcelableArray;
-
 import android.annotation.Nullable;
-import android.net.ApfCapabilitiesParcelable;
 import android.net.DhcpResults;
 import android.net.DhcpResultsParcelable;
 import android.net.InetAddresses;
-import android.net.StaticIpConfiguration;
-import android.net.StaticIpConfigurationParcelable;
-import android.net.apf.ApfCapabilities;
 
 import java.net.Inet4Address;
 import java.net.InetAddress;
@@ -38,44 +31,12 @@
  */
 public final class IpConfigurationParcelableUtil {
     /**
-     * Convert a StaticIpConfiguration to a StaticIpConfigurationParcelable.
-     */
-    public static StaticIpConfigurationParcelable toStableParcelable(
-            @Nullable StaticIpConfiguration config) {
-        if (config == null) return null;
-        final StaticIpConfigurationParcelable p = new StaticIpConfigurationParcelable();
-        p.ipAddress = config.getIpAddress();
-        p.gateway = parcelAddress(config.getGateway());
-        p.dnsServers = toParcelableArray(
-                config.getDnsServers(), IpConfigurationParcelableUtil::parcelAddress, String.class);
-        p.domains = config.getDomains();
-        return p;
-    }
-
-    /**
-     * Convert a StaticIpConfigurationParcelable to a StaticIpConfiguration.
-     */
-    public static StaticIpConfiguration fromStableParcelable(
-            @Nullable StaticIpConfigurationParcelable p) {
-        if (p == null) return null;
-        final StaticIpConfiguration config = new StaticIpConfiguration();
-        config.setIpAddress(p.ipAddress);
-        config.setGateway(unparcelAddress(p.gateway));
-        for (InetAddress addr : fromParcelableArray(
-                p.dnsServers, IpConfigurationParcelableUtil::unparcelAddress)) {
-            config.addDnsServer(addr);
-        }
-        config.setDomains(p.domains);
-        return config;
-    }
-
-    /**
      * Convert DhcpResults to a DhcpResultsParcelable.
      */
     public static DhcpResultsParcelable toStableParcelable(@Nullable DhcpResults results) {
         if (results == null) return null;
         final DhcpResultsParcelable p = new DhcpResultsParcelable();
-        p.baseConfiguration = toStableParcelable(results.toStaticIpConfiguration());
+        p.baseConfiguration = results.toStaticIpConfiguration();
         p.leaseDuration = results.leaseDuration;
         p.mtu = results.mtu;
         p.serverAddress = parcelAddress(results.serverAddress);
@@ -88,7 +49,7 @@
      */
     public static DhcpResults fromStableParcelable(@Nullable DhcpResultsParcelable p) {
         if (p == null) return null;
-        final DhcpResults results = new DhcpResults(fromStableParcelable(p.baseConfiguration));
+        final DhcpResults results = new DhcpResults(p.baseConfiguration);
         results.leaseDuration = p.leaseDuration;
         results.mtu = p.mtu;
         results.serverAddress = (Inet4Address) unparcelAddress(p.serverAddress);
@@ -97,27 +58,6 @@
     }
 
     /**
-     * Convert ApfCapabilities to ApfCapabilitiesParcelable.
-     */
-    public static ApfCapabilitiesParcelable toStableParcelable(@Nullable ApfCapabilities caps) {
-        if (caps == null) return null;
-        final ApfCapabilitiesParcelable p = new ApfCapabilitiesParcelable();
-        p.apfVersionSupported = caps.apfVersionSupported;
-        p.maximumApfProgramSize = caps.maximumApfProgramSize;
-        p.apfPacketFormat = caps.apfPacketFormat;
-        return p;
-    }
-
-    /**
-     * Convert ApfCapabilitiesParcelable toApfCapabilities.
-     */
-    public static ApfCapabilities fromStableParcelable(@Nullable ApfCapabilitiesParcelable p) {
-        if (p == null) return null;
-        return new ApfCapabilities(
-                p.apfVersionSupported, p.maximumApfProgramSize, p.apfPacketFormat);
-    }
-
-    /**
      * Convert InetAddress to String.
      * TODO: have an InetAddressParcelable
      */
diff --git a/services/net/java/android/net/shared/ProvisioningConfiguration.java b/services/net/java/android/net/shared/ProvisioningConfiguration.java
index 0aceb22..6f9c294 100644
--- a/services/net/java/android/net/shared/ProvisioningConfiguration.java
+++ b/services/net/java/android/net/shared/ProvisioningConfiguration.java
@@ -235,8 +235,10 @@
         p.usingIpReachabilityMonitor = mUsingIpReachabilityMonitor;
         p.requestedPreDhcpActionMs = mRequestedPreDhcpActionMs;
         p.initialConfig = mInitialConfig == null ? null : mInitialConfig.toStableParcelable();
-        p.staticIpConfig = IpConfigurationParcelableUtil.toStableParcelable(mStaticIpConfig);
-        p.apfCapabilities = IpConfigurationParcelableUtil.toStableParcelable(mApfCapabilities);
+        p.staticIpConfig = mStaticIpConfig == null
+                ? null
+                : new StaticIpConfiguration(mStaticIpConfig);
+        p.apfCapabilities = mApfCapabilities; // ApfCapabilities is immutable
         p.provisioningTimeoutMs = mProvisioningTimeoutMs;
         p.ipv6AddrGenMode = mIPv6AddrGenMode;
         p.network = mNetwork;
@@ -257,10 +259,10 @@
         config.mUsingIpReachabilityMonitor = p.usingIpReachabilityMonitor;
         config.mRequestedPreDhcpActionMs = p.requestedPreDhcpActionMs;
         config.mInitialConfig = InitialConfiguration.fromStableParcelable(p.initialConfig);
-        config.mStaticIpConfig = IpConfigurationParcelableUtil.fromStableParcelable(
-                p.staticIpConfig);
-        config.mApfCapabilities = IpConfigurationParcelableUtil.fromStableParcelable(
-                p.apfCapabilities);
+        config.mStaticIpConfig = p.staticIpConfig == null
+                ? null
+                : new StaticIpConfiguration(p.staticIpConfig);
+        config.mApfCapabilities = p.apfCapabilities; // ApfCapabilities is immutable
         config.mProvisioningTimeoutMs = p.provisioningTimeoutMs;
         config.mIPv6AddrGenMode = p.ipv6AddrGenMode;
         config.mNetwork = p.network;
diff --git a/services/robotests/backup/Android.mk b/services/robotests/backup/Android.mk
index cc59b0c..bd4ebbd 100644
--- a/services/robotests/backup/Android.mk
+++ b/services/robotests/backup/Android.mk
@@ -26,7 +26,7 @@
 LOCAL_PRIVILEGED_MODULE := true
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    bmgrlib \
+    bmgr \
     bu \
     services.backup \
     services.core \
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index 7c91b64..7a40e44 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -26,6 +26,7 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -57,6 +58,8 @@
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.IActivityManager;
+import android.app.IAlarmCompleteListener;
+import android.app.IAlarmListener;
 import android.app.IUidObserver;
 import android.app.PendingIntent;
 import android.app.usage.UsageStatsManagerInternal;
@@ -67,6 +70,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
@@ -231,7 +235,7 @@
         doReturn(Looper.getMainLooper()).when(Looper::myLooper);
 
         when(mMockContext.getContentResolver()).thenReturn(mMockResolver);
-        doReturn("min_futurity=0").when(() ->
+        doReturn("min_futurity=0,min_interval=0").when(() ->
                 Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS));
         mInjector = new Injector(mMockContext);
         mService = new AlarmManagerService(mMockContext, mInjector);
@@ -249,6 +253,7 @@
         // Other boot phases don't matter
         mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
         assertEquals(0, mService.mConstants.MIN_FUTURITY);
+        assertEquals(0, mService.mConstants.MIN_INTERVAL);
         mAppStandbyWindow = mService.mConstants.APP_STANDBY_WINDOW;
         ArgumentCaptor<UsageStatsManagerInternal.AppIdleStateChangeListener> captor =
                 ArgumentCaptor.forClass(UsageStatsManagerInternal.AppIdleStateChangeListener.class);
@@ -257,15 +262,28 @@
     }
 
     private void setTestAlarm(int type, long triggerTime, PendingIntent operation) {
-        setTestAlarm(type, triggerTime, operation, TEST_CALLING_UID);
+        setTestAlarm(type, triggerTime, operation, 0, TEST_CALLING_UID);
     }
 
-    private void setTestAlarm(int type, long triggerTime, PendingIntent operation, int callingUid) {
-        mService.setImpl(type, triggerTime, AlarmManager.WINDOW_EXACT, 0,
+    private void setRepeatingTestAlarm(int type, long firstTrigger, long interval,
+            PendingIntent pi) {
+        setTestAlarm(type, firstTrigger, pi, interval, TEST_CALLING_UID);
+    }
+
+    private void setTestAlarm(int type, long triggerTime, PendingIntent operation, long interval,
+            int callingUid) {
+        mService.setImpl(type, triggerTime, AlarmManager.WINDOW_EXACT, interval,
                 operation, null, "test", AlarmManager.FLAG_STANDALONE, null, null,
                 callingUid, TEST_CALLING_PACKAGE);
     }
 
+    private void setTestAlarmWithListener(int type, long triggerTime, IAlarmListener listener) {
+        mService.setImpl(type, triggerTime, AlarmManager.WINDOW_EXACT, 0,
+                null, listener, "test", AlarmManager.FLAG_STANDALONE, null, null,
+                TEST_CALLING_UID, TEST_CALLING_PACKAGE);
+    }
+
+
     private PendingIntent getNewMockPendingIntent() {
         return getNewMockPendingIntent(TEST_CALLING_UID);
     }
@@ -738,14 +756,14 @@
     @Test
     public void alarmCountKeyedOnCallingUid() {
         final int mockCreatorUid = 431412;
-        final PendingIntent pi = getNewMockPendingIntent(mockCreatorUid);
-        setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 5, pi);
+        setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 5,
+                getNewMockPendingIntent(mockCreatorUid));
         assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
         assertEquals(-1, mService.mAlarmsPerUid.get(mockCreatorUid, -1));
     }
 
     @Test
-    public void alarmCountOnSet() {
+    public void alarmCountOnSetPi() {
         final int numAlarms = 103;
         final int[] types = {RTC_WAKEUP, RTC, ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME};
         for (int i = 1; i <= numAlarms; i++) {
@@ -755,7 +773,21 @@
     }
 
     @Test
-    public void alarmCountOnExpiration() throws InterruptedException {
+    public void alarmCountOnSetListener() {
+        final int numAlarms = 103;
+        final int[] types = {RTC_WAKEUP, RTC, ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME};
+        for (int i = 1; i <= numAlarms; i++) {
+            setTestAlarmWithListener(types[i % 4], mNowElapsedTest + i, new IAlarmListener.Stub() {
+                @Override
+                public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
+                }
+            });
+            assertEquals(i, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        }
+    }
+
+    @Test
+    public void alarmCountOnExpirationPi() throws InterruptedException {
         final int numAlarms = 8; // This test is slow
         for (int i = 0; i < numAlarms; i++) {
             setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, getNewMockPendingIntent());
@@ -770,6 +802,86 @@
     }
 
     @Test
+    public void alarmCountOnExpirationListener() throws InterruptedException {
+        final int numAlarms = 8; // This test is slow
+        for (int i = 0; i < numAlarms; i++) {
+            setTestAlarmWithListener(ELAPSED_REALTIME, mNowElapsedTest + i + 10,
+                    new IAlarmListener.Stub() {
+                        @Override
+                        public void doAlarm(IAlarmCompleteListener callback)
+                                throws RemoteException {
+                        }
+                    });
+        }
+        int expired = 0;
+        while (expired < numAlarms) {
+            mNowElapsedTest = mTestTimer.getElapsed();
+            mTestTimer.expire();
+            expired++;
+            assertEquals(numAlarms - expired, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0));
+        }
+    }
+
+    @Test
+    public void alarmCountOnExceptionWhileSendingPi() throws Exception {
+        final int numAlarms = 5; // This test is slow
+        for (int i = 0; i < numAlarms; i++) {
+            final PendingIntent pi = getNewMockPendingIntent();
+            doThrow(PendingIntent.CanceledException.class).when(pi).send(eq(mMockContext), eq(0),
+                    any(), any(), any(), any(), any());
+            setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, pi);
+        }
+        int expired = 0;
+        while (expired < numAlarms) {
+            mNowElapsedTest = mTestTimer.getElapsed();
+            mTestTimer.expire();
+            expired++;
+            assertEquals(numAlarms - expired, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0));
+        }
+    }
+
+    @Test
+    public void alarmCountOnExceptionWhileCallingListener() throws Exception {
+        final int numAlarms = 5; // This test is slow
+        for (int i = 0; i < numAlarms; i++) {
+            final IAlarmListener listener = new IAlarmListener.Stub() {
+                @Override
+                public void doAlarm(IAlarmCompleteListener callback) throws RemoteException {
+                    throw new RemoteException("For testing behavior on exception");
+                }
+            };
+            setTestAlarmWithListener(ELAPSED_REALTIME, mNowElapsedTest + i + 10, listener);
+        }
+        int expired = 0;
+        while (expired < numAlarms) {
+            mNowElapsedTest = mTestTimer.getElapsed();
+            mTestTimer.expire();
+            expired++;
+            assertEquals(numAlarms - expired, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0));
+        }
+    }
+
+    @Test
+    public void alarmCountForRepeatingAlarms() throws Exception {
+        final long interval = 1231;
+        final long firstTrigger = mNowElapsedTest + 321;
+        final PendingIntent pi = getNewMockPendingIntent();
+        setRepeatingTestAlarm(ELAPSED_REALTIME, firstTrigger, interval, pi);
+        assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+
+        for (int i = 0; i < 5; i++) {
+            mNowElapsedTest = mTestTimer.getElapsed();
+            mTestTimer.expire();
+            assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        }
+        doThrow(PendingIntent.CanceledException.class).when(pi).send(eq(mMockContext), eq(0),
+                any(), any(), any(), any(), any());
+        mNowElapsedTest = mTestTimer.getElapsed();
+        mTestTimer.expire();
+        assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1));
+    }
+
+    @Test
     public void alarmCountOnUidRemoved() {
         final int numAlarms = 10;
         for (int i = 0; i < numAlarms; i++) {
@@ -798,7 +910,7 @@
         for (int i = 0; i < numAlarms; i++) {
             int mockUid = UserHandle.getUid(mockUserId, 1234 + i);
             setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10,
-                    getNewMockPendingIntent(mockUid), mockUid);
+                    getNewMockPendingIntent(mockUid), 0, mockUid);
         }
         assertEquals(numAlarms, mService.mAlarmsPerUid.size());
         mService.removeUserLocked(mockUserId);
@@ -820,6 +932,12 @@
         }
     }
 
+    @Test
+    public void alarmCountOnInvalidSet() {
+        setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 12345, null);
+        assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1));
+    }
+
     @After
     public void tearDown() {
         if (mMockingSession != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java
index e100d16..b0c97d1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java
@@ -23,6 +23,7 @@
 
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.platform.test.annotations.Presubmit;
 import android.provider.DeviceConfig;
 
 import com.android.server.appop.AppOpsService;
@@ -44,8 +45,9 @@
  * Tests for {@link AppCompactor}.
  *
  * Build/Install/Run:
- * atest FrameworksServicesTests:AppCompactorTest
+ * atest FrameworksMockingServicesTests:AppCompactorTest
  */
+@Presubmit
 @RunWith(MockitoJUnitRunner.class)
 public final class AppCompactorTest {
 
@@ -129,6 +131,12 @@
                 AppCompactor.KEY_COMPACT_THROTTLE_4,
                 Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1), false);
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                AppCompactor.KEY_COMPACT_THROTTLE_5,
+                Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_5 + 1), false);
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                AppCompactor.KEY_COMPACT_THROTTLE_6,
+                Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_6 + 1), false);
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                 AppCompactor.KEY_COMPACT_STATSD_SAMPLE_RATE,
                 Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false);
 
@@ -151,6 +159,10 @@
                 AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1);
         assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo(
                 AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f);
+        assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo(
+                AppCompactor.DEFAULT_COMPACT_THROTTLE_5 + 1);
+        assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo(
+                AppCompactor.DEFAULT_COMPACT_THROTTLE_6 + 1);
     }
 
     @Test
@@ -254,7 +266,7 @@
         mCompactorUnderTest.init();
 
         // When we override new reasonable throttle values after init...
-        mCountDown = new CountDownLatch(4);
+        mCountDown = new CountDownLatch(6);
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                 AppCompactor.KEY_COMPACT_THROTTLE_1,
                 Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1), false);
@@ -267,6 +279,12 @@
         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                 AppCompactor.KEY_COMPACT_THROTTLE_4,
                 Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1), false);
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                AppCompactor.KEY_COMPACT_THROTTLE_5,
+                Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_5 + 1), false);
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                AppCompactor.KEY_COMPACT_THROTTLE_6,
+                Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_6 + 1), false);
         assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue();
 
         // Then those flags values are reflected in the compactor.
@@ -278,6 +296,10 @@
                 AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1);
         assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo(
                 AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1);
+        assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo(
+                AppCompactor.DEFAULT_COMPACT_THROTTLE_5 + 1);
+        assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo(
+                AppCompactor.DEFAULT_COMPACT_THROTTLE_6 + 1);
     }
 
     @Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index cad71a2..08f6a37 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -722,6 +722,147 @@
         assertEquals(expectedStats, newStatsRare);
     }
 
+    /**
+     * Test getTimeUntilQuotaConsumedLocked when the determination is based within the bucket
+     * window.
+     */
+    @Test
+    public void testGetTimeUntilQuotaConsumedLocked_BucketWindow() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        // Close to RARE boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (24 * HOUR_IN_MILLIS - 30 * SECOND_IN_MILLIS),
+                        30 * SECOND_IN_MILLIS, 5));
+        // Far away from FREQUENT boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (7 * HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+        // Overlap WORKING_SET boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS),
+                        3 * MINUTE_IN_MILLIS, 5));
+        // Close to ACTIVE boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (9 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+
+        setStandbyBucket(RARE_INDEX);
+        assertEquals(30 * SECOND_IN_MILLIS,
+                mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertEquals(MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(FREQUENT_INDEX);
+        assertEquals(MINUTE_IN_MILLIS,
+                mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertEquals(MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        setStandbyBucket(WORKING_INDEX);
+        assertEquals(5 * MINUTE_IN_MILLIS,
+                mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertEquals(7 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        // ACTIVE window = allowed time, so jobs can essentially run non-stop until they reach the
+        // max execution time.
+        setStandbyBucket(ACTIVE_INDEX);
+        assertEquals(7 * MINUTE_IN_MILLIS,
+                mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertEquals(mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /**
+     * Test getTimeUntilQuotaConsumedLocked when the app is close to the max execution limit.
+     */
+    @Test
+    public void testGetTimeUntilQuotaConsumedLocked_MaxExecution() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        // Overlap boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(
+                        now - (24 * HOUR_IN_MILLIS + 8 * MINUTE_IN_MILLIS), 4 * HOUR_IN_MILLIS, 5));
+
+        setStandbyBucket(WORKING_INDEX);
+        assertEquals(8 * MINUTE_IN_MILLIS,
+                mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        // Max time will phase out, so should use bucket limit.
+        assertEquals(10 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
+        // Close to boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (24 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS),
+                        4 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS, 5));
+
+        setStandbyBucket(WORKING_INDEX);
+        assertEquals(5 * MINUTE_IN_MILLIS,
+                mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertEquals(10 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
+        // Far from boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(
+                        now - (20 * HOUR_IN_MILLIS), 4 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS, 5));
+
+        setStandbyBucket(WORKING_INDEX);
+        assertEquals(3 * MINUTE_IN_MILLIS,
+                mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        assertEquals(3 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
+    /**
+     * Test getTimeUntilQuotaConsumedLocked when the max execution time and bucket window time
+     * remaining are equal.
+     */
+    @Test
+    public void testGetTimeUntilQuotaConsumedLocked_EqualTimeRemaining() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        setStandbyBucket(FREQUENT_INDEX);
+
+        // Overlap boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(
+                        now - (24 * HOUR_IN_MILLIS + 11 * MINUTE_IN_MILLIS),
+                        4 * HOUR_IN_MILLIS,
+                        5));
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(
+                        now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+
+        // Both max and bucket time have 8 minutes left.
+        assertEquals(8 * MINUTE_IN_MILLIS,
+                mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        // Max time essentially free. Bucket time has 2 min phase out plus original 8 minute
+        // window time.
+        assertEquals(10 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+
+        mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
+        // Overlap boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(
+                        now - (24 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 2 * MINUTE_IN_MILLIS, 5));
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(
+                        now - (20 * HOUR_IN_MILLIS),
+                        3 * HOUR_IN_MILLIS + 48 * MINUTE_IN_MILLIS,
+                        5));
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(
+                        now - (8 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5));
+
+        // Both max and bucket time have 8 minutes left.
+        assertEquals(8 * MINUTE_IN_MILLIS,
+                mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+        // Max time only has one minute phase out. Bucket time has 2 minute phase out.
+        assertEquals(9 * MINUTE_IN_MILLIS,
+                mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
+    }
+
     @Test
     public void testIsWithinQuotaLocked_NeverApp() {
         assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test.never", NEVER_INDEX));
@@ -1902,7 +2043,10 @@
         // window, so as the package "reaches its quota" it will have more to keep running.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - 2 * HOUR_IN_MILLIS,
-                        10 * MINUTE_IN_MILLIS - remainingTimeMs, 1));
+                        10 * SECOND_IN_MILLIS - remainingTimeMs, 1));
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - HOUR_IN_MILLIS,
+                        9 * MINUTE_IN_MILLIS + 50 * SECOND_IN_MILLIS, 1));
 
         assertEquals(remainingTimeMs, mQuotaController.getRemainingExecutionTimeLocked(jobStatus));
         // Start the job.
@@ -1919,6 +2063,18 @@
         // amount of remaining time left its quota.
         assertEquals(remainingTimeMs,
                 mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
-        verify(handler, atLeast(1)).sendMessageDelayed(any(), eq(remainingTimeMs));
+        // Handler is told to check when the quota will be consumed, not when the initial
+        // remaining time is over.
+        verify(handler, atLeast(1)).sendMessageDelayed(any(), eq(10 * SECOND_IN_MILLIS));
+        verify(handler, never()).sendMessageDelayed(any(), eq(remainingTimeMs));
+
+        // After 10 seconds, the job should finally be out of quota.
+        advanceElapsedClock(10 * SECOND_IN_MILLIS - remainingTimeMs);
+        // Wait for some extra time to allow for job processing.
+        verify(mJobSchedulerService,
+                timeout(12 * SECOND_IN_MILLIS).times(1))
+                .onControllerStateChanged();
+        assertFalse(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+        verify(handler, never()).sendMessageDelayed(any(), anyInt());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
index 2ed25ea..f336497 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
@@ -23,10 +23,12 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.IAccessibilityServiceClient;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -46,6 +48,7 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 
 
@@ -149,4 +152,21 @@
         assertTrue(mConnection.getServiceInfo().crashed);
         verify(mMockKeyEventDispatcher).flush(mConnection);
     }
+
+    @Test
+    public void connectedService_notInEnabledServiceList_doNotInitClient()
+            throws RemoteException {
+        IBinder mockBinder = mock(IBinder.class);
+        IAccessibilityServiceClient mockClient = mock(IAccessibilityServiceClient.class);
+        when(mockBinder.queryLocalInterface(any())).thenReturn(mockClient);
+        when(mMockUserState.getEnabledServicesLocked())
+                .thenReturn(Collections.emptySet());
+        setServiceBinding(COMPONENT_NAME);
+
+        mConnection.bindLocked();
+        mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
+        mHandler.sendAllMessages();
+        verify(mMockSystemSupport, times(2)).onClientChangeLocked(false);
+        verify(mockClient, times(0)).init(any(), anyInt(), any());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 04abeca1..46d0761 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -34,7 +34,9 @@
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
@@ -64,13 +66,17 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.os.UserManagerInternal;
+import android.os.storage.IStorageManager;
 import android.platform.test.annotations.Presubmit;
 import android.util.Log;
 
+
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
+import com.android.server.FgThread;
 import com.android.server.pm.UserManagerService;
 import com.android.server.wm.WindowManagerService;
 
@@ -79,7 +85,9 @@
 import org.junit.Test;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -92,12 +100,20 @@
  */
 @SmallTest
 @Presubmit
+
 public class UserControllerTest {
-    private static final int TEST_USER_ID = 10;
+    // Use big enough user id to avoid picking up already active user id.
+    private static final int TEST_USER_ID = 100;
+    private static final int TEST_USER_ID1 = 101;
+    private static final int TEST_USER_ID2 = 102;
     private static final int NONEXIST_USER_ID = 2;
     private static final String TAG = UserControllerTest.class.getSimpleName();
+
+    private static final long HANDLER_WAIT_TIME_MS = 100;
+
     private UserController mUserController;
     private TestInjector mInjector;
+    private final HashMap<Integer, UserState> mUserStates = new HashMap<>();
 
     private static final List<String> START_FOREGROUND_USER_ACTIONS = newArrayList(
             Intent.ACTION_USER_STARTED,
@@ -127,6 +143,11 @@
             doNothing().when(mInjector).startHomeActivity(anyInt(), anyString());
             doReturn(false).when(mInjector).stackSupervisorSwitchUser(anyInt(), any());
             doNothing().when(mInjector).stackSupervisorResumeFocusedStackTopActivity();
+            doNothing().when(mInjector).systemServiceManagerCleanupUser(anyInt());
+            doNothing().when(mInjector).activityManagerForceStopPackage(anyInt(), anyString());
+            doNothing().when(mInjector).activityManagerOnUserStopped(anyInt());
+            doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());
+            doNothing().when(mInjector).stackSupervisorRemoveUser(anyInt());
             mUserController = new UserController(mInjector);
             setUpUser(TEST_USER_ID, 0);
         });
@@ -258,7 +279,7 @@
     }
 
     @Test
-    public void testContinueUserSwitch() {
+    public void testContinueUserSwitch() throws RemoteException {
         // Start user -- this will update state of mUserController
         mUserController.startUser(TEST_USER_ID, true);
         Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
@@ -270,11 +291,11 @@
         // Verify that continueUserSwitch worked as expected
         mUserController.continueUserSwitch(userState, oldUserId, newUserId);
         verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
-        continueUserSwitchAssertions();
+        continueUserSwitchAssertions(TEST_USER_ID, false);
     }
 
     @Test
-    public void testContinueUserSwitchUIDisabled() {
+    public void testContinueUserSwitchUIDisabled() throws RemoteException {
         mUserController.mUserSwitchUiEnabled = false;
         // Start user -- this will update state of mUserController
         mUserController.startUser(TEST_USER_ID, true);
@@ -287,16 +308,21 @@
         // Verify that continueUserSwitch worked as expected
         mUserController.continueUserSwitch(userState, oldUserId, newUserId);
         verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
-        continueUserSwitchAssertions();
+        continueUserSwitchAssertions(TEST_USER_ID, false);
     }
 
-    private void continueUserSwitchAssertions() {
-        Set<Integer> expectedCodes = Collections.singleton(REPORT_USER_SWITCH_COMPLETE_MSG);
+    private void continueUserSwitchAssertions(int expectedUserId, boolean backgroundUserStopping)
+            throws RemoteException {
+        Set<Integer> expectedCodes = new LinkedHashSet<>();
+        expectedCodes.add(REPORT_USER_SWITCH_COMPLETE_MSG);
+        if (backgroundUserStopping) {
+            expectedCodes.add(0); // this is for directly posting in stopping.
+        }
         Set<Integer> actualCodes = mInjector.mHandler.getMessageCodes();
         assertEquals("Unexpected message sent", expectedCodes, actualCodes);
         Message msg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_COMPLETE_MSG);
         assertNotNull(msg);
-        assertEquals("Unexpected userId", TEST_USER_ID, msg.arg1);
+        assertEquals("Unexpected userId", expectedUserId, msg.arg1);
     }
 
     @Test
@@ -321,6 +347,128 @@
         verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false);
     }
 
+    @Test
+    public void testExplicitSystenUserStartInBackground() {
+        setUpUser(UserHandle.USER_SYSTEM, 0);
+        assertFalse(mUserController.isSystemUserStarted());
+        assertTrue(mUserController.startUser(UserHandle.USER_SYSTEM, false, null));
+        assertTrue(mUserController.isSystemUserStarted());
+    }
+
+    /**
+     * Test stopping of user from max running users limit.
+     */
+    @Test
+    public void testUserStoppingForMultipleUsersNormalMode()
+            throws InterruptedException, RemoteException {
+        setUpUser(TEST_USER_ID1, 0);
+        setUpUser(TEST_USER_ID2, 0);
+        mUserController.mMaxRunningUsers = 3;
+        int numerOfUserSwitches = 1;
+        addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM,
+                numerOfUserSwitches, false);
+        // running: user 0, USER_ID
+        assertTrue(mUserController.canStartMoreUsers());
+        assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}),
+                mUserController.getRunningUsersLU());
+
+        numerOfUserSwitches++;
+        addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID,
+                numerOfUserSwitches, false);
+        // running: user 0, USER_ID, USER_ID1
+        assertFalse(mUserController.canStartMoreUsers());
+        assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID, TEST_USER_ID1}),
+                mUserController.getRunningUsersLU());
+
+        numerOfUserSwitches++;
+        addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1,
+                numerOfUserSwitches, false);
+        UserState ussUser2 = mUserStates.get(TEST_USER_ID2);
+        // skip middle step and call this directly.
+        mUserController.finishUserSwitch(ussUser2);
+        waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS);
+        // running: user 0, USER_ID1, USER_ID2
+        // USER_ID should be stopped as it is least recently used non user0.
+        assertFalse(mUserController.canStartMoreUsers());
+        assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1, TEST_USER_ID2}),
+                mUserController.getRunningUsersLU());
+    }
+
+    /**
+     * This test tests delayed locking mode using 4 users. As core logic of delayed locking is
+     * happening in finishUserStopped call, the test also calls finishUserStopped while skipping
+     * all middle steps which takes too much work to mock.
+     */
+    @Test
+    public void testUserStoppingForMultipleUsersDelayedLockingMode()
+            throws InterruptedException, RemoteException {
+        setUpUser(TEST_USER_ID1, 0);
+        setUpUser(TEST_USER_ID2, 0);
+        mUserController.mMaxRunningUsers = 3;
+        mUserController.mDelayUserDataLocking = true;
+        int numerOfUserSwitches = 1;
+        addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM,
+                numerOfUserSwitches, false);
+        // running: user 0, USER_ID
+        assertTrue(mUserController.canStartMoreUsers());
+        assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID}),
+                mUserController.getRunningUsersLU());
+        numerOfUserSwitches++;
+
+        addForegroundUserAndContinueUserSwitch(TEST_USER_ID1, TEST_USER_ID,
+                numerOfUserSwitches, true);
+        // running: user 0, USER_ID1
+        // stopped + unlocked: USER_ID
+        numerOfUserSwitches++;
+        assertTrue(mUserController.canStartMoreUsers());
+        assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID1}),
+                mUserController.getRunningUsersLU());
+        // Skip all other steps and test unlock delaying only
+        UserState uss = mUserStates.get(TEST_USER_ID);
+        uss.setState(UserState.STATE_SHUTDOWN); // necessary state change from skipped part
+        mUserController.finishUserStopped(uss);
+        // Cannot mock FgThread handler, so confirm that there is no posted message left before
+        // checking.
+        waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS);
+        verify(mInjector.mStorageManagerMock, times(0))
+                .lockUserKey(anyInt());
+
+        addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_ID1,
+                numerOfUserSwitches, true);
+        // running: user 0, USER_ID2
+        // stopped + unlocked: USER_ID1
+        // stopped + locked: USER_ID
+        assertTrue(mUserController.canStartMoreUsers());
+        assertEquals(Arrays.asList(new Integer[] {0, TEST_USER_ID2}),
+                mUserController.getRunningUsersLU());
+        UserState ussUser1 = mUserStates.get(TEST_USER_ID1);
+        ussUser1.setState(UserState.STATE_SHUTDOWN);
+        mUserController.finishUserStopped(ussUser1);
+        waitForHandlerToComplete(FgThread.getHandler(), HANDLER_WAIT_TIME_MS);
+        verify(mInjector.mStorageManagerMock, times(1))
+                .lockUserKey(TEST_USER_ID);
+    }
+
+    private void addForegroundUserAndContinueUserSwitch(int newUserId, int expectedOldUserId,
+            int expectedNumberOfCalls, boolean expectOldUserStopping)
+            throws RemoteException {
+        // Start user -- this will update state of mUserController
+        mUserController.startUser(newUserId, true);
+        Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
+        assertNotNull(reportMsg);
+        UserState userState = (UserState) reportMsg.obj;
+        int oldUserId = reportMsg.arg1;
+        assertEquals(expectedOldUserId, oldUserId);
+        assertEquals(newUserId, reportMsg.arg2);
+        mUserStates.put(newUserId, userState);
+        mInjector.mHandler.clearAllRecordedMessages();
+        // Verify that continueUserSwitch worked as expected
+        mUserController.continueUserSwitch(userState, oldUserId, newUserId);
+        verify(mInjector.getWindowManager(), times(expectedNumberOfCalls))
+                .stopFreezingScreen();
+        continueUserSwitchAssertions(newUserId, expectOldUserStopping);
+    }
+
     private void setUpUser(int userId, int flags) {
         UserInfo userInfo = new UserInfo(userId, "User" + userId, flags);
         when(mInjector.mUserManagerMock.getUserInfo(eq(userId))).thenReturn(userInfo);
@@ -334,6 +482,22 @@
         return result;
     }
 
+    private void waitForHandlerToComplete(Handler handler, long waitTimeMs)
+            throws InterruptedException {
+        if (!handler.hasMessagesOrCallbacks()) { // if nothing queued, do not wait.
+            return;
+        }
+        final Object lock = new Object();
+        synchronized (lock) {
+            handler.post(() -> {
+                synchronized (lock) {
+                    lock.notify();
+                }
+            });
+            lock.wait(waitTimeMs);
+        }
+    }
+
     // Should be public to allow mocking
     private static class TestInjector extends UserController.Injector {
         public final TestHandler mHandler;
@@ -342,8 +506,11 @@
         public final List<Intent> mSentIntents = new ArrayList<>();
 
         private final TestHandler mUiHandler;
+
+        private final IStorageManager mStorageManagerMock;
         private final UserManagerInternal mUserManagerInternalMock;
         private final WindowManagerService mWindowManagerMock;
+
         private final Context mCtx;
 
         TestInjector(Context ctx) {
@@ -356,6 +523,7 @@
             mUserManagerMock = mock(UserManagerService.class);
             mUserManagerInternalMock = mock(UserManagerInternal.class);
             mWindowManagerMock = mock(WindowManagerService.class);
+            mStorageManagerMock = mock(IStorageManager.class);
         }
 
         @Override
@@ -417,6 +585,17 @@
         @Override
         void reportCurWakefulnessUsageEvent() {
         }
+
+        @Override
+        boolean isRuntimeRestarted() {
+            // to pass all metrics related calls
+            return true;
+        }
+
+        @Override
+        protected IStorageManager getStorageManager() {
+            return mStorageManagerMock;
+        }
     }
 
     private static class TestHandler extends Handler {
diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
index dd79aad..29cbf98 100644
--- a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
@@ -95,6 +95,7 @@
             new ComponentName("package2", "class2")
     };
     private static final int NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 1;
+    private static final int UNSTARTED_NON_USER_SYSTEM = UserHandle.USER_SYSTEM + 2;
 
     @UserIdInt
     private int mUserId;
@@ -126,8 +127,6 @@
     private TrampolineTestable mTrampoline;
     private File mTestDir;
     private File mSuppressFile;
-    private File mActivatedFile;
-    private File mRememberActivatedFile;
 
     @Before
     public void setUp() throws Exception {
@@ -141,6 +140,7 @@
 
         when(mUserManagerMock.getUserInfo(UserHandle.USER_SYSTEM)).thenReturn(mUserInfoMock);
         when(mUserManagerMock.getUserInfo(NON_USER_SYSTEM)).thenReturn(mUserInfoMock);
+        when(mUserManagerMock.getUserInfo(UNSTARTED_NON_USER_SYSTEM)).thenReturn(mUserInfoMock);
 
         TrampolineTestable.sBackupManagerServiceMock = mBackupManagerServiceMock;
         TrampolineTestable.sCallingUserId = UserHandle.USER_SYSTEM;
@@ -154,18 +154,31 @@
         mSuppressFile = new File(mTestDir, "suppress");
         TrampolineTestable.sSuppressFile = mSuppressFile;
 
-        mActivatedFile = new File(mTestDir, "activate-" + NON_USER_SYSTEM);
-        TrampolineTestable.sActivatedFiles.append(NON_USER_SYSTEM, mActivatedFile);
-        mRememberActivatedFile = new File(mTestDir, "rem-activate-" + NON_USER_SYSTEM);
-        TrampolineTestable.sRememberActivatedFiles.append(NON_USER_SYSTEM, mRememberActivatedFile);
+        setUpStateFilesForNonSystemUser(NON_USER_SYSTEM);
+        setUpStateFilesForNonSystemUser(UNSTARTED_NON_USER_SYSTEM);
 
         mTrampoline = new TrampolineTestable(mContextMock);
     }
 
+    private void setUpStateFilesForNonSystemUser(int userId) {
+        File activatedFile = new File(mTestDir, "activate-" + userId);
+        TrampolineTestable.sActivatedFiles.append(userId, activatedFile);
+        File rememberActivatedFile = new File(mTestDir, "rem-activate-" + userId);
+        TrampolineTestable.sRememberActivatedFiles.append(userId, rememberActivatedFile);
+    }
+
     @After
     public void tearDown() throws Exception {
         mSuppressFile.delete();
-        mActivatedFile.delete();
+        deleteFiles(TrampolineTestable.sActivatedFiles);
+        deleteFiles(TrampolineTestable.sRememberActivatedFiles);
+    }
+
+    private void deleteFiles(SparseArray<File> files) {
+        int numFiles = files.size();
+        for (int i = 0; i < numFiles; i++) {
+            files.valueAt(i).delete();
+        }
     }
 
     @Test
@@ -245,6 +258,16 @@
     }
 
     @Test
+    public void
+            isBackupServiceActive_forUnstartedNonSystemUser_returnsTrueWhenSystemAndUserActivated()
+            throws Exception {
+        mTrampoline.initializeService();
+        mTrampoline.setBackupServiceActive(UNSTARTED_NON_USER_SYSTEM, true);
+
+        assertTrue(mTrampoline.isBackupServiceActive(UNSTARTED_NON_USER_SYSTEM));
+    }
+
+    @Test
     public void setBackupServiceActive_forSystemUserAndCallerSystemUid_serviceCreated() {
         mTrampoline.initializeService();
         TrampolineTestable.sCallingUid = Process.SYSTEM_UID;
@@ -421,7 +444,8 @@
 
         mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true);
 
-        assertTrue(RandomAccessFileUtils.readBoolean(mRememberActivatedFile, false));
+        assertTrue(RandomAccessFileUtils.readBoolean(
+                TrampolineTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), false));
     }
 
     @Test
@@ -430,7 +454,8 @@
 
         mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, false);
 
-        assertFalse(RandomAccessFileUtils.readBoolean(mRememberActivatedFile, true));
+        assertFalse(RandomAccessFileUtils.readBoolean(
+                TrampolineTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), true));
     }
 
     @Test
@@ -440,7 +465,8 @@
         mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, true);
         mTrampoline.setBackupServiceActive(NON_USER_SYSTEM, false);
 
-        assertFalse(RandomAccessFileUtils.readBoolean(mRememberActivatedFile, true));
+        assertFalse(RandomAccessFileUtils.readBoolean(
+                TrampolineTestable.sRememberActivatedFiles.get(NON_USER_SYSTEM), true));
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java
index 4b3d9cf..0792414 100644
--- a/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java
+++ b/services/tests/servicestests/src/com/android/server/backup/testutils/IPackageManagerStub.java
@@ -1148,6 +1148,11 @@
         return null;
     }
 
+    @Override
+    public String getAttentionServicePackageName() throws RemoteException {
+        return null;
+    }
+
     public String getIncidentReportApproverPackageName() throws RemoteException {
         return null;
     }
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 bd7774a..cbabb0b 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -85,10 +85,11 @@
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
 import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
 import android.util.Pair;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.internal.R;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
@@ -99,7 +100,6 @@
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
 import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 import java.io.File;
@@ -241,29 +241,23 @@
         final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>();
 
         // UM.setApplicationRestrictions() will save to appRestrictions.
-        doAnswer(new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) throws Throwable {
-                String pkg = (String) invocation.getArguments()[0];
-                Bundle bundle = (Bundle) invocation.getArguments()[1];
-                UserHandle user = (UserHandle) invocation.getArguments()[2];
+        doAnswer((Answer<Void>) invocation -> {
+            String pkg = (String) invocation.getArguments()[0];
+            Bundle bundle = (Bundle) invocation.getArguments()[1];
+            UserHandle user = (UserHandle) invocation.getArguments()[2];
 
-                appRestrictions.put(Pair.create(pkg, user), bundle);
+            appRestrictions.put(Pair.create(pkg, user), bundle);
 
-                return null;
-            }
+            return null;
         }).when(getServices().userManager).setApplicationRestrictions(
                 anyString(), nullable(Bundle.class), any(UserHandle.class));
 
         // UM.getApplicationRestrictions() will read from appRestrictions.
-        doAnswer(new Answer<Bundle>() {
-            @Override
-            public Bundle answer(InvocationOnMock invocation) throws Throwable {
-                String pkg = (String) invocation.getArguments()[0];
-                UserHandle user = (UserHandle) invocation.getArguments()[1];
+        doAnswer((Answer<Bundle>) invocation -> {
+            String pkg = (String) invocation.getArguments()[0];
+            UserHandle user = (UserHandle) invocation.getArguments()[1];
 
-                return appRestrictions.get(Pair.create(pkg, user));
-            }
+            return appRestrictions.get(Pair.create(pkg, user));
         }).when(getServices().userManager).getApplicationRestrictions(
                 anyString(), any(UserHandle.class));
 
@@ -2242,11 +2236,13 @@
         intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
         assertNull(intent);
 
-        // Permission that is set by device owner returns correct intent
-        when(getServices().userManager.getUserRestrictionSource(
+        // UM.getUserRestrictionSources() will return a list of size 1 with the caller resource.
+        doAnswer((Answer<List<UserManager.EnforcingUser>>) invocation -> Collections.singletonList(
+                new UserManager.EnforcingUser(
+                        UserHandle.myUserId(), UserManager.RESTRICTION_SOURCE_DEVICE_OWNER))
+        ).when(getServices().userManager).getUserRestrictionSources(
                 eq(UserManager.DISALLOW_ADJUST_VOLUME),
-                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
-                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+                eq(UserHandle.getUserHandleForUid(UserHandle.myUserId())));
         intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
         assertNotNull(intent);
         assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction());
diff --git a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
index 2f427b0..de841a0 100644
--- a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
@@ -124,7 +124,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -133,7 +133,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -142,7 +142,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -151,7 +151,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -160,7 +160,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -169,7 +169,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -178,7 +178,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -187,7 +187,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -196,7 +196,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -205,7 +205,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -214,7 +214,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -223,7 +223,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -232,7 +232,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -241,7 +241,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -250,7 +250,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -259,7 +259,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -268,7 +268,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -277,7 +277,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -286,7 +286,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -295,7 +295,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -304,7 +304,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -313,7 +313,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -322,7 +322,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -331,7 +331,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -340,7 +340,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -349,7 +349,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -358,7 +358,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -367,7 +367,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -376,7 +376,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -385,7 +385,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -394,7 +394,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -403,7 +403,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -412,7 +412,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -421,7 +421,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -430,7 +430,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -439,7 +439,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -448,7 +448,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -457,7 +457,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -466,7 +466,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -475,7 +475,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -484,7 +484,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -493,7 +493,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -502,7 +502,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -511,7 +511,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -520,7 +520,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -529,7 +529,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -538,7 +538,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -547,7 +547,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -556,7 +556,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOffAfterNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -571,7 +571,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOffBeforeNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -586,7 +586,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOffDuringNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -601,7 +601,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOffInFuture_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -616,7 +616,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOnAfterNight_turnsOn() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -631,7 +631,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOnBeforeNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -646,7 +646,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOnDuringNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -661,7 +661,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOnInFuture_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -676,7 +676,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOffAfterNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -691,7 +691,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOffBeforeNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -706,7 +706,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOffDuringNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -721,7 +721,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOffInPast_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -736,7 +736,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOnAfterNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -751,7 +751,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOnBeforeNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -766,7 +766,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOnDuringNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -781,7 +781,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOnInPast_turnsOn() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -796,7 +796,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOffAfterNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -811,7 +811,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOffBeforeNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -826,7 +826,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInFuture_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -841,7 +841,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInPast_turnsOff() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -856,7 +856,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOnAfterNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -871,7 +871,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOnBeforeNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -886,7 +886,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInFuture_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -901,7 +901,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInPast_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -984,22 +984,19 @@
     }
 
     @Test
-    public void displayWhiteBalance_enable() {
-        setWhiteBalance(true /* Enable DWB Setting */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+    public void displayWhiteBalance_enabled() {
+        setDisplayWhiteBalanceEnabled(true);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
         mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
         startService();
         assertDwbActive(true);
     }
 
     @Test
-    public void displayWhiteBalance_disableAfterNightDisplayEnable() {
-        setWhiteBalance(true /* Enable DWB Setting */);
-
+    public void displayWhiteBalance_disabledAfterNightDisplayEnabled() {
+        setDisplayWhiteBalanceEnabled(true);
         startService();
-        /* Enable nightlight */
-        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         /* Since we are using FakeSettingsProvider which could not trigger observer change,
          * force an update here.*/
@@ -1008,26 +1005,23 @@
     }
 
     @Test
-    public void displayWhiteBalance_enableAfterNightDisplayDisable() {
-        setWhiteBalance(true /* Enable DWB Setting */);
+    public void displayWhiteBalance_enabledAfterNightDisplayDisabled() {
+        setDisplayWhiteBalanceEnabled(true);
         startService();
-        /* Enable nightlight */
-        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         mCds.updateDisplayWhiteBalanceStatus();
         assertDwbActive(false);
 
-        /* Disable nightlight */
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
         mCds.updateDisplayWhiteBalanceStatus();
         assertDwbActive(true);
     }
 
     @Test
-    public void displayWhiteBalance_enableAfterLinearColorMode() {
-        setWhiteBalance(true /* Enable DWB Setting */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+    public void displayWhiteBalance_enabledAfterLinearColorModeSelected() {
+        setDisplayWhiteBalanceEnabled(true);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
         startService();
         mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
 
@@ -1035,47 +1029,6 @@
         assertDwbActive(true);
     }
 
-    @Test
-    public void displayWhiteBalance_setTemperatureOverMax() {
-        int max = mCds.mDisplayWhiteBalanceTintController.mTemperatureMax;
-
-        ColorDisplayService.ColorDisplayServiceInternal cdsInternal = LocalServices.getService(
-                ColorDisplayService.ColorDisplayServiceInternal.class);
-        cdsInternal.setDisplayWhiteBalanceColorTemperature(max + 1);
-
-        assertWithMessage("Unexpected temperature set")
-                .that(mCds.mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
-                .isEqualTo(max);
-    }
-
-    @Test
-    public void displayWhiteBalance_setTemperatureBelowMin() {
-        int min = mCds.mDisplayWhiteBalanceTintController.mTemperatureMin;
-
-        ColorDisplayService.ColorDisplayServiceInternal cdsInternal = LocalServices.getService(
-                ColorDisplayService.ColorDisplayServiceInternal.class);
-        cdsInternal.setDisplayWhiteBalanceColorTemperature(min - 1);
-
-        assertWithMessage("Unexpected temperature set")
-                .that(mCds.mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
-                .isEqualTo(min);
-    }
-
-    @Test
-    public void displayWhiteBalance_setValidTemperature() {
-        int min = mCds.mDisplayWhiteBalanceTintController.mTemperatureMin;
-        int max = mCds.mDisplayWhiteBalanceTintController.mTemperatureMax;
-        int valToSet = (min + max) / 2;
-
-        ColorDisplayService.ColorDisplayServiceInternal cdsInternal = LocalServices.getService(
-                ColorDisplayService.ColorDisplayServiceInternal.class);
-        cdsInternal.setDisplayWhiteBalanceColorTemperature(valToSet);
-
-        assertWithMessage("Unexpected temperature set")
-                .that(mCds.mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
-                .isEqualTo(valToSet);
-    }
-
     /**
      * Configures Night display to use a custom schedule.
      *
@@ -1109,7 +1062,7 @@
      * @param lastActivatedTimeOffset the offset relative to now to record that Night display was
      * activated (in minutes)
      */
-    private void setActivated(boolean activated, int lastActivatedTimeOffset) {
+    private void setNightDisplayActivated(boolean activated, int lastActivatedTimeOffset) {
         mBinderService.setNightDisplayActivated(activated);
         Secure.putStringForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
@@ -1140,11 +1093,11 @@
     /**
      * Configures the Display White Balance setting state.
      *
-     * @param state {@code true} if display white balance should be enabled
+     * @param enabled {@code true} if display white balance should be enabled
      */
-    private void setWhiteBalance(boolean state) {
+    private void setDisplayWhiteBalanceEnabled(boolean enabled) {
         Secure.putIntForUser(mContext.getContentResolver(),
-                Secure.DISPLAY_WHITE_BALANCE_ENABLED, state ? 1 : 0, mUserId);
+                Secure.DISPLAY_WHITE_BALANCE_ENABLED, enabled ? 1 : 0, mUserId);
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java b/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
new file mode 100644
index 0000000..1dd4e15
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.color;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class DisplayWhiteBalanceTintControllerTest {
+
+    private DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController;
+
+    @Before
+    public void setUp() {
+        mDisplayWhiteBalanceTintController = new DisplayWhiteBalanceTintController();
+    }
+
+    @Test
+    public void displayWhiteBalance_setTemperatureOverMax() {
+        final int max = mDisplayWhiteBalanceTintController.mTemperatureMax;
+        mDisplayWhiteBalanceTintController.setMatrix(max + 1);
+        assertWithMessage("Unexpected temperature set")
+                .that(mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
+                .isEqualTo(max);
+    }
+
+    @Test
+    public void displayWhiteBalance_setTemperatureBelowMin() {
+        final int min = mDisplayWhiteBalanceTintController.mTemperatureMin;
+        mDisplayWhiteBalanceTintController.setMatrix(min - 1);
+        assertWithMessage("Unexpected temperature set")
+                .that(mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
+                .isEqualTo(min);
+    }
+
+    @Test
+    public void displayWhiteBalance_setValidTemperature() {
+        final int colorTemperature = (mDisplayWhiteBalanceTintController.mTemperatureMin
+                + mDisplayWhiteBalanceTintController.mTemperatureMax) / 2;
+        mDisplayWhiteBalanceTintController.setMatrix(colorTemperature);
+
+        assertWithMessage("Unexpected temperature set")
+                .that(mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
+                .isEqualTo(colorTemperature);
+    }
+
+}
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 78751a1..3a0f4c2 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -31,7 +31,6 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.util.HexDump;
-import com.android.server.IoThread;
 import com.android.server.LocalServices;
 import com.android.server.job.JobStore.JobSet;
 import com.android.server.job.controllers.JobStatus;
@@ -45,8 +44,6 @@
 import java.time.ZoneOffset;
 import java.util.Arrays;
 import java.util.Iterator;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Test reading and writing correctly from file.
@@ -96,14 +93,12 @@
     @After
     public void tearDown() throws Exception {
         mTaskStoreUnderTest.clear();
+        mTaskStoreUnderTest.waitForWriteToCompleteForTesting(5_000L);
     }
 
     private void waitForPendingIo() throws Exception {
-        final CountDownLatch latch = new CountDownLatch(1);
-        IoThread.getHandler().post(() -> {
-            latch.countDown();
-        });
-        latch.await(10, TimeUnit.SECONDS);
+        assertTrue("Timed out waiting for persistence I/O to complete",
+                mTaskStoreUnderTest.waitForWriteToCompleteForTesting(5_000L));
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index 3d02576..09e20e0 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -46,6 +46,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.LockSettingsInternal;
 import com.android.server.LocalServices;
+import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
 import com.android.server.wm.WindowManagerInternal;
 
 import org.mockito.invocation.InvocationOnMock;
@@ -56,7 +57,7 @@
 import java.util.Arrays;
 
 
-public class BaseLockSettingsServiceTests extends AndroidTestCase {
+public abstract class BaseLockSettingsServiceTests extends AndroidTestCase {
     protected static final int PRIMARY_USER_ID = 0;
     protected static final int MANAGED_PROFILE_USER_ID = 12;
     protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
@@ -89,6 +90,7 @@
     WindowManagerInternal mMockWindowManager;
     FakeGsiService mGsiService;
     PasswordSlotManagerTestable mPasswordSlotManager;
+    RecoverableKeyStoreManager mRecoverableKeyStoreManager;
     protected boolean mHasSecureLockScreen;
 
     @Override
@@ -105,6 +107,7 @@
         mMockWindowManager = mock(WindowManagerInternal.class);
         mGsiService = new FakeGsiService();
         mPasswordSlotManager = new PasswordSlotManagerTestable();
+        mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class);
 
         LocalServices.removeServiceForTest(LockSettingsInternal.class);
         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
@@ -141,12 +144,14 @@
         mAuthSecretService = mock(IAuthSecret.class);
         mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils, mStorage,
                 mGateKeeperService, mKeyStore, setUpStorageManagerMock(), mActivityManager,
-                mSpManager, mAuthSecretService, mGsiService);
+                mSpManager, mAuthSecretService, mGsiService, mRecoverableKeyStoreManager);
         when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
         mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
         installChildProfile(MANAGED_PROFILE_USER_ID);
         installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
-        when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
+        for (UserInfo profile : mPrimaryUserProfiles) {
+            when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles);
+        }
         when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
 
         final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
@@ -173,6 +178,7 @@
     private UserInfo installChildProfile(int profileId) {
         final UserInfo userInfo = new UserInfo(
             profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
+        userInfo.profileGroupId = PRIMARY_USER_ID;
         mPrimaryUserProfiles.add(userInfo);
         when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
         when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java
index ca4330f..d2a9145 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java
@@ -26,6 +26,9 @@
 import static org.mockito.Mockito.when;
 
 import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.VerifyCredentialResponse;
@@ -40,6 +43,8 @@
  * By default, those tests run without caching. Untrusted credential reset depends on caching so
  * this class included those tests.
  */
+@SmallTest
+@Presubmit
 public class CachedSyntheticPasswordTests extends SyntheticPasswordTests {
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index f4632db..10fb3ba 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -30,6 +30,7 @@
 import android.security.keystore.KeyPermanentlyInvalidatedException;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
 
 import java.io.FileNotFoundException;
 
@@ -45,11 +46,13 @@
         private SyntheticPasswordManager mSpManager;
         private IAuthSecret mAuthSecretService;
         private FakeGsiService mGsiService;
+        private RecoverableKeyStoreManager mRecoverableKeyStoreManager;
 
         public MockInjector(Context context, LockSettingsStorage storage, KeyStore keyStore,
                 IActivityManager activityManager, LockPatternUtils lockPatternUtils,
                 IStorageManager storageManager, SyntheticPasswordManager spManager,
-                IAuthSecret authSecretService, FakeGsiService gsiService) {
+                IAuthSecret authSecretService, FakeGsiService gsiService,
+                RecoverableKeyStoreManager recoverableKeyStoreManager) {
             super(context);
             mLockSettingsStorage = storage;
             mKeyStore = keyStore;
@@ -58,6 +61,7 @@
             mStorageManager = storageManager;
             mSpManager = spManager;
             mGsiService = gsiService;
+            mRecoverableKeyStoreManager = recoverableKeyStoreManager;
         }
 
         @Override
@@ -119,15 +123,21 @@
         public boolean isGsiRunning() {
             return mGsiService.isGsiRunning();
         }
+
+        @Override
+        public RecoverableKeyStoreManager getRecoverableKeyStoreManager(KeyStore keyStore) {
+            return mRecoverableKeyStoreManager;
+        }
     }
 
     protected LockSettingsServiceTestable(Context context, LockPatternUtils lockPatternUtils,
             LockSettingsStorage storage, FakeGateKeeperService gatekeeper, KeyStore keystore,
             IStorageManager storageManager, IActivityManager mActivityManager,
             SyntheticPasswordManager spManager, IAuthSecret authSecretService,
-            FakeGsiService gsiService) {
+            FakeGsiService gsiService, RecoverableKeyStoreManager recoverableKeyStoreManager) {
         super(new MockInjector(context, storage, keystore, mActivityManager, lockPatternUtils,
-                storageManager, spManager, authSecretService, gsiService));
+                storageManager, spManager, authSecretService, gsiService,
+                recoverableKeyStoreManager));
         mGateKeeperService = gatekeeper;
         mAuthSecretService = authSecretService;
     }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 255e694b..67d6eda 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -25,9 +25,19 @@
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+
 import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
 import android.service.gatekeeper.GateKeeperResponse;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.VerifyCredentialResponse;
 import com.android.server.locksettings.FakeGateKeeperService.VerifyHandle;
@@ -36,6 +46,8 @@
 /**
  * runtest frameworks-services -c com.android.server.locksettings.LockSettingsServiceTests
  */
+@SmallTest
+@Presubmit
 public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
 
     @Override
@@ -206,6 +218,222 @@
         assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
     }
 
+    public void testSetLockCredential_forPrimaryUser_sendsCredentials() throws Exception {
+        final byte[] password = "password".getBytes();
+
+        mService.setLockCredential(
+                password,
+                CREDENTIAL_TYPE_PASSWORD,
+                null,
+                PASSWORD_QUALITY_ALPHABETIC,
+                PRIMARY_USER_ID,
+                false);
+
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretChanged(CREDENTIAL_TYPE_PASSWORD, password, PRIMARY_USER_ID);
+    }
+
+    public void testSetLockCredential_forProfileWithSeparateChallenge_sendsCredentials()
+            throws Exception {
+        final byte[] pattern = "12345".getBytes();
+
+        mService.setLockCredential(
+                pattern,
+                CREDENTIAL_TYPE_PATTERN,
+                null,
+                PASSWORD_QUALITY_SOMETHING,
+                MANAGED_PROFILE_USER_ID,
+                false);
+
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretChanged(CREDENTIAL_TYPE_PATTERN, pattern, MANAGED_PROFILE_USER_ID);
+    }
+
+    public void testSetLockCredential_forProfileWithSeparateChallenge_updatesCredentials()
+            throws Exception {
+        final String oldCredential = "12345";
+        final byte[] newCredential = "newPassword".getBytes();
+        initializeStorageWithCredential(
+                MANAGED_PROFILE_USER_ID,
+                oldCredential,
+                CREDENTIAL_TYPE_PATTERN,
+                PASSWORD_QUALITY_SOMETHING);
+
+        mService.setLockCredential(
+                newCredential,
+                CREDENTIAL_TYPE_PASSWORD,
+                oldCredential.getBytes(),
+                PASSWORD_QUALITY_ALPHABETIC,
+                MANAGED_PROFILE_USER_ID,
+                false);
+
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretChanged(
+                        CREDENTIAL_TYPE_PASSWORD, newCredential, MANAGED_PROFILE_USER_ID);
+    }
+
+    public void testSetLockCredential_forProfileWithUnifiedChallenge_doesNotSendRandomCredential()
+            throws Exception {
+        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+
+        mService.setLockCredential(
+                "12345".getBytes(),
+                CREDENTIAL_TYPE_PATTERN,
+                null,
+                PASSWORD_QUALITY_SOMETHING,
+                PRIMARY_USER_ID,
+                false);
+
+        verify(mRecoverableKeyStoreManager, never())
+                .lockScreenSecretChanged(
+                        eq(CREDENTIAL_TYPE_PASSWORD), any(), eq(MANAGED_PROFILE_USER_ID));
+    }
+
+    public void
+            testSetLockCredential_forPrimaryUserWithUnifiedChallengeProfile_updatesBothCredentials()
+                    throws Exception {
+        final String oldCredential = "oldPassword";
+        final byte[] newCredential = "newPassword".getBytes();
+        initializeStorageWithCredential(
+                PRIMARY_USER_ID, oldCredential, CREDENTIAL_TYPE_PASSWORD, 1234);
+        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+
+        mService.setLockCredential(
+                newCredential,
+                CREDENTIAL_TYPE_PASSWORD,
+                oldCredential.getBytes(),
+                PASSWORD_QUALITY_ALPHABETIC,
+                PRIMARY_USER_ID,
+                false);
+
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretChanged(CREDENTIAL_TYPE_PASSWORD, newCredential, PRIMARY_USER_ID);
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretChanged(
+                        CREDENTIAL_TYPE_PASSWORD, newCredential, MANAGED_PROFILE_USER_ID);
+    }
+
+    public void
+            testSetLockCredential_forPrimaryUserWithUnifiedChallengeProfile_removesBothCredentials()
+                    throws Exception {
+        final String oldCredential = "oldPassword";
+        initializeStorageWithCredential(
+                PRIMARY_USER_ID, oldCredential, CREDENTIAL_TYPE_PASSWORD, 1234);
+        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+
+        mService.setLockCredential(
+                null,
+                CREDENTIAL_TYPE_NONE,
+                oldCredential.getBytes(),
+                PASSWORD_QUALITY_UNSPECIFIED,
+                PRIMARY_USER_ID,
+                false);
+
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretChanged(CREDENTIAL_TYPE_NONE, null, PRIMARY_USER_ID);
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretChanged(CREDENTIAL_TYPE_NONE, null, MANAGED_PROFILE_USER_ID);
+    }
+
+    public void testSetLockCredential_forUnifiedToSeparateChallengeProfile_sendsNewCredentials()
+            throws Exception {
+        final String parentPassword = "parentPassword";
+        final byte[] profilePassword = "profilePassword".getBytes();
+        initializeStorageWithCredential(
+                PRIMARY_USER_ID, parentPassword, CREDENTIAL_TYPE_PASSWORD, 1234);
+        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+
+        mService.setLockCredential(
+                profilePassword,
+                CREDENTIAL_TYPE_PASSWORD,
+                null,
+                PASSWORD_QUALITY_ALPHABETIC,
+                MANAGED_PROFILE_USER_ID,
+                false);
+
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretChanged(
+                        CREDENTIAL_TYPE_PASSWORD, profilePassword, MANAGED_PROFILE_USER_ID);
+    }
+
+    public void
+            testSetLockCredential_forSeparateToUnifiedChallengeProfile_doesNotSendRandomCredential()
+                    throws Exception {
+        final String parentPassword = "parentPassword";
+        final String profilePassword = "12345";
+        initializeStorageWithCredential(
+                PRIMARY_USER_ID, parentPassword, CREDENTIAL_TYPE_PASSWORD, 1234);
+        // Create and verify separate profile credentials.
+        testCreateCredential(
+                MANAGED_PROFILE_USER_ID,
+                profilePassword,
+                CREDENTIAL_TYPE_PATTERN,
+                PASSWORD_QUALITY_SOMETHING);
+
+        mService.setSeparateProfileChallengeEnabled(
+                MANAGED_PROFILE_USER_ID, false, profilePassword.getBytes());
+
+        // Called once for setting the initial separate profile credentials and not again during
+        // unification.
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretChanged(anyInt(), any(), eq(MANAGED_PROFILE_USER_ID));
+    }
+
+    public void testVerifyCredential_forPrimaryUser_sendsCredentials() throws Exception {
+        final String password = "password";
+        initializeStorageWithCredential(PRIMARY_USER_ID, password, CREDENTIAL_TYPE_PASSWORD, 1234);
+        reset(mRecoverableKeyStoreManager);
+
+        mService.verifyCredential(
+                password.getBytes(), CREDENTIAL_TYPE_PASSWORD, 1, PRIMARY_USER_ID);
+
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretAvailable(
+                        CREDENTIAL_TYPE_PASSWORD, password.getBytes(), PRIMARY_USER_ID);
+    }
+
+    public void testVerifyCredential_forProfileWithSeparateChallenge_sendsCredentials()
+            throws Exception {
+        final byte[] pattern = "12345".getBytes();
+        mService.setLockCredential(
+                pattern,
+                CREDENTIAL_TYPE_PATTERN,
+                null,
+                PASSWORD_QUALITY_SOMETHING,
+                MANAGED_PROFILE_USER_ID,
+                false);
+        reset(mRecoverableKeyStoreManager);
+
+        mService.verifyCredential(pattern, CREDENTIAL_TYPE_PATTERN, 1, MANAGED_PROFILE_USER_ID);
+
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretAvailable(
+                        CREDENTIAL_TYPE_PATTERN, pattern, MANAGED_PROFILE_USER_ID);
+    }
+
+    public void
+            testVerifyCredential_forPrimaryUserWithUnifiedChallengeProfile_sendsCredentialsForBoth()
+                    throws Exception {
+        final String pattern = "12345";
+        initializeStorageWithCredential(PRIMARY_USER_ID, pattern, CREDENTIAL_TYPE_PATTERN, 1234);
+        mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+        reset(mRecoverableKeyStoreManager);
+
+        mService.verifyCredential(pattern.getBytes(), CREDENTIAL_TYPE_PATTERN, 1, PRIMARY_USER_ID);
+
+        // Parent sends its credentials for both the parent and profile.
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretAvailable(
+                        CREDENTIAL_TYPE_PATTERN, pattern.getBytes(), PRIMARY_USER_ID);
+        verify(mRecoverableKeyStoreManager)
+                .lockScreenSecretAvailable(
+                        CREDENTIAL_TYPE_PATTERN, pattern.getBytes(), MANAGED_PROFILE_USER_ID);
+        // Profile doesn't send its own random credentials.
+        verify(mRecoverableKeyStoreManager, never())
+                .lockScreenSecretAvailable(
+                        eq(CREDENTIAL_TYPE_PASSWORD), any(), eq(MANAGED_PROFILE_USER_ID));
+    }
+
     private void testCreateCredential(int userId, String credential, int type, int quality)
             throws RemoteException {
         mService.setLockCredential(credential.getBytes(), type, null, quality,
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
index fcfc6d2..c00d33b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsShellCommandTest.java
@@ -21,7 +21,7 @@
 
 import static com.android.internal.widget.LockPatternUtils.stringToPattern;
 
-import static junit.framework.Assert.*;
+import static junit.framework.Assert.assertEquals;
 
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.any;
@@ -30,6 +30,10 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import static java.io.FileDescriptor.err;
+import static java.io.FileDescriptor.in;
+import static java.io.FileDescriptor.out;
+
 import android.app.ActivityManager;
 import android.content.Context;
 import android.os.Binder;
@@ -51,8 +55,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import static java.io.FileDescriptor.*;
-
 /**
  * Test class for {@link LockSettingsShellCommand}.
  *
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
index 6e1f357..8af4edd 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -29,11 +29,14 @@
 import android.os.FileUtils;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 import android.util.Log;
 import android.util.Log.TerribleFailure;
 import android.util.Log.TerribleFailureHandler;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.PersistentDataBlockManagerInternal;
 import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
@@ -48,6 +51,8 @@
 /**
  * runtest frameworks-services -c com.android.server.locksettings.LockSettingsStorageTests
  */
+@SmallTest
+@Presubmit
 public class LockSettingsStorageTests extends AndroidTestCase {
     private static final int SOME_USER_ID = 1034;
     private final byte[] PASSWORD_0 = "thepassword0".getBytes();
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/PasswordSlotManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/PasswordSlotManagerTests.java
index 1d5a99b..31526b5 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/PasswordSlotManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/PasswordSlotManagerTests.java
@@ -16,8 +16,11 @@
 
 package com.android.server.locksettings;
 
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 
+import androidx.test.filters.SmallTest;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.util.HashMap;
@@ -25,6 +28,8 @@
 import java.util.Map;
 import java.util.Set;
 
+@SmallTest
+@Presubmit
 public class PasswordSlotManagerTests extends AndroidTestCase {
 
     PasswordSlotManagerTestable mManager;
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SP800DeriveTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SP800DeriveTests.java
index fc2dcb9..29d0fc1 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SP800DeriveTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SP800DeriveTests.java
@@ -16,10 +16,15 @@
 
 package com.android.server.locksettings;
 
+import android.platform.test.annotations.Presubmit;
 import android.test.AndroidTestCase;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.internal.util.HexDump;
 
+@SmallTest
+@Presubmit
 public class SP800DeriveTests extends AndroidTestCase {
     public void testFixedInput() throws Exception {
         // CAVP: https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/key-derivation
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 5a9ca0f..0273f76 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -33,6 +33,9 @@
 import android.app.admin.PasswordMetrics;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.VerifyCredentialResponse;
@@ -48,6 +51,8 @@
 /**
  * runtest frameworks-services -c com.android.server.locksettings.SyntheticPasswordTests
  */
+@SmallTest
+@Presubmit
 public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
 
     public static final byte[] PAYLOAD = new byte[] {1, 2, -1, -2, 55};
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
index 5e56704..abbf016 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/WeaverBasedSyntheticPasswordTests.java
@@ -1,5 +1,11 @@
 package com.android.server.locksettings;
 
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+@SmallTest
+@Presubmit
 public class WeaverBasedSyntheticPasswordTests extends SyntheticPasswordTests {
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
index 5bab65c..6890017 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
@@ -58,6 +58,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.widget.LockPatternUtils;
 import com.android.server.locksettings.recoverablekeystore.storage.ApplicationKeyStorage;
 import com.android.server.locksettings.recoverablekeystore.storage.CleanupManager;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
@@ -83,7 +84,7 @@
 import java.util.ArrayList;
 import java.util.Map;
 import java.util.Random;
-import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
 
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
@@ -156,6 +157,7 @@
     @Mock private PlatformKeyManager mPlatformKeyManager;
     @Mock private ApplicationKeyStorage mApplicationKeyStorage;
     @Mock private CleanupManager mCleanupManager;
+    @Mock private ExecutorService mExecutorService;
     @Spy private TestOnlyInsecureCertificateHelper mTestOnlyInsecureCertificateHelper;
 
     private RecoverableKeyStoreDb mRecoverableKeyStoreDb;
@@ -188,7 +190,7 @@
                 mMockContext,
                 mRecoverableKeyStoreDb,
                 mRecoverySessionStorage,
-                Executors.newSingleThreadExecutor(),
+                mExecutorService,
                 mRecoverySnapshotStorage,
                 mMockListenersStorage,
                 mPlatformKeyManager,
@@ -1246,6 +1248,24 @@
         }
     }
 
+    @Test
+    public void lockScreenSecretAvailable_syncsKeysForUser() throws Exception {
+        mRecoverableKeyStoreManager.lockScreenSecretAvailable(
+                LockPatternUtils.CREDENTIAL_TYPE_PATTERN, "password".getBytes(), 11);
+
+        verify(mExecutorService).execute(any());
+    }
+
+    @Test
+    public void lockScreenSecretChanged_syncsKeysForUser() throws Exception {
+        mRecoverableKeyStoreManager.lockScreenSecretChanged(
+                LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
+                "password".getBytes(),
+                11);
+
+        verify(mExecutorService).execute(any());
+    }
+
     private static byte[] encryptedApplicationKey(
             SecretKey recoveryKey, byte[] applicationKey) throws Exception {
         return KeySyncUtils.encryptKeysWithRecoveryKey(recoveryKey, ImmutableMap.of(
diff --git a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
index 26853a9..3f687c8 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
@@ -88,19 +88,13 @@
     }
 
     @Override
-    public void uninstallAndDisablePackageForAllUsers(Context context, String packageName) {
-        enablePackageForAllUsers(context, packageName, false);
-    }
-
-    @Override
     public void enablePackageForAllUsers(Context context, String packageName, boolean enable) {
         for(int userId : mUsers) {
             enablePackageForUser(packageName, enable, userId);
         }
     }
 
-    @Override
-    public void enablePackageForUser(String packageName, boolean enable, int userId) {
+    private void enablePackageForUser(String packageName, boolean enable, int userId) {
         Map<Integer, PackageInfo> userPackages = mPackages.get(packageName);
         if (userPackages == null) {
             throw new IllegalArgumentException("There is no package called " + packageName);
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index bf89cd0..2e60866 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -41,7 +41,6 @@
 import org.mockito.Matchers;
 import org.mockito.Mockito;
 
-import java.lang.Integer;
 import java.util.concurrent.CountDownLatch;
 
 /**
@@ -68,27 +67,32 @@
     }
 
     private void setupWithPackages(WebViewProviderInfo[] packages) {
-        setupWithPackages(packages, true);
+        setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */,
+                true /* isDebuggable */, false /* multiProcessDefault */);
     }
 
-    private void setupWithPackages(WebViewProviderInfo[] packages,
-            boolean fallbackLogicEnabled) {
-        setupWithPackages(packages, fallbackLogicEnabled, 1);
+    private void setupWithPackagesAndFallbackLogic(WebViewProviderInfo[] packages) {
+        setupWithAllParameters(packages, true /* fallbackLogicEnabled */, 1 /* numRelros */,
+                true /* isDebuggable */, false /* multiProcessDefault */);
     }
 
-    private void setupWithPackages(WebViewProviderInfo[] packages,
-            boolean fallbackLogicEnabled, int numRelros) {
-        setupWithPackages(packages, fallbackLogicEnabled, numRelros,
-                true /* isDebuggable == true -> don't check package signatures */);
+    private void setupWithPackagesAndRelroCount(WebViewProviderInfo[] packages, int numRelros) {
+        setupWithAllParameters(packages, false /* fallbackLogicEnabled */, numRelros,
+                true /* isDebuggable */, false /* multiProcessDefault */);
     }
 
-    private void setupWithPackages(WebViewProviderInfo[] packages,
-            boolean fallbackLogicEnabled, int numRelros, boolean isDebuggable) {
-        setupWithPackages(packages, fallbackLogicEnabled, numRelros, isDebuggable,
-                false /* multiProcessDefault */);
+    private void setupWithPackagesNonDebuggable(WebViewProviderInfo[] packages) {
+        setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */,
+                false /* isDebuggable */, false /* multiProcessDefault */);
     }
 
-    private void setupWithPackages(WebViewProviderInfo[] packages,
+    private void setupWithPackagesAndMultiProcess(WebViewProviderInfo[] packages,
+            boolean multiProcessDefault) {
+        setupWithAllParameters(packages, false /* fallbackLogicEnabled */, 1 /* numRelros */,
+                true /* isDebuggable */, multiProcessDefault);
+    }
+
+    private void setupWithAllParameters(WebViewProviderInfo[] packages,
             boolean fallbackLogicEnabled, int numRelros, boolean isDebuggable,
             boolean multiProcessDefault) {
         TestSystemImpl testing = new TestSystemImpl(packages, fallbackLogicEnabled, numRelros,
@@ -119,7 +123,7 @@
 
     private void checkCertainPackageUsedAfterWebViewBootPreparation(String expectedProviderName,
             WebViewProviderInfo[] webviewPackages, int numRelros) {
-        setupWithPackages(webviewPackages, true, numRelros);
+        setupWithPackagesAndRelroCount(webviewPackages, numRelros);
         // Add (enabled and valid) package infos for each provider
         setEnabledAndValidPackageInfos(webviewPackages);
 
@@ -289,8 +293,7 @@
                         Base64.encodeToString(
                                 validSignature.toByteArray(), Base64.DEFAULT)})
         };
-        setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
-                false /* isDebuggable */);
+        setupWithPackagesNonDebuggable(packages);
         mTestSystemImpl.setPackageInfo(createPackageInfo(invalidPackage, true /* enabled */,
                     true /* valid */, true /* installed */, new Signature[]{invalidPackageSignature}
                     , 0 /* updateTime */));
@@ -510,82 +513,75 @@
         }
     }
 
+    /**
+     * Scenario for testing migrating away from the fallback logic.
+     * We start with a primary package that's a disabled fallback, and an enabled secondary,
+     * so that the fallback being re-enabled will cause a provider switch, as that covers
+     * the most complex case.
+     */
     @Test
-    public void testRunFallbackLogicIfEnabled() {
-        checkFallbackLogicBeingRun(true);
-    }
-
-    @Test
-    public void testDontRunFallbackLogicIfDisabled() {
-        checkFallbackLogicBeingRun(false);
-    }
-
-    private void checkFallbackLogicBeingRun(boolean fallbackLogicEnabled) {
+    public void testFallbackLogicMigration() {
         String primaryPackage = "primary";
-        String fallbackPackage = "fallback";
+        String secondaryPackage = "secondary";
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo(
-                    primaryPackage, "", true /* default available */, false /* fallback */, null),
+                    primaryPackage, "", true /* default available */, true /* fallback */, null),
             new WebViewProviderInfo(
-                    fallbackPackage, "", true /* default available */, true /* fallback */, null)};
-        setupWithPackages(packages, fallbackLogicEnabled);
-        setEnabledAndValidPackageInfos(packages);
+                    secondaryPackage, "", true /* default available */, false /* fallback */,
+                    null)};
+        setupWithPackagesAndFallbackLogic(packages);
+        mTestSystemImpl.setPackageInfo(
+                createPackageInfo(primaryPackage, false /* enabled */ , true /* valid */,
+                    true /* installed */));
+        mTestSystemImpl.setPackageInfo(
+                createPackageInfo(secondaryPackage, true /* enabled */ , true /* valid */,
+                    true /* installed */));
 
+        // Check that the boot time logic re-enables and chooses the primary, and disables the
+        // fallback logic.
         runWebViewBootPreparationOnMainSync();
-        // Verify that we disable the fallback package if fallback logic enabled, and don't disable
-        // the fallback package if that logic is disabled
-        if (fallbackLogicEnabled) {
-            Mockito.verify(mTestSystemImpl).uninstallAndDisablePackageForAllUsers(
-                    Matchers.anyObject(), Mockito.eq(fallbackPackage));
-        } else {
-            Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
-                    Matchers.anyObject(), Matchers.anyObject());
-        }
-        Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
-                Mockito.argThat(new IsPackageInfoWithName(primaryPackage)));
+        Mockito.verify(mTestSystemImpl).enablePackageForAllUsers(
+                Matchers.anyObject(), Mockito.eq(primaryPackage), Mockito.eq(true));
+        checkPreparationPhasesForPackage(primaryPackage, 1);
+        assertFalse(mTestSystemImpl.isFallbackLogicEnabled());
 
-        // Enable fallback package
-        mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
+        // Disable primary again
+        mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, false /* enabled */,
                         true /* valid */, true /* installed */));
-        mWebViewUpdateServiceImpl.packageStateChanged(
-                fallbackPackage, WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
+        mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
+                WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
+        checkPreparationPhasesForPackage(secondaryPackage, 1);
 
-        if (fallbackLogicEnabled) {
-            // Check that we have now disabled the fallback package twice
-            Mockito.verify(mTestSystemImpl, Mockito.times(2)).uninstallAndDisablePackageForAllUsers(
-                    Matchers.anyObject(), Mockito.eq(fallbackPackage));
-        } else {
-            // Check that we still haven't disabled any package
-            Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
-                    Matchers.anyObject(), Matchers.anyObject());
-        }
+        // Run boot logic again and check that we didn't re-enable the primary a second time.
+        runWebViewBootPreparationOnMainSync();
+        Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForAllUsers(
+                Matchers.anyObject(), Mockito.eq(primaryPackage), Mockito.eq(true));
+        checkPreparationPhasesForPackage(secondaryPackage, 2);
     }
 
     /**
-     * Scenario for installing primary package when fallback enabled.
-     * 1. Start with only fallback installed
-     * 2. Install non-fallback
-     * 3. Fallback should be disabled
+     * Scenario for installing primary package when secondary in use.
+     * 1. Start with only secondary installed
+     * 2. Install primary
+     * 3. Primary should be used
      */
     @Test
-    public void testInstallingNonFallbackPackage() {
+    public void testInstallingPrimaryPackage() {
         String primaryPackage = "primary";
-        String fallbackPackage = "fallback";
+        String secondaryPackage = "secondary";
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo(
                     primaryPackage, "", true /* default available */, false /* fallback */, null),
             new WebViewProviderInfo(
-                    fallbackPackage, "", true /* default available */, true /* fallback */, null)};
-        setupWithPackages(packages, true /* isFallbackLogicEnabled */);
+                    secondaryPackage, "", true /* default available */, false /* fallback */,
+                    null)};
+        setupWithPackages(packages);
         mTestSystemImpl.setPackageInfo(
-                createPackageInfo(fallbackPackage, true /* enabled */ , true /* valid */,
+                createPackageInfo(secondaryPackage, true /* enabled */ , true /* valid */,
                     true /* installed */));
 
         runWebViewBootPreparationOnMainSync();
-        Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
-                Matchers.anyObject(), Matchers.anyObject());
-
-        checkPreparationPhasesForPackage(fallbackPackage,
+        checkPreparationPhasesForPackage(secondaryPackage,
                 1 /* first preparation for this package*/);
 
         // Install primary package
@@ -595,24 +591,22 @@
         mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
                 WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
 
-        // Verify fallback disabled, primary package used as provider, and fallback package killed
-        Mockito.verify(mTestSystemImpl).uninstallAndDisablePackageForAllUsers(
-                Matchers.anyObject(), Mockito.eq(fallbackPackage));
+        // Verify primary package used as provider, and secondary package killed
         checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation for this package*/);
-        Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(fallbackPackage));
+        Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(secondaryPackage));
     }
 
     @Test
-    public void testFallbackChangesEnabledStateSingleUser() {
+    public void testRemovingPrimarySelectsSecondarySingleUser() {
         for (PackageRemovalType removalType : REMOVAL_TYPES) {
-            checkFallbackChangesEnabledState(false /* multiUser */, removalType);
+            checkRemovingPrimarySelectsSecondary(false /* multiUser */, removalType);
         }
     }
 
     @Test
-    public void testFallbackChangesEnabledStateMultiUser() {
+    public void testRemovingPrimarySelectsSecondaryMultiUser() {
         for (PackageRemovalType removalType : REMOVAL_TYPES) {
-            checkFallbackChangesEnabledState(true /* multiUser */, removalType);
+            checkRemovingPrimarySelectsSecondary(true /* multiUser */, removalType);
         }
     }
 
@@ -626,16 +620,17 @@
 
     private PackageRemovalType[] REMOVAL_TYPES = PackageRemovalType.class.getEnumConstants();
 
-    public void checkFallbackChangesEnabledState(boolean multiUser,
+    public void checkRemovingPrimarySelectsSecondary(boolean multiUser,
             PackageRemovalType removalType) {
         String primaryPackage = "primary";
-        String fallbackPackage = "fallback";
+        String secondaryPackage = "secondary";
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo(
                     primaryPackage, "", true /* default available */, false /* fallback */, null),
             new WebViewProviderInfo(
-                    fallbackPackage, "", true /* default available */, true /* fallback */, null)};
-        setupWithPackages(packages, true /* fallbackLogicEnabled */);
+                    secondaryPackage, "", true /* default available */, false /* fallback */,
+                    null)};
+        setupWithPackages(packages);
         int secondaryUserId = 10;
         int userIdToChangePackageFor = multiUser ? secondaryUserId : TestSystemImpl.PRIMARY_USER_ID;
         if (multiUser) {
@@ -645,18 +640,12 @@
         setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
 
         runWebViewBootPreparationOnMainSync();
-
-        // Verify fallback disabled at boot when primary package enabled
-        checkEnablePackageForUserCalled(fallbackPackage, false, multiUser
-                ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
-                : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */);
-
         checkPreparationPhasesForPackage(primaryPackage, 1);
 
         boolean enabled = !(removalType == PackageRemovalType.DISABLE);
         boolean installed = !(removalType == PackageRemovalType.UNINSTALL);
         boolean hidden = (removalType == PackageRemovalType.HIDE);
-        // Disable primary package and ensure fallback becomes enabled and used
+        // Disable primary package and ensure secondary becomes used
         mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
                 createPackageInfo(primaryPackage, enabled /* enabled */, true /* valid */,
                     installed /* installed */, null /* signature */, 0 /* updateTime */,
@@ -665,15 +654,9 @@
                 removalType == PackageRemovalType.DISABLE
                 ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_REMOVED,
                 userIdToChangePackageFor); // USER ID
+        checkPreparationPhasesForPackage(secondaryPackage, 1);
 
-        checkEnablePackageForUserCalled(fallbackPackage, true, multiUser
-                ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
-                : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */);
-
-        checkPreparationPhasesForPackage(fallbackPackage, 1);
-
-
-        // Again enable primary package and verify primary is used and fallback becomes disabled
+        // Again enable primary package and verify primary is used
         mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
                 createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
                     true /* installed */));
@@ -681,60 +664,9 @@
                 removalType == PackageRemovalType.DISABLE
                 ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_ADDED,
                 userIdToChangePackageFor);
-
-        // Verify fallback is disabled a second time when primary package becomes enabled
-        checkEnablePackageForUserCalled(fallbackPackage, false, multiUser
-                ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
-                : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 2 /* numUsages */);
-
         checkPreparationPhasesForPackage(primaryPackage, 2);
     }
 
-    private void checkEnablePackageForUserCalled(String packageName, boolean expectEnabled,
-            int[] userIds, int numUsages) {
-        for (int userId : userIds) {
-            Mockito.verify(mTestSystemImpl, Mockito.times(numUsages)).enablePackageForUser(
-                    Mockito.eq(packageName), Mockito.eq(expectEnabled), Mockito.eq(userId));
-        }
-    }
-
-    @Test
-    public void testAddUserWhenFallbackLogicEnabled() {
-        checkAddingNewUser(true);
-    }
-
-    @Test
-    public void testAddUserWhenFallbackLogicDisabled() {
-        checkAddingNewUser(false);
-    }
-
-    public void checkAddingNewUser(boolean fallbackLogicEnabled) {
-        String primaryPackage = "primary";
-        String fallbackPackage = "fallback";
-        WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
-            new WebViewProviderInfo(
-                    primaryPackage, "", true /* default available */, false /* fallback */, null),
-            new WebViewProviderInfo(
-                    fallbackPackage, "", true /* default available */, true /* fallback */, null)};
-        setupWithPackages(packages, fallbackLogicEnabled);
-        setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
-        int newUser = 100;
-        mTestSystemImpl.addUser(newUser);
-        setEnabledAndValidPackageInfosForUser(newUser, packages);
-        mWebViewUpdateServiceImpl.handleNewUser(newUser);
-        if (fallbackLogicEnabled) {
-            // Verify fallback package becomes disabled for new user
-            Mockito.verify(mTestSystemImpl).enablePackageForUser(
-                    Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
-                    Mockito.eq(newUser));
-        } else {
-            // Verify that we don't disable fallback for new user
-            Mockito.verify(mTestSystemImpl, Mockito.never()).enablePackageForUser(
-                    Mockito.anyObject(), Matchers.anyBoolean() /* enable */,
-                    Matchers.anyInt() /* user */);
-        }
-    }
-
     /**
      * Ensures that adding a new user for which the current WebView package is uninstalled causes a
      * change of WebView provider.
@@ -742,13 +674,14 @@
     @Test
     public void testAddingNewUserWithUninstalledPackage() {
         String primaryPackage = "primary";
-        String fallbackPackage = "fallback";
+        String secondaryPackage = "secondary";
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo(
                     primaryPackage, "", true /* default available */, false /* fallback */, null),
             new WebViewProviderInfo(
-                    fallbackPackage, "", true /* default available */, true /* fallback */, null)};
-        setupWithPackages(packages, true /* fallbackLogicEnabled */);
+                    secondaryPackage, "", true /* default available */, false /* fallback */,
+                    null)};
+        setupWithPackages(packages);
         setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
         int newUser = 100;
         mTestSystemImpl.addUser(newUser);
@@ -757,18 +690,10 @@
                 createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
                         false /* installed */));
         mTestSystemImpl.setPackageInfoForUser(newUser,
-                createPackageInfo(fallbackPackage, false /* enabled */, true /* valid */,
+                createPackageInfo(secondaryPackage, true /* enabled */, true /* valid */,
                         true /* installed */));
         mWebViewUpdateServiceImpl.handleNewUser(newUser);
-        // Verify fallback package doesn't become disabled for the primary user.
-        Mockito.verify(mTestSystemImpl, Mockito.never()).enablePackageForUser(
-                Mockito.anyObject(), Mockito.eq(false) /* enable */,
-                Mockito.eq(TestSystemImpl.PRIMARY_USER_ID) /* user */);
-        // Verify that we enable the fallback package for the secondary user.
-        Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
-                Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */,
-                Mockito.eq(newUser) /* user */);
-        checkPreparationPhasesForPackage(fallbackPackage, 1 /* numRelros */);
+        checkPreparationPhasesForPackage(secondaryPackage, 1 /* numRelros */);
     }
 
     /**
@@ -874,7 +799,8 @@
         setupWithPackages(packages);
         // Only 'install' nonChosenPackage
         mTestSystemImpl.setPackageInfo(
-                createPackageInfo(nonChosenPackage, true /* enabled */, true /* valid */, true /* installed */));
+                createPackageInfo(nonChosenPackage, true /* enabled */, true /* valid */,
+                        true /* installed */));
 
         // Set user-chosen package
         mTestSystemImpl.updateUserSetting(null, chosenPackage);
@@ -1024,7 +950,8 @@
         checkPreparationPhasesForPackage(thirdPackage, 1);
 
         mTestSystemImpl.setPackageInfo(
-                createPackageInfo(secondPackage, true /* enabled */, false /* valid */, true /* installed */));
+                createPackageInfo(secondPackage, true /* enabled */, false /* valid */,
+                        true /* installed */));
 
         // Try to switch to the invalid second package, this should result in switching to the first
         // package, since that is more preferred than the third one.
@@ -1084,40 +1011,17 @@
                 100000 /* candidate version */, false /* expected validity */);
     }
 
-    @Test
-    public void testMinimumSystemVersionUsedFallbackIgnored() {
-        checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */,
-                200000 /* candidate version */, false /* expected validity */, true /* add fallback */,
-                100000 /* fallback version */, false /* expected validity of fallback */);
-    }
-
-    @Test
-    public void testFallbackValid() {
-        checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */,
-                200000/* candidate version */, false /* expected validity */, true /* add fallback */,
-                300000 /* fallback version */, true /* expected validity of fallback */);
-    }
-
-    private void checkPackageVersions(int[] systemVersions, int candidateVersion,
-            boolean candidateShouldBeValid) {
-        checkPackageVersions(systemVersions, candidateVersion, candidateShouldBeValid,
-                false, 0, false);
-    }
-
     /**
      * Utility method for checking that package version restriction works as it should.
      * I.e. that a package with lower version than the system-default is not valid and that a
      * package with greater than or equal version code is considered valid.
      */
     private void checkPackageVersions(int[] systemVersions, int candidateVersion,
-            boolean candidateShouldBeValid, boolean addFallback, int fallbackVersion,
-            boolean fallbackShouldBeValid) {
+            boolean candidateShouldBeValid) {
         int numSystemPackages = systemVersions.length;
-        int numFallbackPackages = (addFallback ? 1 : 0);
-        int numPackages = systemVersions.length + 1 + numFallbackPackages;
+        int numPackages = systemVersions.length + 1;
         String candidatePackage = "candidatePackage";
         String systemPackage = "systemPackage";
-        String fallbackPackage = "fallbackPackage";
 
         // Each package needs a valid signature since we set isDebuggable to false
         Signature signature = new Signature("11");
@@ -1126,8 +1030,7 @@
 
         // Set up config
         // 1. candidatePackage
-        // 2-N. default available non-fallback packages
-        // N+1. default available fallback package
+        // 2-N. default available packages
         WebViewProviderInfo[] packages = new WebViewProviderInfo[numPackages];
         packages[0] = new WebViewProviderInfo(candidatePackage, "",
                 false /* available by default */, false /* fallback */,
@@ -1137,14 +1040,7 @@
                     true /* available by default */, false /* fallback */,
                     new String[]{encodedSignatureString});
         }
-        if (addFallback) {
-            packages[packages.length-1] = new WebViewProviderInfo(fallbackPackage, "",
-                    true /* available by default */, true /* fallback */,
-                    new String[]{encodedSignatureString});
-        }
-
-        setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
-                false /* isDebuggable */);
+        setupWithPackagesNonDebuggable(packages);
 
         // Set package infos
         mTestSystemImpl.setPackageInfo(
@@ -1157,12 +1053,6 @@
                         true /* installed */, new Signature[]{signature}, 0 /* updateTime */,
                         false /* hidden */, systemVersions[n-1], true /* isSystemApp */));
         }
-        if (addFallback) {
-            mTestSystemImpl.setPackageInfo(
-                    createPackageInfo(fallbackPackage, true /* enabled */, true /* valid */,
-                        true /* installed */, new Signature[]{signature}, 0 /* updateTime */,
-                        false /* hidden */, fallbackVersion, true /* isSystemApp */));
-        }
 
         WebViewProviderInfo[] validPackages = mWebViewUpdateServiceImpl.getValidWebViewPackages();
         int expectedNumValidPackages = numSystemPackages;
@@ -1175,15 +1065,6 @@
             }
         }
 
-        if (fallbackShouldBeValid) {
-            expectedNumValidPackages += numFallbackPackages;
-        } else {
-            // Ensure the fallback package is not one of the valid packages
-            for(int n = 0; n < validPackages.length; n++) {
-                assertFalse(fallbackPackage.equals(validPackages[n].packageName));
-            }
-        }
-
         assertEquals(expectedNumValidPackages, validPackages.length);
 
         runWebViewBootPreparationOnMainSync();
@@ -1212,7 +1093,7 @@
         WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
                 new WebViewProviderInfo(testPackageName, "",
                         true /*default available*/, false /* fallback */, null)};
-        setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
+        setupWithPackages(webviewPackages);
         mTestSystemImpl.setPackageInfo(createPackageInfo(testPackageName, true /* enabled */,
                     true /* valid */, false /* installed */));
 
@@ -1250,7 +1131,7 @@
             new WebViewProviderInfo(installedPackage, "", true /* available by default */,
                     false /* fallback */, null)};
 
-        setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
+        setupWithPackages(webviewPackages);
         int secondaryUserId = 5;
         if (multiUser) {
             mTestSystemImpl.addUser(secondaryUserId);
@@ -1301,7 +1182,7 @@
             new WebViewProviderInfo(installedPackage, "", true /* available by default */,
                     false /* fallback */, null)};
 
-        setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
+        setupWithPackages(webviewPackages);
         int secondaryUserId = 412;
         mTestSystemImpl.addUser(secondaryUserId);
 
@@ -1356,7 +1237,7 @@
             new WebViewProviderInfo(installedPackage, "", true /* available by default */,
                     false /* fallback */, null)};
 
-        setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
+        setupWithPackages(webviewPackages);
         int secondaryUserId = 4;
         mTestSystemImpl.addUser(secondaryUserId);
 
@@ -1377,78 +1258,25 @@
     }
 
     @Test
-    public void testFallbackEnabledIfPrimaryUninstalledSingleUser() {
-        checkFallbackEnabledIfPrimaryUninstalled(false /* multiUser */);
-    }
-
-    @Test
-    public void testFallbackEnabledIfPrimaryUninstalledMultiUser() {
-        checkFallbackEnabledIfPrimaryUninstalled(true /* multiUser */);
-    }
-
-    /**
-     * Ensures that fallback becomes enabled at boot if the primary package is uninstalled for some
-     * user.
-     */
-    private void checkFallbackEnabledIfPrimaryUninstalled(boolean multiUser) {
-        String primaryPackage = "primary";
-        String fallbackPackage = "fallback";
-        WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
-            new WebViewProviderInfo(
-                    primaryPackage, "", true /* default available */, false /* fallback */, null),
-            new WebViewProviderInfo(
-                    fallbackPackage, "", true /* default available */, true /* fallback */, null)};
-        setupWithPackages(packages, true /* fallback logic enabled */);
-        int secondaryUserId = 5;
-        if (multiUser) {
-            mTestSystemImpl.addUser(secondaryUserId);
-            // Install all packages for the primary user.
-            setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
-            // Only install fallback package for secondary user.
-            mTestSystemImpl.setPackageInfoForUser(secondaryUserId,
-                    createPackageInfo(primaryPackage, true /* enabled */,
-                            true /* valid */, false /* installed */));
-            mTestSystemImpl.setPackageInfoForUser(secondaryUserId,
-                    createPackageInfo(fallbackPackage, false /* enabled */,
-                            true /* valid */, true /* installed */));
-        } else {
-            mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
-                    true /* valid */, false /* installed */));
-            mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, false /* enabled */,
-                    true /* valid */, true /* installed */));
-        }
-
-        runWebViewBootPreparationOnMainSync();
-        // Verify that we enable the fallback package
-        Mockito.verify(mTestSystemImpl).enablePackageForAllUsers(
-                Mockito.anyObject(), Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */);
-
-        checkPreparationPhasesForPackage(fallbackPackage, 1 /* first preparation phase */);
-    }
-
-    @Test
     public void testPreparationRunsIffNewPackage() {
         String primaryPackage = "primary";
-        String fallbackPackage = "fallback";
+        String secondaryPackage = "secondary";
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo(
                     primaryPackage, "", true /* default available */, false /* fallback */, null),
             new WebViewProviderInfo(
-                    fallbackPackage, "", true /* default available */, true /* fallback */, null)};
-        setupWithPackages(packages, true /* fallback logic enabled */);
+                    secondaryPackage, "", true /* default available */, false /* fallback */,
+                    null)};
+        setupWithPackages(packages);
         mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
                     true /* valid */, true /* installed */, null /* signatures */,
                     10 /* lastUpdateTime*/ ));
-        mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
+        mTestSystemImpl.setPackageInfo(createPackageInfo(secondaryPackage, true /* enabled */,
                     true /* valid */, true /* installed */));
 
         runWebViewBootPreparationOnMainSync();
 
         checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
-        Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
-                Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
-                Matchers.anyInt() /* user */);
-
 
         mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
                 WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0 /* userId */);
@@ -1459,9 +1287,6 @@
         // package still has the same update-time so we shouldn't run preparation here
         Mockito.verify(mTestSystemImpl, Mockito.times(1)).onWebViewProviderChanged(
                 Mockito.argThat(new IsPackageInfoWithName(primaryPackage)));
-        Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
-                Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
-                Matchers.anyInt() /* user */);
 
         // Ensure we can still load the package
         WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
@@ -1496,7 +1321,7 @@
         firstPackage.versionName = "first package version";
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo(firstPackage.packageName, "", true, false, null)};
-        setupWithPackages(packages, true);
+        setupWithPackages(packages);
         mTestSystemImpl.setPackageInfo(firstPackage);
 
         runWebViewBootPreparationOnMainSync();
@@ -1542,9 +1367,7 @@
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo(
                     primaryPackage, "", true /* default available */, false /* fallback */, null)};
-        setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
-                          true /* debuggable */,
-                          enabledByDefault /* not multiprocess by default */);
+        setupWithPackagesAndMultiProcess(packages, enabledByDefault);
         mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
                     true /* valid */, true /* installed */, null /* signatures */,
                     10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
@@ -1599,8 +1422,7 @@
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo(
                     primaryPackage, "", true /* default available */, false /* fallback */, null)};
-        setupWithPackages(packages, true /* fallback logic enabled */, 1 /* numRelros */,
-                          true /* debuggable */, enabledByDefault /* multiprocess by default */);
+        setupWithPackagesAndMultiProcess(packages, enabledByDefault);
         mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
                     true /* valid */, true /* installed */, null /* signatures */,
                     10 /* lastUpdateTime*/, false /* not hidden */, 1000 /* versionCode */,
@@ -1638,7 +1460,7 @@
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo(oldSdkPackage.packageName, "", true, false, null),
             currentSdkProviderInfo, newSdkProviderInfo};
-        setupWithPackages(packages, true);
+        setupWithPackages(packages);
 ;
         mTestSystemImpl.setPackageInfo(newSdkPackage);
         mTestSystemImpl.setPackageInfo(currentSdkPackage);
diff --git a/services/tests/uiservicestests/AndroidManifest.xml b/services/tests/uiservicestests/AndroidManifest.xml
index aa3135f..3ff85c8 100644
--- a/services/tests/uiservicestests/AndroidManifest.xml
+++ b/services/tests/uiservicestests/AndroidManifest.xml
@@ -29,6 +29,7 @@
     <uses-permission android:name="android.permission.DEVICE_POWER" />
     <uses-permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
 
     <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 426122a..ca7a71e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -18,6 +18,9 @@
 
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
+import static android.app.Notification.CATEGORY_CALL;
+import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
@@ -40,6 +43,8 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Build.VERSION_CODES.O_MR1;
 import static android.os.Build.VERSION_CODES.P;
+import static android.service.notification.Adjustment.KEY_IMPORTANCE;
+import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 
@@ -77,6 +82,8 @@
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
 import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Person;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.app.usage.UsageStatsManagerInternal;
 import android.companion.ICompanionDeviceManager;
@@ -90,6 +97,7 @@
 import android.content.pm.ParceledListSlice;
 import android.content.res.Resources;
 import android.graphics.Color;
+import android.graphics.drawable.Icon;
 import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Binder;
@@ -98,7 +106,9 @@
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.DeviceConfig;
 import android.provider.MediaStore;
 import android.provider.Settings;
@@ -131,7 +141,6 @@
 import com.android.server.lights.LightsManager;
 import com.android.server.notification.NotificationManagerService.NotificationAssistants;
 import com.android.server.notification.NotificationManagerService.NotificationListeners;
-import com.android.server.pm.UserManagerService;
 import com.android.server.uri.UriGrantsManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -147,7 +156,6 @@
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -224,23 +232,21 @@
     @Mock
     AppOpsManager mAppOpsManager;
     @Mock
-    private UserManagerService mUserMangerService;
-    @Mock
     private TestableNotificationManagerService.NotificationAssistantAccessGrantedCallback
             mNotificationAssistantAccessGrantedCallback;
+    @Mock
+    UserManager mUm;
 
     // Use a Testable subclass so we can simulate calls from the system without failing.
     private static class TestableNotificationManagerService extends NotificationManagerService {
         int countSystemChecks = 0;
         boolean isSystemUid = true;
         int countLogSmartSuggestionsVisible = 0;
-        UserManagerService mUserManagerService;
         @Nullable
         NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback;
 
-        TestableNotificationManagerService(Context context, UserManagerService userManagerService) {
+        TestableNotificationManagerService(Context context) {
             super(context);
-            mUserManagerService = userManagerService;
         }
 
         @Override
@@ -277,11 +283,6 @@
         }
 
         @Override
-        UserManagerService getUserManagerService() {
-            return mUserManagerService;
-        }
-
-        @Override
         protected void setNotificationAssistantAccessGrantedForUserInternal(
                 ComponentName assistant, int userId, boolean granted) {
             if (mNotificationAssistantAccessGrantedCallback != null) {
@@ -324,7 +325,7 @@
         LocalServices.removeServiceForTest(WindowManagerInternal.class);
         LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
 
-        mService = new TestableNotificationManagerService(mContext, mUserMangerService);
+        mService = new TestableNotificationManagerService(mContext);
 
         // Use this testable looper.
         mTestableLooper = TestableLooper.get(this);
@@ -377,7 +378,7 @@
                     mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
                     mGroupHelper, mAm, mAppUsageStats,
                     mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal,
-                    mAppOpsManager);
+                    mAppOpsManager, mUm);
             mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
         } catch (SecurityException e) {
             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
@@ -436,6 +437,11 @@
 
     private NotificationRecord generateNotificationRecord(NotificationChannel channel,
             Notification.TvExtender extender) {
+        return generateNotificationRecord(channel, extender, false /* isBubble */);
+    }
+
+    private NotificationRecord generateNotificationRecord(NotificationChannel channel,
+            Notification.TvExtender extender, boolean isBubble) {
         if (channel == null) {
             channel = mTestNotificationChannel;
         }
@@ -445,6 +451,9 @@
         if (extender != null) {
             nb.extend(extender);
         }
+        if (isBubble) {
+            nb.setBubbleMetadata(getBasicBubbleMetadataBuilder().build());
+        }
         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
                 nb.build(), new UserHandle(mUid), null, 0);
         return new NotificationRecord(mContext, sbn, channel);
@@ -492,6 +501,26 @@
         return answers;
     }
 
+    private void clearDeviceConfig() {
+        DeviceConfig.resetToDefaults(
+                Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI);
+    }
+
+    private void setDefaultAssistantInDeviceConfig(String componentName) {
+        DeviceConfig.setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE,
+                componentName,
+                false);
+    }
+
+    private Notification.BubbleMetadata.Builder getBasicBubbleMetadataBuilder() {
+        PendingIntent pi = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+        return new Notification.BubbleMetadata.Builder()
+                .setIntent(pi)
+                .setIcon(Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon));
+    }
+
     @Test
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
@@ -831,7 +860,7 @@
         mService.addEnqueuedNotification(r);
 
         Bundle bundle = new Bundle();
-        bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
+        bundle.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
@@ -1905,8 +1934,8 @@
     }
 
     @Test
-    public void testHasCompanionDevice_noService() throws Exception {
-        mService = new TestableNotificationManagerService(mContext, mUserMangerService);
+    public void testHasCompanionDevice_noService() {
+        mService = new TestableNotificationManagerService(mContext);
 
         assertFalse(mService.hasCompanionDevice(mListener));
     }
@@ -2608,7 +2637,7 @@
                 + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
                 + "</dnd_apps>"
                 + "</notification-policy>";
-        when(mUserMangerService.isManagedProfile(10)).thenReturn(true);
+        when(mUm.isManagedProfile(10)).thenReturn(true);
         mService.readPolicyXml(
                 new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())),
                 true,
@@ -2632,7 +2661,7 @@
                 + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
                 + "</dnd_apps>"
                 + "</notification-policy>";
-        when(mUserMangerService.isManagedProfile(10)).thenReturn(false);
+        when(mUm.isManagedProfile(10)).thenReturn(false);
         mService.readPolicyXml(
                 new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())),
                 true,
@@ -2826,7 +2855,7 @@
         mService.setHandler(handler);
 
         Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
@@ -2867,7 +2896,7 @@
         when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
 
         Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
@@ -2885,13 +2914,13 @@
         when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
 
         Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         assertEquals(IMPORTANCE_DEFAULT, r.getImportance());
-        assertFalse(r.hasAdjustment(Adjustment.KEY_IMPORTANCE));
+        assertFalse(r.hasAdjustment(KEY_IMPORTANCE));
     }
 
     @Test
@@ -4275,17 +4304,634 @@
                 .onGranted(eq(xmlConfig), eq(0), eq(true));
     }
 
-    private void clearDeviceConfig() {
-        DeviceConfig.resetToDefaults(
-                Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI);
+    @Test
+    public void testFlagBubbleNotifs_flag_appForeground() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Notif with bubble metadata but not our other misc requirements
+        NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,
+                null /* tvExtender */, true /* isBubble */);
+
+        // Say we're foreground
+        when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
+                IMPORTANCE_FOREGROUND);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes allowed, yes foreground, yes bubble
+        assertTrue(mService.getNotificationRecord(
+                nr.sbn.getKey()).getNotification().isBubbleNotification());
     }
 
-    private void setDefaultAssistantInDeviceConfig(String componentName) {
-        DeviceConfig.setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE,
-                componentName,
-                false);
+    @Test
+    public void testFlagBubbleNotifs_noFlag_appNotForeground() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Notif with bubble metadata but not our other misc requirements
+        NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,
+                null /* tvExtender */, true /* isBubble */);
+
+        // Make sure we're NOT foreground
+        when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
+                IMPORTANCE_VISIBLE);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes allowed but NOT foreground, no bubble
+        assertFalse(mService.getNotificationRecord(
+                nr.sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_flag_previousForegroundFlag() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Notif with bubble metadata but not our other misc requirements
+        NotificationRecord nr1 = generateNotificationRecord(mTestNotificationChannel,
+                null /* tvExtender */, true /* isBubble */);
+
+        // Send notif when we're foreground
+        when(mActivityManager.getPackageImportance(nr1.sbn.getPackageName())).thenReturn(
+                IMPORTANCE_FOREGROUND);
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nr1.sbn.getId(), nr1.sbn.getNotification(), nr1.sbn.getUserId());
+        waitForIdle();
+
+        // yes allowed, yes foreground, yes bubble
+        assertTrue(mService.getNotificationRecord(
+                nr1.sbn.getKey()).getNotification().isBubbleNotification());
+
+        // Send a new update when we're not foreground
+        NotificationRecord nr2 = generateNotificationRecord(mTestNotificationChannel,
+                null /* tvExtender */, true /* isBubble */);
+
+        when(mActivityManager.getPackageImportance(nr2.sbn.getPackageName())).thenReturn(
+                IMPORTANCE_VISIBLE);
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nr2.sbn.getId(), nr2.sbn.getNotification(), nr2.sbn.getUserId());
+        waitForIdle();
+
+        // yes allowed, previously foreground / flagged, yes bubble
+        assertTrue(mService.getNotificationRecord(
+                nr2.sbn.getKey()).getNotification().isBubbleNotification());
+
+        StatusBarNotification[] notifs2 = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifs2.length);
+        assertEquals(1, mService.getNotificationRecordCount());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_noFlag_previousForegroundFlag_afterRemoval()
+            throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Notif with bubble metadata but not our other misc requirements
+        NotificationRecord nr1 = generateNotificationRecord(mTestNotificationChannel,
+                null /* tvExtender */, true /* isBubble */);
+
+        // Send notif when we're foreground
+        when(mActivityManager.getPackageImportance(nr1.sbn.getPackageName())).thenReturn(
+                IMPORTANCE_FOREGROUND);
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nr1.sbn.getId(), nr1.sbn.getNotification(), nr1.sbn.getUserId());
+        waitForIdle();
+
+        // yes allowed, yes foreground, yes bubble
+        assertTrue(mService.getNotificationRecord(
+                nr1.sbn.getKey()).getNotification().isBubbleNotification());
+
+        // Remove the bubble
+        mBinderService.cancelNotificationWithTag(PKG, "tag", nr1.sbn.getId(),
+                nr1.sbn.getUserId());
+        waitForIdle();
+
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        assertEquals(0, notifs.length);
+        assertEquals(0, mService.getNotificationRecordCount());
+
+        // Send a new update when we're not foreground
+        NotificationRecord nr2 = generateNotificationRecord(mTestNotificationChannel,
+                null /* tvExtender */, true /* isBubble */);
+
+        when(mActivityManager.getPackageImportance(nr2.sbn.getPackageName())).thenReturn(
+                IMPORTANCE_VISIBLE);
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nr2.sbn.getId(), nr2.sbn.getNotification(), nr2.sbn.getUserId());
+        waitForIdle();
+
+        // yes allowed, but was removed & no foreground, so no bubble
+        assertFalse(mService.getNotificationRecord(
+                nr2.sbn.getKey()).getNotification().isBubbleNotification());
+
+        StatusBarNotification[] notifs2 = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifs2.length);
+        assertEquals(1, mService.getNotificationRecordCount());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_flag_messaging() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // Make it messaging style
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setStyle(new Notification.MessagingStyle(person)
+                        .setConversationTitle("Bubble Chat")
+                        .addMessage("Hello?",
+                                SystemClock.currentThreadTimeMillis() - 300000, person)
+                        .addMessage("Is it me you're looking for?",
+                                SystemClock.currentThreadTimeMillis(), person)
+                )
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes allowed, yes messaging, yes bubble
+        assertTrue(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_flag_phonecall() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // Make it a phone call
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setCategory(CATEGORY_CALL)
+                .addPerson(person)
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        // Make sure it has foreground service
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes phone call, yes person, yes foreground service, yes bubble
+        assertTrue(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_noFlag_phonecall_noForegroundService() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // Make it a phone call
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setCategory(CATEGORY_CALL)
+                .addPerson(person)
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes phone call, yes person, NO foreground service, no bubble
+        assertFalse(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_noFlag_phonecall_noPerson() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build();
+        // Make it a phone call
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setCategory(CATEGORY_CALL)
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        // Make sure it has foreground service
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes phone call, yes foreground service, BUT NO person, no bubble
+        assertFalse(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_noFlag_phonecall_noCategory() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // No category
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .addPerson(person)
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        // Make sure it has foreground service
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes person, yes foreground service, BUT NO call, no bubble
+        assertFalse(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_noFlag_messaging_appNotAllowed() throws RemoteException {
+        // Bubbles are NOT allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(false);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // Make it messaging style
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setStyle(new Notification.MessagingStyle(person)
+                        .setConversationTitle("Bubble Chat")
+                        .addMessage("Hello?",
+                                SystemClock.currentThreadTimeMillis() - 300000, person)
+                        .addMessage("Is it me you're looking for?",
+                                SystemClock.currentThreadTimeMillis(), person)
+                )
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        // Post the notification
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // not allowed, no bubble
+        assertFalse(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_noFlag_notBubble() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Notif WITHOUT bubble metadata
+        NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel);
+
+        // Post the notification
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // no bubble metadata, no bubble
+        assertFalse(mService.getNotificationRecord(
+                nr.sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_noFlag_messaging_channelNotAllowed() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(true);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // But not on this channel!
+        mTestNotificationChannel.setAllowBubbles(false);
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // Make it messaging style
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setStyle(new Notification.MessagingStyle(person)
+                        .setConversationTitle("Bubble Chat")
+                        .addMessage("Hello?",
+                                SystemClock.currentThreadTimeMillis() - 300000, person)
+                        .addMessage("Is it me you're looking for?",
+                                SystemClock.currentThreadTimeMillis(), person)
+                )
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        // Post the notification
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // channel not allowed, no bubble
+        assertFalse(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_noFlag_phonecall_notAllowed() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(false);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // Make it a phone call
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setCategory(CATEGORY_CALL)
+                .addPerson(person)
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        // Make sure it has foreground service
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes phone call, yes person, yes foreground service, but not allowed, no bubble
+        assertFalse(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testFlagBubbleNotifs_noFlag_phonecall_channelNotAllowed() throws RemoteException {
+        // Bubbles are allowed!
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.areBubblesAllowed(anyString(), anyInt())).thenReturn(false);
+        when(mPreferencesHelper.getNotificationChannel(
+                anyString(), anyInt(), anyString(), anyBoolean())).thenReturn(
+                mTestNotificationChannel);
+        when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(
+                mTestNotificationChannel.getImportance());
+
+        // But not on this channel!
+        mTestNotificationChannel.setAllowBubbles(false);
+
+        // Give it bubble metadata
+        Notification.BubbleMetadata data = getBasicBubbleMetadataBuilder().build();
+        // Give it a person
+        Person person = new Person.Builder()
+                .setName("bubblebot")
+                .build();
+        // Make it a phone call
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setCategory(CATEGORY_CALL)
+                .addPerson(person)
+                .setContentTitle("foo")
+                .setBubbleMetadata(data)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
+
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, null, mUid, 0,
+                nb.build(), new UserHandle(mUid), null, 0);
+        // Make sure it has foreground service
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
+        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
+        waitForIdle();
+
+        // yes phone call, yes person, yes foreground service, but channel not allowed, no bubble
+        assertFalse(mService.getNotificationRecord(
+                sbn.getKey()).getNotification().isBubbleNotification());
+    }
+
+    @Test
+    public void testCancelAllNotifications_cancelsBubble() throws Exception {
+        final NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel);
+        nr.sbn.getNotification().flags |= FLAG_BUBBLE;
+        mService.addNotification(nr);
+
+        mBinderService.cancelAllNotifications(PKG, nr.sbn.getUserId());
+        waitForIdle();
+
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        assertEquals(0, notifs.length);
+        assertEquals(0, mService.getNotificationRecordCount());
+    }
+
+    @Test
+    public void testAppCancelNotifications_cancelsBubbles() throws Exception {
+        final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel);
+        nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE;
+
+        // Post the notification
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+                nrBubble.sbn.getId(), nrBubble.sbn.getNotification(), nrBubble.sbn.getUserId());
+        waitForIdle();
+
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifs.length);
+        assertEquals(1, mService.getNotificationRecordCount());
+
+        mBinderService.cancelNotificationWithTag(PKG, null, nrBubble.sbn.getId(),
+                nrBubble.sbn.getUserId());
+        waitForIdle();
+
+        StatusBarNotification[] notifs2 = mBinderService.getActiveNotifications(PKG);
+        assertEquals(0, notifs2.length);
+        assertEquals(0, mService.getNotificationRecordCount());
+    }
+
+    @Test
+    public void testCancelAllNotificationsFromListener_ignoresBubbles() throws Exception {
+        final NotificationRecord nrNormal = generateNotificationRecord(mTestNotificationChannel);
+        final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel);
+        nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE;
+
+        mService.addNotification(nrNormal);
+        mService.addNotification(nrBubble);
+
+        mService.getBinderService().cancelNotificationsFromListener(null, null);
+        waitForIdle();
+
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifs.length);
+        assertEquals(1, mService.getNotificationRecordCount());
+    }
+
+    @Test
+    public void testCancelNotificationsFromListener_ignoresBubbles() throws Exception {
+        final NotificationRecord nrNormal = generateNotificationRecord(mTestNotificationChannel);
+        final NotificationRecord nrBubble = generateNotificationRecord(mTestNotificationChannel);
+        nrBubble.sbn.getNotification().flags |= FLAG_BUBBLE;
+
+        mService.addNotification(nrNormal);
+        mService.addNotification(nrBubble);
+
+        String[] keys = {nrNormal.sbn.getKey(), nrBubble.sbn.getKey()};
+        mService.getBinderService().cancelNotificationsFromListener(null, keys);
+        waitForIdle();
+
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifs.length);
+        assertEquals(1, mService.getNotificationRecordCount());
     }
 
     public void testGetAllowedAssistantCapabilities() throws Exception {
@@ -4301,4 +4947,55 @@
             assertFalse(currentCapabilities.contains(capability));
         }
     }
+
+    public void testAdjustRestrictedKey() throws Exception {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+
+        when(mAssistants.isAdjustmentAllowed(KEY_IMPORTANCE)).thenReturn(true);
+        when(mAssistants.isAdjustmentAllowed(KEY_USER_SENTIMENT)).thenReturn(false);
+
+        Bundle signals = new Bundle();
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
+        signals.putInt(KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
+        Adjustment adjustment = new Adjustment(r.sbn.getPackageName(), r.getKey(), signals,
+               "", r.getUser().getIdentifier());
+
+        mBinderService.applyAdjustmentFromAssistant(null, adjustment);
+        r.applyAdjustments();
+
+        assertEquals(IMPORTANCE_LOW, r.getAssistantImportance());
+        assertEquals(USER_SENTIMENT_NEUTRAL, r.getUserSentiment());
+    }
+
+    public void testAreNotificationsEnabledForPackage_crossUser() throws Exception {
+        try {
+            mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
+                    mUid + UserHandle.PER_USER_RANGE);
+            fail("Cannot call cross user without permission");
+        } catch (SecurityException e) {
+            // pass
+        }
+
+        // cross user, with permission, no problem
+        TestablePermissions perms = mContext.getTestablePermissions();
+        perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
+        mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
+                mUid + UserHandle.PER_USER_RANGE);
+    }
+
+    public void testAreBubblesAllowedForPackage_crossUser() throws Exception {
+        try {
+            mBinderService.areBubblesAllowedForPackage(mContext.getPackageName(),
+                    mUid + UserHandle.PER_USER_RANGE);
+            fail("Cannot call cross user without permission");
+        } catch (SecurityException e) {
+            // pass
+        }
+
+        // cross user, with permission, no problem
+        TestablePermissions perms = mContext.getTestablePermissions();
+        perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED);
+        mBinderService.areBubblesAllowedForPackage(mContext.getPackageName(),
+                mUid + UserHandle.PER_USER_RANGE);
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index e375195..7c22350 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -477,8 +477,9 @@
         assertEquals(MetricsEvent.IMPORTANCE_EXPLANATION_APP,
                 logMaker.getTaggedData(
                         MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_INITIAL_EXPLANATION));
-        // This field is only populated if the assistant was itself overridden by the system.
-        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST));
+        // This field is populated whenever mImportanceExplanationCode is.
+        assertEquals(IMPORTANCE_LOW,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_IMPORTANCE_ASST));
     }
 
     @Test
@@ -952,7 +953,31 @@
     }
 
     @Test
-    public void testApplyImportanceAdjustmentsForNonOemLockedChannels() {
+    public void testIgnoreImportanceAdjustmentsForDefaultAppLockedChannels() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        channel.setImportanceLockedByCriticalDeviceFunction(true);
+
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, groupId /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        assertEquals(IMPORTANCE_DEFAULT, record.getImportance());
+
+        Bundle bundle = new Bundle();
+        bundle.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
+        Adjustment adjustment = new Adjustment(
+                PKG_O, record.getKey(), bundle, "", record.getUserId());
+
+        record.addAdjustment(adjustment);
+        record.applyAdjustments();
+        record.calculateImportance();
+
+        assertEquals(IMPORTANCE_DEFAULT, record.getImportance());
+    }
+
+    @Test
+    public void testApplyImportanceAdjustmentsForNonOemDefaultAppLockedChannels() {
         NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
         channel.setImportanceLockedByOEM(false);
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 39e47ec..87f10a4 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -62,11 +62,9 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableContentResolver;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Xml;
 
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.UiServiceTestCase;
 
@@ -91,6 +89,9 @@
 import java.util.Objects;
 import java.util.concurrent.ThreadLocalRandom;
 
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class PreferencesHelperTest extends UiServiceTestCase {
@@ -2442,4 +2443,153 @@
         assertEquals(IMPORTANCE_HIGH,
                 mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
     }
+
+    @Test
+    public void testUpdateDefaultApps_add_multiUser() {
+        NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+        NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
+        // different uids, same package
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
+        mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
+
+        ArraySet<String> toAdd = new ArraySet<>();
+        toAdd.add(PKG_O);
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
+
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+        assertFalse(mHelper.getNotificationChannel(
+                PKG_O, UserHandle.PER_USER_RANGE + 1, c.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+    }
+
+    @Test
+    public void testUpdateDefaultApps_add_onlyGivenPkg() {
+        NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
+
+        ArraySet<String> toAdd = new ArraySet<>();
+        toAdd.add(PKG_O);
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
+
+
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+        assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+    }
+
+    @Test
+    public void testUpdateDefaultApps_remove() {
+        NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+        // different uids, same package
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
+
+        ArraySet<String> toAdd = new ArraySet<>();
+        toAdd.add(PKG_O);
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
+
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+
+        ArraySet<String> toRemove = new ArraySet<>();
+        toRemove.add(PKG_O);
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, null);
+
+        assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+        assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+    }
+
+    @Test
+    public void testUpdateDefaultApps_addAndRemove() {
+        NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, b, false, false);
+
+        ArraySet<String> toAdd = new ArraySet<>();
+        toAdd.add(PKG_O);
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
+
+
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+        assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+
+        // now the default is PKG_N_MR1
+        ArraySet<String> toRemove = new ArraySet<>();
+        toRemove.add(PKG_O);
+        toAdd = new ArraySet<>();
+        toAdd.add(PKG_N_MR1);
+        mHelper.updateDefaultApps(USER.getIdentifier(), toRemove, toAdd);
+
+        assertFalse(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+        assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, b.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+    }
+
+    @Test
+    public void testUpdateDefaultApps_appDoesNotExist_noCrash() {
+        ArraySet<String> toAdd = new ArraySet<>();
+        toAdd.add(PKG_O);
+        ArraySet<String> toRemove = new ArraySet<>();
+        toRemove.add(PKG_N_MR1);
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), toRemove, toAdd);
+    }
+
+    @Test
+    public void testUpdateDefaultApps_channelDoesNotExistYet() {
+        NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+
+        ArraySet<String> toAdd = new ArraySet<>();
+        toAdd.add(PKG_O);
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
+
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+
+        mHelper.createNotificationChannel(PKG_O, UID_O, b, true, false);
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
+                .isImportanceLockedByCriticalDeviceFunction());
+    }
+
+    @Test
+    public void testUpdateNotificationChannel_defaultAppLockedImportance() {
+        NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
+        ArraySet<String> toAdd = new ArraySet<>();
+        toAdd.add(PKG_O);
+        mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, toAdd);
+
+        NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
+        update.setAllowBubbles(false);
+
+        mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
+
+        assertEquals(IMPORTANCE_HIGH,
+                mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
+        assertEquals(false,
+                mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
+
+        mHelper.updateNotificationChannel(PKG_O, UID_O, update, false);
+
+        assertEquals(IMPORTANCE_HIGH,
+                mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
new file mode 100644
index 0000000..91d3e5e
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
+import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MAX;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
+import static android.app.role.RoleManager.ROLE_DIALER;
+import static android.app.role.RoleManager.ROLE_EMERGENCY;
+import static android.app.role.RoleManager.ROLE_SMS;
+import static android.content.pm.PackageManager.FEATURE_WATCH;
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Build.VERSION_CODES.O_MR1;
+import static android.os.Build.VERSION_CODES.P;
+import static android.service.notification.Adjustment.KEY_IMPORTANCE;
+import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.app.IActivityManager;
+import android.app.INotificationManager;
+import android.app.ITransientNotification;
+import android.app.IUriGrantsManager;
+import android.app.Notification;
+import android.app.Notification.MessagingStyle.Message;
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManagerInternal;
+import android.app.role.RoleManager;
+import android.app.usage.UsageStatsManagerInternal;
+import android.companion.ICompanionDeviceManager;
+import android.content.ComponentName;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.UserInfo;
+import android.graphics.Color;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.DeviceConfig;
+import android.provider.MediaStore;
+import android.provider.Settings;
+import android.service.notification.Adjustment;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationStats;
+import android.service.notification.NotifyingApp;
+import android.service.notification.StatusBarNotification;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableContext;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.testing.TestablePermissions;
+import android.text.Html;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.AtomicFile;
+
+import com.android.internal.R;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.server.LocalServices;
+import com.android.server.UiServiceTestCase;
+import com.android.server.lights.Light;
+import com.android.server.lights.LightsManager;
+import com.android.server.notification.NotificationManagerService.NotificationAssistants;
+import com.android.server.notification.NotificationManagerService.NotificationListeners;
+import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.wm.WindowManagerInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+import androidx.annotation.Nullable;
+import androidx.test.InstrumentationRegistry;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class RoleObserverTest extends UiServiceTestCase {
+    private TestableNotificationManagerService mService;
+    private NotificationManagerService.RoleObserver mRoleObserver;
+
+    private TestableContext mContext = spy(getContext());
+
+    @Mock
+    private PreferencesHelper mPreferencesHelper;
+    @Mock
+    private UserManager mUm;
+    @Mock
+    private Executor mExecutor;
+    @Mock
+    private RoleManager mRoleManager;
+
+    private List<UserInfo> mUsers;
+
+    private static class TestableNotificationManagerService extends NotificationManagerService {
+
+        TestableNotificationManagerService(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void handleSavePolicyFile() {
+            return;
+        }
+
+        @Override
+        protected void loadPolicyFile() {
+            return;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        LocalServices.removeServiceForTest(WindowManagerInternal.class);
+        LocalServices.addService(WindowManagerInternal.class, mock(WindowManagerInternal.class));
+
+        mUsers = new ArrayList<>();
+        mUsers.add(new UserInfo(0, "system", 0));
+        mUsers.add(new UserInfo(10, "second", 0));
+        when(mUm.getUsers()).thenReturn(mUsers);
+
+        mService = new TestableNotificationManagerService(mContext);
+        mRoleObserver = mService.new RoleObserver(mRoleManager, mExecutor);
+
+        try {
+            mService.init(mock(Looper.class),
+                    mock(IPackageManager.class), mock(PackageManager.class),
+                    mock(LightsManager.class),
+                    mock(NotificationListeners.class), mock(NotificationAssistants.class),
+                    mock(ConditionProviders.class), mock(ICompanionDeviceManager.class),
+                    mock(SnoozeHelper.class), mock(NotificationUsageStats.class),
+                    mock(AtomicFile.class), mock(ActivityManager.class),
+                    mock(GroupHelper.class), mock(IActivityManager.class),
+                    mock(UsageStatsManagerInternal.class),
+                    mock(DevicePolicyManagerInternal.class), mock(IUriGrantsManager.class),
+                    mock(UriGrantsManagerInternal.class),
+                    mock(AppOpsManager.class), mUm);
+        } catch (SecurityException e) {
+            if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
+                throw e;
+            }
+        }
+        mService.setPreferencesHelper(mPreferencesHelper);
+    }
+
+    @Test
+    public void testInit() {
+        List<String> dialer0 = new ArrayList<>();
+        dialer0.add("dialer");
+        List<String> emer0 = new ArrayList<>();
+        emer0.add("emergency");
+        List<String> sms10 = new ArrayList<>();
+        sms10.add("sms");
+        when(mRoleManager.getRoleHoldersAsUser(
+                ROLE_DIALER,
+                mUsers.get(0).getUserHandle())).
+                thenReturn(dialer0);
+        when(mRoleManager.getRoleHoldersAsUser(
+                ROLE_EMERGENCY,
+                mUsers.get(0).getUserHandle())).
+                thenReturn(emer0);
+        when(mRoleManager.getRoleHoldersAsUser(
+                ROLE_SMS,
+                mUsers.get(1).getUserHandle())).
+                thenReturn(sms10);
+
+        mRoleObserver.init();
+
+        // verify internal records of current state of the world
+        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(
+                ROLE_DIALER, dialer0.get(0), mUsers.get(0).id));
+        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(
+                ROLE_DIALER, dialer0.get(0), mUsers.get(1).id));
+        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(
+                ROLE_SMS, dialer0.get(0), mUsers.get(1).id));
+
+        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(
+                ROLE_EMERGENCY, emer0.get(0), mUsers.get(0).id));
+        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(
+                ROLE_EMERGENCY, emer0.get(0), mUsers.get(1).id));
+
+        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(
+                ROLE_SMS, sms10.get(0), mUsers.get(0).id));
+        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(
+                ROLE_DIALER, sms10.get(0), mUsers.get(0).id));
+        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(
+                ROLE_SMS, sms10.get(0), mUsers.get(1).id));
+
+        // make sure we're listening to updates
+        verify(mRoleManager, times(1)).addOnRoleHoldersChangedListenerAsUser(
+                eq(mExecutor), any(), eq(UserHandle.ALL));
+
+        // make sure we told pref helper about the state of the world
+        verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, new ArraySet<>(dialer0));
+        verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, new ArraySet<>(emer0));
+        verify(mPreferencesHelper, times(1)).updateDefaultApps(10, null, new ArraySet<>(sms10));
+    }
+
+    @Test
+    public void testSwapDefault() {
+        List<String> dialer0 = new ArrayList<>();
+        dialer0.add("dialer");
+
+        when(mRoleManager.getRoleHoldersAsUser(
+                ROLE_DIALER,
+                mUsers.get(0).getUserHandle())).
+                thenReturn(dialer0);
+
+        mRoleObserver.init();
+
+        List<String> newDefault = new ArrayList<>();
+        newDefault.add("phone");
+
+        when(mRoleManager.getRoleHoldersAsUser(
+                ROLE_DIALER,
+                mUsers.get(0).getUserHandle())).
+                thenReturn(newDefault);
+
+        mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0));
+
+        verify(mPreferencesHelper, times(1)).updateDefaultApps(
+                0, new ArraySet<>(dialer0), new ArraySet<>(newDefault));
+    }
+
+    @Test
+    public void testSwapDefault_multipleOverlappingApps() {
+        List<String> dialer0 = new ArrayList<>();
+        dialer0.add("dialer");
+        dialer0.add("phone");
+
+        when(mRoleManager.getRoleHoldersAsUser(
+                ROLE_DIALER,
+                mUsers.get(0).getUserHandle())).
+                thenReturn(dialer0);
+
+        mRoleObserver.init();
+
+        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 0));
+        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "emerPhone", 0));
+        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0));
+
+        List<String> newDefault = new ArrayList<>();
+        newDefault.add("phone");
+        newDefault.add("emerPhone");
+
+        when(mRoleManager.getRoleHoldersAsUser(
+                ROLE_DIALER,
+                mUsers.get(0).getUserHandle())).
+                thenReturn(newDefault);
+
+        mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0));
+
+        ArraySet<String> expectedRemove = new ArraySet<>();
+        expectedRemove.add("dialer");
+        ArraySet<String> expectedAdd = new ArraySet<>();
+        expectedAdd.add("emerPhone");
+
+        verify(mPreferencesHelper, times(1)).updateDefaultApps(
+                0, expectedRemove, expectedAdd);
+
+        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 0));
+        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "emerPhone", 0));
+        assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0));
+    }
+
+    @Test
+    public void testSwapDefault_newUser() {
+        List<String> dialer0 = new ArrayList<>();
+        dialer0.add("dialer");
+
+        when(mRoleManager.getRoleHoldersAsUser(
+                ROLE_DIALER,
+                mUsers.get(0).getUserHandle())).
+                thenReturn(dialer0);
+
+        mRoleObserver.init();
+
+        List<String> dialer10 = new ArrayList<>();
+        dialer10.add("phone");
+
+        when(mRoleManager.getRoleHoldersAsUser(
+                ROLE_DIALER,
+                mUsers.get(1).getUserHandle())).
+                thenReturn(dialer10);
+
+        mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(10));
+
+        ArraySet<String> expectedRemove = new ArraySet<>();
+        ArraySet<String> expectedAdd = new ArraySet<>();
+        expectedAdd.add("phone");
+
+        verify(mPreferencesHelper, times(1)).updateDefaultApps(
+                10, expectedRemove, expectedAdd);
+
+        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 10));
+        assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0));
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
index 042c9d9..3b15376 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java
@@ -415,6 +415,39 @@
     }
 
     @Test
+    public void testIsAlarmInSchedule_alarmAndNowInSchedule_sameScheduleTrigger_daylightSavings() {
+        Calendar alarm = getDaylightSavingsDay();
+        alarm.set(Calendar.HOUR_OF_DAY, 23);
+        alarm.set(Calendar.MINUTE, 15);
+        alarm.set(Calendar.SECOND, 0);
+        alarm.set(Calendar.MILLISECOND, 0);
+
+        Calendar now = getDaylightSavingsDay();
+        now.set(Calendar.HOUR_OF_DAY, 2);
+        now.set(Calendar.MINUTE, 10);
+        now.set(Calendar.SECOND, 0);
+        now.set(Calendar.MILLISECOND, 0);
+        now.add(Calendar.DATE, 1); // add a day, on daylight savings this becomes 3:10am
+
+        final Calendar tempToday = getDaylightSavingsDay();
+        final Calendar tempTomorrow = getDaylightSavingsDay();
+        tempTomorrow.add(Calendar.DATE, 1);
+        mScheduleInfo.days = new int[] {tempToday.get(Calendar.DAY_OF_WEEK),
+                tempTomorrow.get(Calendar.DAY_OF_WEEK)};
+
+        mScheduleInfo.startHour = 22;
+        mScheduleInfo.startMinute = 15;
+        mScheduleInfo.endHour = 3;
+        mScheduleInfo.endMinute = 15;
+        mScheduleCalendar.setSchedule(mScheduleInfo);
+
+        assertTrue(mScheduleCalendar.isInSchedule(alarm.getTimeInMillis()));
+        assertTrue(mScheduleCalendar.isInSchedule(now.getTimeInMillis()));
+        assertTrue(mScheduleCalendar.isAlarmInSchedule(alarm.getTimeInMillis(),
+                now.getTimeInMillis()));
+    }
+
+    @Test
     public void testIsAlarmInSchedule_alarmAndNowInSchedule_sameScheduleTrigger() {
         Calendar alarm = new GregorianCalendar();
         alarm.set(Calendar.HOUR_OF_DAY, 23);
@@ -424,10 +457,10 @@
 
         Calendar now = new GregorianCalendar();
         now.set(Calendar.HOUR_OF_DAY, 2);
-        now.set(Calendar.MINUTE, 15);
+        now.set(Calendar.MINUTE, 10);
         now.set(Calendar.SECOND, 0);
         now.set(Calendar.MILLISECOND, 0);
-        now.add(Calendar.DATE, 1); // add a day
+        now.add(Calendar.DATE, 1); // add a day, on daylight savings this becomes 3:10am
 
         mScheduleInfo.days = new int[] {getTodayDay(), getTodayDay(1)};
         mScheduleInfo.startHour = 22;
@@ -481,4 +514,11 @@
         cal.add(Calendar.DATE, offset);
         return cal.get(Calendar.DAY_OF_WEEK);
     }
+
+
+    private Calendar getDaylightSavingsDay() {
+        // the day before daylight savings in the US - March 9, 2019
+        Calendar daylightSavingsDay = new GregorianCalendar(2019, 2, 9);
+        return daylightSavingsDay;
+    }
 }
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 d580557..32e96a5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -438,8 +438,11 @@
         doReturn(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
                 .when(mActivity.mAppWindowToken).getOrientationIgnoreVisibility();
         mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-        mActivity.info.maxAspectRatio = 1;
+        mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = 1;
         ensureActivityConfiguration();
+        // The parent configuration doesn't change since the first resolved configuration, so the
+        // activity shouldn't be in the size compatibility mode.
+        assertFalse(mActivity.inSizeCompatMode());
 
         final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
         // Ensure the app bounds keep the declared aspect ratio.
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 822700f..1e00b30 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -31,6 +31,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
 import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
 import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
 import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
@@ -929,6 +930,16 @@
     }
 
     @Test
+    public void testWontFinishHomeStackImmediately() {
+        final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
+
+        // Home stack should not be destroyed immediately.
+        final ActivityRecord activity1 = finishCurrentActivity(homeStack);
+        assertEquals(FINISHING, activity1.getState());
+    }
+
+    @Test
     public void testFinishCurrentActivity() {
         // Create 2 activities on a new display.
         final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
index febb795..380f7c6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
@@ -22,12 +22,11 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
 
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
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 9bd9930..b1ffbbd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -24,9 +24,9 @@
 import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.platform.test.annotations.Presubmit;
 import android.view.WindowManager;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
new file mode 100644
index 0000000..fa0c384
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.graphics.GraphicBuffer;
+import android.graphics.PixelFormat;
+import android.platform.test.annotations.Presubmit;
+import android.view.Surface;
+import android.view.SurfaceControl;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Test class for {@link TaskSnapshotSurface}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTest:AppWindowThumbnailTest
+ *
+ */
+@SmallTest
+@Presubmit
+public class AppWindowThumbnailTest extends WindowTestsBase {
+    private AppWindowThumbnail buildThumbnail() {
+        final GraphicBuffer buffer = GraphicBuffer.create(1, 1, PixelFormat.RGBA_8888,
+                GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
+        final AppWindowToken mockAwt = mock(AppWindowToken.class);
+        when(mockAwt.getPendingTransaction()).thenReturn(new StubTransaction());
+        when(mockAwt.makeSurface()).thenReturn(new MockSurfaceControlBuilder());
+        return new AppWindowThumbnail(new StubTransaction(), mockAwt,
+                buffer, false, mock(Surface.class), mock(SurfaceAnimator.class));
+    }
+
+    @Test
+    public void testDestroy_nullsSurface() {
+        final AppWindowThumbnail t = buildThumbnail();
+        assertNotNull(t.getSurfaceControl());
+        t.destroy();
+        assertNull(t.getSurfaceControl());
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
index 85b2f7b..5cef38d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
@@ -38,6 +38,7 @@
 import android.content.res.Resources;
 import android.graphics.Matrix;
 import android.graphics.RectF;
+import android.os.Binder;
 import android.os.IBinder;
 import android.testing.TestableResources;
 import android.util.Pair;
@@ -86,7 +87,6 @@
                 Math.min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * DENSITY_DEFAULT / DISPLAY_DENSITY;
         mDisplayContent.getDisplayRotation().configure(
                 DISPLAY_WIDTH, DISPLAY_HEIGHT, shortSizeDp, longSizeDp);
-        mDisplayPolicy.configure(DISPLAY_WIDTH, DISPLAY_HEIGHT, shortSizeDp);
         mDisplayPolicy.onConfigurationChanged();
 
         mStatusBarWindow.mAttrs.gravity = Gravity.TOP;
@@ -99,7 +99,8 @@
     }
 
     void addWindow(WindowState win) {
-        mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, true /* hasStatusBarPermission */);
+        mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(),
+                Binder.getCallingUid());
         assertEquals(WindowManagerGlobal.ADD_OKAY,
                 mDisplayPolicy.prepareAddWindowLw(win, win.mAttrs));
         win.mHasSurface = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index 9a8a732..652ea7d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
 import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
 
@@ -40,7 +42,9 @@
 
 import android.app.WindowConfiguration;
 import android.platform.test.annotations.Presubmit;
+import android.util.Xml;
 import android.view.Display;
+import android.view.DisplayAddress;
 import android.view.DisplayInfo;
 import android.view.Surface;
 
@@ -53,14 +57,22 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.MockitoSession;
+import org.xmlpull.v1.XmlPullParser;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 
 /**
  * Tests for the {@link DisplayWindowSettings} class.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTests:DisplayWindowSettingsTests
+ *  atest WmTests:DisplayWindowSettingsTests
  */
 @SmallTest
 @Presubmit
@@ -69,12 +81,14 @@
     private static final File TEST_FOLDER = getInstrumentation().getTargetContext().getCacheDir();
     private DisplayWindowSettings mTarget;
 
-    DisplayInfo mPrivateDisplayInfo;
+    private DisplayInfo mPrivateDisplayInfo;
 
     private DisplayContent mPrimaryDisplay;
     private DisplayContent mSecondaryDisplay;
     private DisplayContent mPrivateDisplay;
 
+    private TestStorage mStorage;
+
     @Before
     public void setUp() throws Exception {
         deleteRecursively(TEST_FOLDER);
@@ -83,7 +97,8 @@
         mWm.setIsPc(false);
         mWm.setForceDesktopModeOnExternalDisplays(false);
 
-        mTarget = new DisplayWindowSettings(mWm, TEST_FOLDER);
+        mStorage = new TestStorage();
+        mTarget = new DisplayWindowSettings(mWm, mStorage);
 
         mPrimaryDisplay = mWm.getDefaultDisplayContentLocked();
         mSecondaryDisplay = mDisplayContent;
@@ -143,7 +158,7 @@
 
         mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
 
-        assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
+        assertEquals(WINDOWING_MODE_FREEFORM,
                 mPrimaryDisplay.getWindowingMode());
     }
 
@@ -185,7 +200,7 @@
 
         mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
 
-        assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
+        assertEquals(WINDOWING_MODE_FREEFORM,
                 mSecondaryDisplay.getWindowingMode());
     }
 
@@ -196,7 +211,7 @@
 
         mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
 
-        assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
+        assertEquals(WINDOWING_MODE_FREEFORM,
                 mSecondaryDisplay.getWindowingMode());
     }
 
@@ -474,6 +489,171 @@
         mockitoSession.finishMocking();
     }
 
+    @Test
+    public void testReadingDisplaySettingsFromStorage() {
+        final String displayIdentifier = mSecondaryDisplay.getDisplayInfo().uniqueId;
+        prepareDisplaySettings(displayIdentifier);
+
+        readAndAssertDisplaySettings(mPrimaryDisplay);
+    }
+
+    @Test
+    public void testReadingDisplaySettingsFromStorage_LegacyDisplayId() {
+        final String displayIdentifier = mPrimaryDisplay.getDisplayInfo().name;
+        prepareDisplaySettings(displayIdentifier);
+
+        readAndAssertDisplaySettings(mPrimaryDisplay);
+    }
+
+    @Test
+    public void testReadingDisplaySettingsFromStorage_LegacyDisplayId_UpdateAfterAccess()
+            throws Exception {
+        // Store display settings with legacy display identifier.
+        final String displayIdentifier = mPrimaryDisplay.getDisplayInfo().name;
+        prepareDisplaySettings(displayIdentifier);
+
+        // Update settings with new value, should trigger write to injector.
+        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
+        settings.setRemoveContentModeLocked(mPrimaryDisplay, REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY);
+        assertEquals("Settings value must be updated", REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY,
+                settings.getRemoveContentModeLocked(mPrimaryDisplay));
+        assertTrue(mStorage.wasWriteSuccessful());
+
+        // Verify that display identifier was updated.
+        final String newDisplayIdentifier = getStoredDisplayAttributeValue("name");
+        assertEquals("Display identifier must be updated to use uniqueId",
+                mPrimaryDisplay.getDisplayInfo().uniqueId, newDisplayIdentifier);
+    }
+
+    @Test
+    public void testReadingDisplaySettingsFromStorage_UsePortAsId() {
+        final DisplayAddress.Physical displayAddress = DisplayAddress.fromPhysicalDisplayId(123456);
+        mPrimaryDisplay.getDisplayInfo().address = displayAddress;
+
+        final String displayIdentifier = "port:" + displayAddress.getPort();
+        prepareDisplaySettings(displayIdentifier, true /* usePortAsId */);
+
+        readAndAssertDisplaySettings(mPrimaryDisplay);
+    }
+
+    @Test
+    public void testReadingDisplaySettingsFromStorage_UsePortAsId_IncorrectAddress() {
+        final String displayIdentifier = mPrimaryDisplay.getDisplayInfo().uniqueId;
+        prepareDisplaySettings(displayIdentifier, true /* usePortAsId */);
+
+        mPrimaryDisplay.getDisplayInfo().address = DisplayAddress.fromPhysicalDisplayId(123456);
+
+        // Verify that the entry is not matched and default settings are returned instead.
+        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm);
+        assertNotEquals("Default setting must be returned for new entry",
+                WINDOWING_MODE_PINNED, settings.getWindowingModeLocked(mPrimaryDisplay));
+    }
+
+    @Test
+    public void testWritingDisplaySettingsToStorage() throws Exception {
+        // Write some settings to storage.
+        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
+        settings.setShouldShowSystemDecorsLocked(mSecondaryDisplay, true);
+        settings.setShouldShowImeLocked(mSecondaryDisplay, true);
+        assertTrue(mStorage.wasWriteSuccessful());
+
+        // Verify that settings were stored correctly.
+        assertEquals("Attribute value must be stored", mSecondaryDisplay.getDisplayInfo().uniqueId,
+                getStoredDisplayAttributeValue("name"));
+        assertEquals("Attribute value must be stored", "true",
+                getStoredDisplayAttributeValue("shouldShowSystemDecors"));
+        assertEquals("Attribute value must be stored", "true",
+                getStoredDisplayAttributeValue("shouldShowIme"));
+    }
+
+    @Test
+    public void testWritingDisplaySettingsToStorage_UsePortAsId() throws Exception {
+        // Store config to use port as identifier.
+        final DisplayAddress.Physical displayAddress = DisplayAddress.fromPhysicalDisplayId(123456);
+        mSecondaryDisplay.getDisplayInfo().address = displayAddress;
+        prepareDisplaySettings(null /* displayIdentifier */, true /* usePortAsId */);
+
+        // Write some settings.
+        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
+        settings.setShouldShowSystemDecorsLocked(mSecondaryDisplay, true);
+        settings.setShouldShowImeLocked(mSecondaryDisplay, true);
+        assertTrue(mStorage.wasWriteSuccessful());
+
+        // Verify that settings were stored correctly.
+        assertEquals("Attribute value must be stored", "port:" + displayAddress.getPort(),
+                getStoredDisplayAttributeValue("name"));
+        assertEquals("Attribute value must be stored", "true",
+                getStoredDisplayAttributeValue("shouldShowSystemDecors"));
+        assertEquals("Attribute value must be stored", "true",
+                getStoredDisplayAttributeValue("shouldShowIme"));
+    }
+
+    /**
+     * Prepares display settings and stores in {@link #mStorage}. Uses provided display identifier
+     * and stores windowingMode=WINDOWING_MODE_PINNED.
+     */
+    private void prepareDisplaySettings(String displayIdentifier) {
+        prepareDisplaySettings(displayIdentifier, false /* usePortAsId */);
+    }
+
+    private void prepareDisplaySettings(String displayIdentifier, boolean usePortAsId) {
+        String contents = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<display-settings>\n";
+        if (usePortAsId) {
+            contents += "  <config identifier=\"1\"/>\n";
+        }
+        if (displayIdentifier != null) {
+            contents += "  <display\n"
+                    + "    name=\"" + displayIdentifier + "\"\n"
+                    + "    windowingMode=\"" + WINDOWING_MODE_PINNED + "\"/>\n";
+        }
+        contents += "</display-settings>\n";
+
+        final InputStream is = new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
+        mStorage.setReadStream(is);
+    }
+
+    private void readAndAssertDisplaySettings(DisplayContent displayContent) {
+        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
+        assertEquals("Stored setting must be read",
+                WINDOWING_MODE_PINNED, settings.getWindowingModeLocked(displayContent));
+        assertEquals("Not stored setting must be set to default value",
+                REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY,
+                settings.getRemoveContentModeLocked(displayContent));
+    }
+
+    private String getStoredDisplayAttributeValue(String attr) throws Exception {
+        try (InputStream stream = mStorage.openRead()) {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(stream, StandardCharsets.UTF_8.name());
+            int type;
+            while ((type = parser.next()) != XmlPullParser.START_TAG
+                    && type != XmlPullParser.END_DOCUMENT) {
+                // Do nothing.
+            }
+
+            if (type != XmlPullParser.START_TAG) {
+                throw new IllegalStateException("no start tag found");
+            }
+
+            int outerDepth = parser.getDepth();
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                    continue;
+                }
+
+                String tagName = parser.getName();
+                if (tagName.equals("display")) {
+                    return parser.getAttributeValue(null, attr);
+                }
+            }
+        } finally {
+            mStorage.closeRead();
+        }
+        return null;
+    }
+
     private static void assertOverscan(DisplayContent display, int left, int top, int right,
             int bottom) {
         final DisplayInfo info = display.getDisplayInfo();
@@ -490,7 +670,11 @@
      * path that also means the previous state must be written correctly.
      */
     private void applySettingsToDisplayByNewInstance(DisplayContent display) {
-        new DisplayWindowSettings(mWm, TEST_FOLDER).applySettingsToDisplayLocked(display);
+        // Assert that prior write completed successfully.
+        assertTrue(mStorage.wasWriteSuccessful());
+
+        // Read and apply settings.
+        new DisplayWindowSettings(mWm, mStorage).applySettingsToDisplayLocked(display);
     }
 
     private static boolean deleteRecursively(File file) {
@@ -506,4 +690,81 @@
         }
         return fullyDeleted;
     }
+
+    /** In-memory storage implementation. */
+    public class TestStorage implements DisplayWindowSettings.SettingPersister {
+        private InputStream mReadStream;
+        private ByteArrayOutputStream mWriteStream;
+
+        private boolean mWasSuccessful;
+
+        /**
+         * Returns input stream for reading. By default tries forward the output stream if previous
+         * write was successful.
+         * @see #closeRead()
+         */
+        @Override
+        public InputStream openRead() throws FileNotFoundException {
+            if (mReadStream == null && mWasSuccessful) {
+                mReadStream = new ByteArrayInputStream(mWriteStream.toByteArray());
+            }
+            if (mReadStream == null) {
+                throw new FileNotFoundException();
+            }
+            if (mReadStream.markSupported()) {
+                mReadStream.mark(Integer.MAX_VALUE);
+            }
+            return mReadStream;
+        }
+
+        /** Must be called after each {@link #openRead} to reset the position in the stream. */
+        void closeRead() throws IOException {
+            if (mReadStream == null) {
+                throw new FileNotFoundException();
+            }
+            if (mReadStream.markSupported()) {
+                mReadStream.reset();
+            }
+            mReadStream = null;
+        }
+
+        /**
+         * Creates new or resets existing output stream for write. Automatically closes previous
+         * read stream, since following reads should happen based on this new write.
+         */
+        @Override
+        public OutputStream startWrite() throws IOException {
+            if (mWriteStream == null) {
+                mWriteStream = new ByteArrayOutputStream();
+            } else {
+                mWriteStream.reset();
+            }
+            if (mReadStream != null) {
+                closeRead();
+            }
+            return mWriteStream;
+        }
+
+        @Override
+        public void finishWrite(OutputStream os, boolean success) {
+            mWasSuccessful = success;
+            try {
+                os.close();
+            } catch (IOException e) {
+                // This method can't throw IOException since the super implementation doesn't, so
+                // we just wrap it in a RuntimeException so we end up crashing the test all the
+                // same.
+                throw new RuntimeException(e);
+            }
+        }
+
+        /** Override the read stream of the injector. By default it uses current write stream. */
+        private void setReadStream(InputStream is) {
+            mReadStream = is;
+        }
+
+        private boolean wasWriteSuccessful() {
+            return mWasSuccessful;
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index a166444..4e906bc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -18,11 +18,10 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertSame;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import android.os.SystemClock;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 08e6ce4..af04858 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -625,7 +625,7 @@
         // excludedTask is not trimmed.
         assertTrimmed(mTasks.get(0));
 
-        mRecentTasks.removeAllVisibleTasks();
+        mRecentTasks.removeAllVisibleTasks(TEST_USER_0_ID);
 
         // Only visible tasks removed.
         assertTrimmed(mTasks.get(0), mTasks.get(1), mTasks.get(2), mTasks.get(3));
@@ -849,11 +849,31 @@
         mRecentTasks.add(t7);
 
         // Remove all the visible tasks and ensure that they are removed
-        mRecentTasks.removeAllVisibleTasks();
+        mRecentTasks.removeAllVisibleTasks(TEST_USER_0_ID);
         assertTrimmed(t1, t2, t3, t4, t5, t6, t7);
     }
 
     @Test
+    public void testRemoveAllVisibleTasksPerUser() {
+        mRecentTasks.setParameters(-1 /* min */, 3 /* max */, 100 /* ms */);
+
+        // Create a visible task per user
+        TaskRecord t1 = createTaskBuilder(".Task1")
+                .setUserId(TEST_USER_0_ID)
+                .build();
+        mRecentTasks.add(t1);
+
+        TaskRecord t2 = createTaskBuilder(".Task1")
+                .setUserId(TEST_USER_1_ID)
+                .build();
+        mRecentTasks.add(t2);
+
+        // Remove all the visible tasks and ensure that they are removed
+        mRecentTasks.removeAllVisibleTasks(TEST_USER_0_ID);
+        assertTrimmed(t1);
+    }
+
+    @Test
     public void testNotRestoreRecentTaskApis() {
         final TaskRecord task = createTaskBuilder(".Task").build();
         final int taskId = task.taskId;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 88ac96d..4f03726 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -181,15 +181,10 @@
     public void testDeferFinish() {
 
         // Start animation
-        mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec,
-                true /* hidden */);
-        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
-                OnAnimationFinishedCallback.class);
-        assertAnimating(mDeferFinishAnimatable);
-        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+        final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);
 
         // Finish the animation but then make sure we are deferring.
-        callbackCaptor.getValue().onAnimationFinished(mSpec);
+        onFinishedCallback.onAnimationFinished(mSpec);
         assertAnimating(mDeferFinishAnimatable);
 
         // Now end defer finishing.
@@ -199,6 +194,36 @@
         verify(mTransaction).remove(eq(mDeferFinishAnimatable.mLeash));
     }
 
+    @Test
+    public void testDeferFinishDoNotFinishNextAnimation() {
+        // Start the first animation.
+        final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);
+        onFinishedCallback.onAnimationFinished(mSpec);
+        // The callback is the resetAndInvokeFinish in {@link SurfaceAnimator#getFinishedCallback}.
+        final Runnable firstDeferFinishCallback = mDeferFinishAnimatable.mEndDeferFinishCallback;
+
+        // Start the second animation.
+        mDeferFinishAnimatable.mSurfaceAnimator.cancelAnimation();
+        startDeferFinishAnimatable(mSpec2);
+        mDeferFinishAnimatable.mFinishedCallbackCalled = false;
+
+        // Simulate the first deferred callback is executed from
+        // {@link AnimatingAppWindowTokenRegistry#endDeferringFinished}.
+        firstDeferFinishCallback.run();
+        // The second animation should not be finished.
+        assertFalse(mDeferFinishAnimatable.mFinishedCallbackCalled);
+    }
+
+    private OnAnimationFinishedCallback startDeferFinishAnimatable(AnimationAdapter anim) {
+        mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, anim,
+                true /* hidden */);
+        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
+                OnAnimationFinishedCallback.class);
+        assertAnimating(mDeferFinishAnimatable);
+        verify(anim).startAnimation(any(), any(), callbackCaptor.capture());
+        return callbackCaptor.getValue();
+    }
+
     private void assertAnimating(MyAnimatable animatable) {
         assertTrue(animatable.mSurfaceAnimator.isAnimating());
         assertNotNull(animatable.mSurfaceAnimator.getAnimation());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
index 00e479f..7cfe71e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -32,6 +32,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.InputChannel;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
@@ -60,10 +61,9 @@
         mWindow.mInputChannel = new InputChannel();
         synchronized (mWm.mGlobalLock) {
             mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
+            spyOn(mDisplayContent);
+            doReturn(mock(InputMonitor.class)).when(mDisplayContent).getInputMonitor();
         }
-
-        spyOn(mDisplayContent);
-        doReturn(mock(InputMonitor.class)).when(mDisplayContent).getInputMonitor();
     }
 
     @Test
@@ -88,6 +88,7 @@
         assertNull(mTarget.getDragWindowHandleLocked());
     }
 
+    @FlakyTest(bugId = 129331490)
     @Test
     public void testHandleTapOutsideTask() {
         synchronized (mWm.mGlobalLock) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
index 1c6afd54..3bedabc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
@@ -18,8 +18,8 @@
 
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
 import android.platform.test.annotations.Presubmit;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 792e8a6..113f3c8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -23,7 +23,7 @@
 import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_APP_THEME;
 import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_REAL;
 
-import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertEquals;
 
 import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
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 8854ede..a91daf0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -16,9 +16,8 @@
 
 package com.android.server.wm;
 
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertTrue;
 
-import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index 8feed7f..a783a40 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -66,7 +66,7 @@
     public final ArrayMap<String, UsageStats> packageStats = new ArrayMap<>();
     public final ArrayMap<Configuration, ConfigurationStats> configurations = new ArrayMap<>();
     public Configuration activeConfiguration;
-    public EventList events = new EventList();
+    public final EventList events = new EventList();
 
     // A string cache. This is important as when we're parsing XML files, we don't want to
     // keep hundreds of strings that have the same contents. We will read the string
@@ -82,7 +82,7 @@
 
         public void commitTime(long timeStamp) {
             if (curStartTime != 0) {
-                duration += timeStamp - duration;
+                duration += timeStamp - curStartTime;
                 curStartTime = 0;
             }
         }
@@ -305,7 +305,9 @@
             UsageStats usageStats = getOrCreateUsageStats(packageName);
             usageStats.update(className, timeStamp, eventType, instanceId);
         }
-        endTime = timeStamp;
+        if (timeStamp > endTime) {
+            endTime = timeStamp;
+        }
     }
 
     /**
@@ -328,6 +330,9 @@
             event.mNotificationChannelId = getCachedStringRef(event.mNotificationChannelId);
         }
         events.insert(event);
+        if (event.mTimeStamp > endTime) {
+            endTime = event.mTimeStamp;
+        }
     }
 
     void updateChooserCounts(String packageName, String category, String action) {
@@ -360,8 +365,9 @@
             configStats.mActivationCount += 1;
             activeConfiguration = configStats.mConfiguration;
         }
-
-        endTime = timeStamp;
+        if (timeStamp > endTime) {
+            endTime = timeStamp;
+        }
     }
 
     void incrementAppLaunchCount(String packageName) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 485a79d..c55bb3c 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -1166,7 +1166,8 @@
         if (beingRestored == null) return null;
         beingRestored.activeConfiguration = onDevice.activeConfiguration;
         beingRestored.configurations.putAll(onDevice.configurations);
-        beingRestored.events = onDevice.events;
+        beingRestored.events.clear();
+        beingRestored.events.merge(onDevice.events);
         return beingRestored;
     }
 
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 9498e16..26bfcc9 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -334,7 +334,7 @@
                 final IntervalStats diskStats = mDatabase.getLatestUsageStats(
                         INTERVAL_DAILY);
                 StringBuilder sb = new StringBuilder(256);
-                sb.append("Last 24 hours of UsageStats missing! timeRange : ");
+                sb.append("Recent UsageStats missing! timeRange : ");
                 sb.append(beginTime);
                 sb.append(", ");
                 sb.append(endTime);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index f1e2281..79e6851 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -842,7 +842,7 @@
                             && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST)
                             && status.isRoleCombinationSupported(POWER_ROLE_SOURCE,
                             DATA_ROLE_DEVICE)
-                            && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST);
+                            && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_DEVICE);
 
                     args.recycle();
                     updateUsbNotification(false);
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 96e12ce..749258e 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -965,7 +965,6 @@
 
     private void handlePortLocked(PortInfo portInfo, IndentingPrintWriter pw) {
         sendPortChangedBroadcastLocked(portInfo);
-        enableContaminantDetectionIfNeeded(portInfo, pw);
         logToStatsd(portInfo, pw);
         updateContaminantNotification();
     }
@@ -977,6 +976,7 @@
 
     private void handlePortChangedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
         logAndPrint(Log.INFO, pw, "USB port changed: " + portInfo);
+        enableContaminantDetectionIfNeeded(portInfo, pw);
         handlePortLocked(portInfo, pw);
     }
 
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 3d7cbb5..94352b2 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -889,7 +889,7 @@
         public void onCallStateChanged(int state, String arg1) {
             if (DBG) Slog.d(TAG, "onCallStateChanged: " + state);
             synchronized (mLock) {
-                onCallStateChangedLocked(TelephonyManager.CALL_STATE_IDLE != state);
+                onCallStateChangedLocked(TelephonyManager.CALL_STATE_OFFHOOK == state);
             }
         }
     }
@@ -924,7 +924,7 @@
         long token = Binder.clearCallingIdentity();
         try {
             // Get the current call state synchronously for the first recognition.
-            mCallActive = mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
+            mCallActive = mTelephonyManager.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK;
 
             // Register for call state changes when the first call to start recognition occurs.
             mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
diff --git a/startop/iorap/tests/Android.bp b/startop/iorap/tests/Android.bp
index 4359978..3e60ad4 100644
--- a/startop/iorap/tests/Android.bp
+++ b/startop/iorap/tests/Android.bp
@@ -16,32 +16,48 @@
 java_library {
     name: "libiorap-java-test-lib",
     srcs: ["src/**/*.kt"],
-
     static_libs: [
-      // Non-test dependencies
-
-      // library under test
-      "services.startop.iorap",
-      // need the system_server code to be on the classpath,
-      "services.core",
-
-      // Test Dependencies
-
-      // test android dependencies
-      "platform-test-annotations",
-      "androidx.test.rules",
-      // test framework dependencies
-      "mockito-target-inline-minus-junit4",
-      // "mockito-target-minus-junit4",
+        // Non-test dependencies
+        // library under test
+        "services.startop.iorap",
+        // need the system_server code to be on the classpath,
+        "services.core",
+        // Test Dependencies
+        // test android dependencies
+        "platform-test-annotations",
+        "androidx.test.rules",
+        // test framework dependencies
+        "mockito-target-inline-minus-junit4",
+        // "mockito-target-minus-junit4",
         // Mockito also requires JNI (see Android.mk)
         // and android:debuggable=true (see AndroidManifest.xml)
-      "truth-prebuilt",
+        "truth-prebuilt",
     ],
-
     // sdk_version: "current",
     // certificate: "platform",
-
-    libs: ["android.test.base", "android.test.runner"],
-
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
     // test_suites: ["device-tests"],
 }
+
+android_test {
+    name: "libiorap-java-tests",
+    dxflags: ["--multi-dex"],
+    test_suites: ["device-tests"],
+    static_libs: ["libiorap-java-test-lib"],
+    compile_multilib: "both",
+    jni_libs: [
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+        "libmultiplejvmtiagentsinterferenceagent",
+    ],
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+    // Use private APIs
+    certificate: "platform",
+    platform_apis: true,
+}
diff --git a/startop/iorap/tests/Android.mk b/startop/iorap/tests/Android.mk
deleted file mode 100644
index fa8c8b5..0000000
--- a/startop/iorap/tests/Android.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# android_test does not support JNI libraries
-# TODO: once b/80095087 is fixed, rewrite this back to android_test
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_JACK_FLAGS := --multi-dex native
-LOCAL_DX_FLAGS := --multi-dex
-
-LOCAL_PACKAGE_NAME := libiorap-java-tests
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    libiorap-java-test-lib
-
-LOCAL_MULTILIB := both
-
-LOCAL_JNI_SHARED_LIBRARIES := \
-    libdexmakerjvmtiagent \
-    libstaticjvmtiagent \
-    libmultiplejvmtiagentsinterferenceagent
-
-LOCAL_JAVA_LIBRARIES := \
-    android.test.base \
-    android.test.runner
-
-# Use private APIs
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-# Disable presubmit test until it works with disabled iorap by default.
-LOCAL_PRESUBMIT_DISABLED := true
-
-include $(BUILD_PACKAGE)
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index c05a346..1822cee 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -552,7 +552,6 @@
         private final Bundle mExtras;
         private final Bundle mIntentExtras;
         private final long mCreationTimeMillis;
-        private final CallIdentification mCallIdentification;
         private final @CallDirection int mCallDirection;
 
         /**
@@ -738,8 +737,6 @@
          * The display name for the caller.
          * <p>
          * This is the name as reported by the {@link ConnectionService} associated with this call.
-         * The name reported by a {@link CallScreeningService} can be retrieved using
-         * {@link CallIdentification#getName()}.
          *
          * @return The display name for the caller.
          */
@@ -857,23 +854,6 @@
         }
 
         /**
-         * Returns {@link CallIdentification} information provided by a
-         * {@link CallScreeningService} for this call.
-         * <p>
-         * {@link InCallService} implementations should display the {@link CallIdentification} for
-         * calls.  The name of the call screening service is provided in
-         * {@link CallIdentification#getCallScreeningAppName()} and should be used to attribute the
-         * call identification information.
-         *
-         * @return The {@link CallIdentification} if it was provided by a
-         * {@link CallScreeningService}, or {@code null} if no {@link CallScreeningService} has
-         * provided {@link CallIdentification} information for the call.
-         */
-        public @Nullable CallIdentification getCallIdentification() {
-            return mCallIdentification;
-        }
-
-        /**
          * Indicates whether the call is an incoming or outgoing call.
          * @return The call's direction.
          */
@@ -902,7 +882,6 @@
                         areBundlesEqual(mExtras, d.mExtras) &&
                         areBundlesEqual(mIntentExtras, d.mIntentExtras) &&
                         Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) &&
-                        Objects.equals(mCallIdentification, d.mCallIdentification) &&
                         Objects.equals(mCallDirection, d.mCallDirection);
             }
             return false;
@@ -925,7 +904,6 @@
                             mExtras,
                             mIntentExtras,
                             mCreationTimeMillis,
-                            mCallIdentification,
                             mCallDirection);
         }
 
@@ -947,7 +925,6 @@
                 Bundle extras,
                 Bundle intentExtras,
                 long creationTimeMillis,
-                CallIdentification callIdentification,
                 int callDirection) {
             mTelecomCallId = telecomCallId;
             mHandle = handle;
@@ -965,7 +942,6 @@
             mExtras = extras;
             mIntentExtras = intentExtras;
             mCreationTimeMillis = creationTimeMillis;
-            mCallIdentification = callIdentification;
             mCallDirection = callDirection;
         }
 
@@ -988,7 +964,6 @@
                     parcelableCall.getExtras(),
                     parcelableCall.getIntentExtras(),
                     parcelableCall.getCreationTimeMillis(),
-                    parcelableCall.getCallIdentification(),
                     parcelableCall.getCallDirection());
         }
 
diff --git a/telecomm/java/android/telecom/CallIdentification.java b/telecomm/java/android/telecom/CallIdentification.java
deleted file mode 100644
index 745affd..0000000
--- a/telecomm/java/android/telecom/CallIdentification.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telecom;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.pm.ApplicationInfo;
-import android.graphics.drawable.Icon;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Encapsulates information about an incoming or outgoing {@link Call} provided by a
- * {@link CallScreeningService}.
- * <p>
- * Call identified information is consumed by the {@link InCallService dialer} app to provide the
- * user with more information about a call.  This can include information such as the name of the
- * caller, address, etc.  Call identification information is persisted to the
- * {@link android.provider.CallLog}.
- */
-public final class CallIdentification implements Parcelable {
-    /**
-     * Builder for {@link CallIdentification} instances.
-     * <p>
-     * A {@link CallScreeningService} uses this class to create new instances of
-     * {@link CallIdentification} for a screened call.
-     */
-    public final static class Builder {
-        private CharSequence mName;
-        private CharSequence mDescription;
-        private CharSequence mDetails;
-        private Icon mPhoto;
-        private int mNuisanceConfidence = CallIdentification.CONFIDENCE_UNKNOWN;
-        private String mPackageName;
-        private CharSequence mAppName;
-
-        /**
-         * Default builder constructor.
-         */
-        public Builder() {
-            // Default constructor
-        }
-
-        /**
-         * Create instance of call identification with specified package/app name.
-         *
-         * @param callIdPackageName The package name.
-         * @param callIdAppName The app name.
-         * @hide
-         */
-        public Builder(@NonNull String callIdPackageName, @NonNull CharSequence callIdAppName) {
-            mPackageName = callIdPackageName;
-            mAppName = callIdAppName;
-        }
-
-        /**
-         * Sets the name associated with the {@link CallIdentification} being built.
-         * <p>
-         * Could be a business name, for example.
-         *
-         * @param name The name associated with the call, or {@code null} if none is provided.
-         * @return Builder instance.
-         */
-        public @NonNull Builder setName(@Nullable CharSequence name) {
-            mName = name;
-            return this;
-        }
-
-        /**
-         * Sets the description associated with the {@link CallIdentification} being built.
-         * <p>
-         * A description of the call as identified by a {@link CallScreeningService}.  The
-         * description is typically presented by Dialer apps after the
-         * {@link CallIdentification#getName() name} to provide a short piece of relevant
-         * information about the call.  This could include a location, address, or a message
-         * regarding the potential nature of the call (e.g. potential telemarketer).
-         *
-         * @param description The call description, or {@code null} if none is provided.
-         * @return Builder instance.
-         */
-        public @NonNull Builder setDescription(@Nullable CharSequence description) {
-            mDescription = description;
-            return this;
-        }
-
-        /**
-         * Sets the details associated with the {@link CallIdentification} being built.
-         * <p>
-         * The details is typically presented by Dialer apps after the
-         * {@link CallIdentification#getName() name} and
-         * {@link CallIdentification#getDescription() description} to provide further clarifying
-         * information about the call. This could include, for example, the opening hours of a
-         * business, or a stats about the number of times a call has been reported as spam.
-         *
-         * @param details The call details, or {@code null} if none is provided.
-         * @return Builder instance.
-         */
-
-        public @NonNull Builder setDetails(@Nullable CharSequence details) {
-            mDetails = details;
-            return this;
-        }
-
-        /**
-         * Sets the photo associated with the {@link CallIdentification} being built.
-         * <p>
-         * This could be, for example, a business logo, or a photo of the caller.
-         *
-         * @param photo The photo associated with the call, or {@code null} if none was provided.
-         * @return Builder instance.
-         */
-        public @NonNull Builder setPhoto(@Nullable Icon photo) {
-            mPhoto = photo;
-            return this;
-        }
-
-        /**
-         * Sets the nuisance confidence with the {@link CallIdentification} being built.
-         * <p>
-         * This can be used to specify how confident the {@link CallScreeningService} is that a call
-         * is or is not a nuisance call.
-         *
-         * @param nuisanceConfidence The nuisance confidence.
-         * @return The builder.
-         */
-        public @NonNull Builder setNuisanceConfidence(@NuisanceConfidence int nuisanceConfidence) {
-            mNuisanceConfidence = nuisanceConfidence;
-            return this;
-        }
-
-        /**
-         * Creates a new instance of {@link CallIdentification} based on the parameters set in this
-         * builder.
-         *
-         * @return {@link CallIdentification} instance.
-         */
-        public @NonNull CallIdentification build() {
-            return new CallIdentification(mName, mDescription, mDetails, mPhoto,
-                    mNuisanceConfidence, mPackageName, mAppName);
-        }
-    }
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(
-            prefix = { "CONFIDENCE_" },
-            value = {CONFIDENCE_NUISANCE, CONFIDENCE_LIKELY_NUISANCE, CONFIDENCE_UNKNOWN,
-                    CONFIDENCE_LIKELY_NOT_NUISANCE, CONFIDENCE_NOT_NUISANCE})
-    public @interface NuisanceConfidence {}
-
-    /**
-     * Call has been identified as a nuisance call.
-     * <p>
-     * Returned from {@link #getNuisanceConfidence()} to indicate that a
-     * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
-     * nuisance call.
-     */
-    public static final int CONFIDENCE_NUISANCE = 2;
-
-    /**
-     * Call has been identified as a likely nuisance call.
-     * <p>
-     * Returned from {@link #getNuisanceConfidence()} to indicate that a
-     * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
-     * nuisance call.
-     */
-    public static final int CONFIDENCE_LIKELY_NUISANCE = 1;
-
-    /**
-     * Call could not be classified as nuisance or non-nuisance.
-     * <p>
-     * Returned from {@link #getNuisanceConfidence()} to indicate that a
-     * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
-     * nuisance call.
-     */
-    public static final int CONFIDENCE_UNKNOWN = 0;
-
-    /**
-     * Call has been identified as not likely to be a nuisance call.
-     * <p>
-     * Returned from {@link #getNuisanceConfidence()} to indicate that a
-     * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
-     * nuisance call.
-     */
-    public static final int CONFIDENCE_LIKELY_NOT_NUISANCE = -1;
-
-    /**
-     * Call has been identified as not a nuisance call.
-     * <p>
-     * Returned from {@link #getNuisanceConfidence()} to indicate that a
-     * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
-     * nuisance call.
-     */
-    public static final int CONFIDENCE_NOT_NUISANCE = -2;
-
-    /**
-     * Default constructor for {@link CallIdentification}.
-     *
-     * @param name The name.
-     * @param description The description.
-     * @param details The details.
-     * @param photo The photo.
-     * @param nuisanceConfidence Confidence that this is a nuisance call.
-     * @hide
-     */
-    private CallIdentification(@Nullable String name, @Nullable String description,
-            @Nullable String details, @Nullable Icon photo,
-            @NuisanceConfidence int nuisanceConfidence) {
-        this(name, description, details, photo, nuisanceConfidence, null, null);
-    }
-
-    /**
-     * Default constructor for {@link CallIdentification}.
-     *
-     * @param name The name.
-     * @param description The description.
-     * @param details The details.
-     * @param photo The photo.
-     * @param nuisanceConfidence Confidence that this is a nuisance call.
-     * @param callScreeningPackageName Package name of the {@link CallScreeningService} which
-     *                                 provided the call identification.
-     * @param callScreeningAppName App name of the {@link CallScreeningService} which provided the
-     *                             call identification.
-     * @hide
-     */
-    private CallIdentification(@Nullable CharSequence name, @Nullable CharSequence description,
-            @Nullable CharSequence details, @Nullable Icon photo,
-            @NuisanceConfidence int nuisanceConfidence, @NonNull String callScreeningPackageName,
-            @NonNull CharSequence callScreeningAppName) {
-        mName = name;
-        mDescription = description;
-        mDetails = details;
-        mPhoto = photo;
-        mNuisanceConfidence = nuisanceConfidence;
-        mCallScreeningAppName = callScreeningAppName;
-        mCallScreeningPackageName = callScreeningPackageName;
-    }
-
-    private CharSequence mName;
-    private CharSequence mDescription;
-    private CharSequence mDetails;
-    private Icon mPhoto;
-    private int mNuisanceConfidence;
-    private String mCallScreeningPackageName;
-    private CharSequence mCallScreeningAppName;
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int i) {
-        parcel.writeCharSequence(mName);
-        parcel.writeCharSequence(mDescription);
-        parcel.writeCharSequence(mDetails);
-        parcel.writeParcelable(mPhoto, 0);
-        parcel.writeInt(mNuisanceConfidence);
-        parcel.writeString(mCallScreeningPackageName);
-        parcel.writeCharSequence(mCallScreeningAppName);
-    }
-
-    /**
-     * Responsible for creating CallIdentification objects for deserialized Parcels.
-     */
-    public static final @android.annotation.NonNull Parcelable.Creator<CallIdentification> CREATOR =
-            new Parcelable.Creator<CallIdentification> () {
-
-                @Override
-                public CallIdentification createFromParcel(Parcel source) {
-                    CharSequence name = source.readCharSequence();
-                    CharSequence description = source.readCharSequence();
-                    CharSequence details = source.readCharSequence();
-                    Icon photo = source.readParcelable(ClassLoader.getSystemClassLoader());
-                    int nuisanceConfidence = source.readInt();
-                    String callScreeningPackageName = source.readString();
-                    CharSequence callScreeningAppName = source.readCharSequence();
-                    return new CallIdentification(name, description, details, photo,
-                            nuisanceConfidence, callScreeningPackageName, callScreeningAppName);
-                }
-
-                @Override
-                public CallIdentification[] newArray(int size) {
-                    return new CallIdentification[size];
-                }
-            };
-
-    /**
-     * The name associated with the number.
-     * <p>
-     * The name of the call as identified by a {@link CallScreeningService}.  Could be a business
-     * name, for example.
-     *
-     * @return The name associated with the number, or {@code null} if none was provided.
-     */
-    public final @Nullable CharSequence getName() {
-        return mName;
-    }
-
-    /**
-     * Description of the call.
-     * <p>
-     * A description of the call as identified by a {@link CallScreeningService}.  The description
-     * is typically presented by Dialer apps after the {@link #getName() name} to provide a short
-     * piece of relevant information about the call.  This could include a location, address, or a
-     * message regarding the potential nature of the call (e.g. potential telemarketer).
-     *
-     * @return The call description, or {@code null} if none was provided.
-     */
-    public final @Nullable CharSequence getDescription() {
-        return mDescription;
-    }
-
-    /**
-     * Details of the call.
-     * <p>
-     * Details of the call as identified by a {@link CallScreeningService}.  The details
-     * are typically presented by Dialer apps after the {@link #getName() name} and
-     * {@link #getDescription() description} to provide further clarifying information about the
-     * call. This could include, for example, the opening hours of a business, or stats about
-     * the number of times a call has been reported as spam.
-     *
-     * @return The call details, or {@code null} if none was provided.
-     */
-    public final @Nullable CharSequence getDetails() {
-        return mDetails;
-    }
-
-    /**
-     * Photo associated with the call.
-     * <p>
-     * A photo associated with the call as identified by a {@link CallScreeningService}.  This
-     * could be, for example, a business logo, or a photo of the caller.
-     *
-     * @return The photo associated with the call, or {@code null} if none was provided.
-     */
-    public final @Nullable Icon getPhoto() {
-        return mPhoto;
-    }
-
-    /**
-     * Indicates the likelihood that this call is a nuisance call.
-     * <p>
-     * How likely the call is a nuisance call, as identified by a {@link CallScreeningService}.
-     *
-     * @return The nuisance confidence.
-     */
-    public final @NuisanceConfidence int getNuisanceConfidence() {
-        return mNuisanceConfidence;
-    }
-
-    /**
-     * The package name of the {@link CallScreeningService} which provided the
-     * {@link CallIdentification}.
-     * <p>
-     * A {@link CallScreeningService} may not set this property; it is set by the system.
-     * @return the package name
-     */
-    public final @NonNull String getCallScreeningPackageName() {
-        return mCallScreeningPackageName;
-    }
-
-    /**
-     * The {@link android.content.pm.PackageManager#getApplicationLabel(ApplicationInfo) name} of
-     * the {@link CallScreeningService} which provided the {@link CallIdentification}.
-     * <p>
-     * A {@link CallScreeningService} may not set this property; it is set by the system.
-     *
-     * @return The name of the app.
-     */
-    public final @NonNull CharSequence getCallScreeningAppName() {
-        return mCallScreeningAppName;
-    }
-
-    /**
-     * Set the package name of the {@link CallScreeningService} which provided this information.
-     *
-     * @param callScreeningPackageName The package name.
-     * @hide
-     */
-    public void setCallScreeningPackageName(@NonNull String callScreeningPackageName) {
-        mCallScreeningPackageName = callScreeningPackageName;
-    }
-
-    /**
-     * Set the app name of the {@link CallScreeningService} which provided this information.
-     *
-     * @param callScreeningAppName The app name.
-     * @hide
-     */
-    public void setCallScreeningAppName(@NonNull CharSequence callScreeningAppName) {
-        mCallScreeningAppName = callScreeningAppName;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        CallIdentification that = (CallIdentification) o;
-        // Note: mPhoto purposely omit as no good comparison exists.
-        return mNuisanceConfidence == that.mNuisanceConfidence
-                && Objects.equals(mName, that.mName)
-                && Objects.equals(mDescription, that.mDescription)
-                && Objects.equals(mDetails, that.mDetails)
-                && Objects.equals(mCallScreeningAppName, that.mCallScreeningAppName)
-                && Objects.equals(mCallScreeningPackageName, that.mCallScreeningPackageName);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mName, mDescription, mDetails, mPhoto, mNuisanceConfidence,
-                mCallScreeningAppName, mCallScreeningPackageName);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("[CallId mName=");
-        sb.append(Log.pii(mName));
-        sb.append(", mDesc=");
-        sb.append(mDescription);
-        sb.append(", mDet=");
-        sb.append(mDetails);
-        sb.append(", conf=");
-        sb.append(mNuisanceConfidence);
-        sb.append(", appName=");
-        sb.append(mCallScreeningAppName);
-        sb.append(", pkgName=");
-        sb.append(mCallScreeningPackageName);
-        return sb.toString();
-    }
-}
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index b1aece7..0e0406d 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -39,8 +39,8 @@
 /**
  * This service can be implemented by the default dialer (see
  * {@link TelecomManager#getDefaultDialerPackage()}) or a third party app to allow or disallow
- * incoming calls before they are shown to a user.  This service can also provide
- * {@link CallIdentification} information for calls.
+ * incoming calls before they are shown to a user. A {@link CallScreeningService} can also see
+ * outgoing calls for the purpose of providing caller ID services for those calls.
  * <p>
  * Below is an example manifest registration for a {@code CallScreeningService}.
  * <pre>
@@ -58,9 +58,9 @@
  * <ol>
  *     <li>Call blocking/screening - the service can choose which calls will ring on the user's
  *     device, and which will be silently sent to voicemail.</li>
- *     <li>Call identification - the service can optionally provide {@link CallIdentification}
- *     information about a {@link Call.Details call} which will be shown to the user in the
- *     Dialer app.</li>
+ *     <li>Call identification - services which provide call identification functionality can
+ *     display a user-interface of their choosing which contains identifying information for a call.
+ *     </li>
  * </ol>
  * <p>
  * <h2>Becoming the {@link CallScreeningService}</h2>
@@ -92,128 +92,6 @@
  * </pre>
  */
 public abstract class CallScreeningService extends Service {
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(
-            prefix = { "CALL_DURATION_" },
-            value = {CALL_DURATION_VERY_SHORT, CALL_DURATION_SHORT, CALL_DURATION_MEDIUM,
-                    CALL_DURATION_LONG})
-    public @interface CallDuration {}
-
-    /**
-     * Call duration reported with {@link #EXTRA_CALL_DURATION} to indicate to the
-     * {@link CallScreeningService} the duration of a call for which the user reported the nuisance
-     * status (see {@link TelecomManager#reportNuisanceCallStatus(Uri, boolean)}).  The
-     * {@link CallScreeningService} can use this as a signal for training nuisance detection
-     * algorithms.  The call duration is reported in coarse grained buckets to minimize exposure of
-     * identifying call log information to the {@link CallScreeningService}.
-     * <p>
-     * Indicates the call was < 3 seconds in duration.
-     */
-    public static final int CALL_DURATION_VERY_SHORT = 1;
-
-    /**
-     * Call duration reported with {@link #EXTRA_CALL_DURATION} to indicate to the
-     * {@link CallScreeningService} the duration of a call for which the user reported the nuisance
-     * status (see {@link TelecomManager#reportNuisanceCallStatus(Uri, boolean)}).  The
-     * {@link CallScreeningService} can use this as a signal for training nuisance detection
-     * algorithms.  The call duration is reported in coarse grained buckets to minimize exposure of
-     * identifying call log information to the {@link CallScreeningService}.
-     * <p>
-     * Indicates the call was greater than 3 seconds, but less than 60 seconds in duration.
-     */
-    public static final int CALL_DURATION_SHORT = 2;
-
-    /**
-     * Call duration reported with {@link #EXTRA_CALL_DURATION} to indicate to the
-     * {@link CallScreeningService} the duration of a call for which the user reported the nuisance
-     * status (see {@link TelecomManager#reportNuisanceCallStatus(Uri, boolean)}).  The
-     * {@link CallScreeningService} can use this as a signal for training nuisance detection
-     * algorithms.  The call duration is reported in coarse grained buckets to minimize exposure of
-     * identifying call log information to the {@link CallScreeningService}.
-     * <p>
-     * Indicates the call was greater than 60 seconds, but less than 120 seconds in duration.
-     */
-    public static final int CALL_DURATION_MEDIUM = 3;
-
-    /**
-     * Call duration reported with {@link #EXTRA_CALL_DURATION} to indicate to the
-     * {@link CallScreeningService} the duration of a call for which the user reported the nuisance
-     * status (see {@link TelecomManager#reportNuisanceCallStatus(Uri, boolean)}).  The
-     * {@link CallScreeningService} can use this as a signal for training nuisance detection
-     * algorithms.  The call duration is reported in coarse grained buckets to minimize exposure of
-     * identifying call log information to the {@link CallScreeningService}.
-     * <p>
-     * Indicates the call was greater than 120 seconds.
-     */
-    public static final int CALL_DURATION_LONG = 4;
-
-    /**
-     * Telecom sends this intent to the {@link CallScreeningService} which the user has chosen to
-     * fill the call screening role when the user indicates through the default dialer whether a
-     * call is a nuisance call or not (see
-     * {@link TelecomManager#reportNuisanceCallStatus(Uri, boolean)}).
-     * <p>
-     * The following extra values are provided for the call:
-     * <ol>
-     *     <li>{@link #EXTRA_CALL_HANDLE} - the handle of the call.</li>
-     *     <li>{@link #EXTRA_IS_NUISANCE} - {@code true} if the user reported the call as a nuisance
-     *     call, {@code false} otherwise.</li>
-     *     <li>{@link #EXTRA_CALL_TYPE} - reports the type of call (incoming, rejected, missed,
-     *     blocked).</li>
-     *     <li>{@link #EXTRA_CALL_DURATION} - the duration of the call (see
-     *     {@link #EXTRA_CALL_DURATION} for valid values).</li>
-     * </ol>
-     * <p>
-     * {@link CallScreeningService} implementations which want to track whether the user reports
-     * calls are nuisance calls should use declare a broadcast receiver in their manifest for this
-     * intent.
-     * <p>
-     * Note: Only {@link CallScreeningService} implementations which have provided
-     * {@link CallIdentification} information for calls at some point will receive this intent.
-     */
-    public static final String ACTION_NUISANCE_CALL_STATUS_CHANGED =
-            "android.telecom.action.NUISANCE_CALL_STATUS_CHANGED";
-
-    /**
-     * Extra used to provide the handle of the call for
-     * {@link #ACTION_NUISANCE_CALL_STATUS_CHANGED}.  The call handle is reported as a
-     * {@link Uri}.
-     */
-    public static final String EXTRA_CALL_HANDLE = "android.telecom.extra.CALL_HANDLE";
-
-    /**
-     * Boolean extra used to indicate whether the user reported a call as a nuisance call.
-     * When {@code true}, the user reported that a call was a nuisance call, {@code false}
-     * otherwise.  Sent with {@link #ACTION_NUISANCE_CALL_STATUS_CHANGED}.
-     */
-    public static final String EXTRA_IS_NUISANCE = "android.telecom.extra.IS_NUISANCE";
-
-    /**
-     * Integer extra used with {@link #ACTION_NUISANCE_CALL_STATUS_CHANGED} to report the type of
-     * call. Valid values are:
-     * <UL>
-     *   <li>{@link android.provider.CallLog.Calls#MISSED_TYPE}</li>
-     *   <li>{@link android.provider.CallLog.Calls#INCOMING_TYPE}</li>
-     *   <li>{@link android.provider.CallLog.Calls#BLOCKED_TYPE}</li>
-     *   <li>{@link android.provider.CallLog.Calls#REJECTED_TYPE}</li>
-     * </UL>
-     */
-    public static final String EXTRA_CALL_TYPE = "android.telecom.extra.CALL_TYPE";
-
-    /**
-     * Integer extra used to with {@link #ACTION_NUISANCE_CALL_STATUS_CHANGED} to report how long
-     * the call lasted.  Valid values are:
-     * <UL>
-     *     <LI>{@link #CALL_DURATION_VERY_SHORT}</LI>
-     *     <LI>{@link #CALL_DURATION_SHORT}</LI>
-     *     <LI>{@link #CALL_DURATION_MEDIUM}</LI>
-     *     <LI>{@link #CALL_DURATION_LONG}</LI>
-     * </UL>
-     */
-    public static final String EXTRA_CALL_DURATION = "android.telecom.extra.CALL_DURATION";
-
     /**
      * The {@link Intent} that must be declared as handled by the service.
      */
@@ -413,10 +291,6 @@
      * Your app can tell if a call is an incoming call by checking to see if
      * {@link Call.Details#getCallDirection()} is {@link Call.Details#DIRECTION_INCOMING}.
      * <p>
-     * For incoming or outgoing calls, the {@link CallScreeningService} can call
-     * {@link #provideCallIdentification(Call.Details, CallIdentification)} in order to provide
-     * {@link CallIdentification} for the call.
-     * <p>
      * Note: The {@link Call.Details} instance provided to a call screening service will only have
      * the following properties set.  The rest of the {@link Call.Details} properties will be set to
      * their default value or {@code null}.
@@ -472,32 +346,4 @@
         } catch (RemoteException e) {
         }
     }
-
-    /**
-     * Provide {@link CallIdentification} information about a {@link Call.Details call}.
-     * <p>
-     * The {@link CallScreeningService} calls this method to provide information it has identified
-     * about a {@link Call.Details call}.  This information will potentially be shown to the user
-     * in the {@link InCallService dialer} app.  It will be logged to the
-     * {@link android.provider.CallLog}.
-     * <p>
-     * A {@link CallScreeningService} should only call this method for calls for which it is able to
-     * provide some {@link CallIdentification} for.  {@link CallIdentification} instances with no
-     * fields set will be ignored by the system.
-     *
-     * @param callDetails The call to provide information for.
-     *                    <p>
-     *                    Must be the same {@link Call.Details call} which was provided to the
-     *                    {@link CallScreeningService} via {@link #onScreenCall(Call.Details)}.
-     * @param identification An instance of {@link CallIdentification} with information about the
-     *                       {@link Call.Details call}.
-     */
-    public final void provideCallIdentification(@NonNull Call.Details callDetails,
-            @NonNull CallIdentification identification) {
-        try {
-            mCallScreeningAdapter.provideCallIdentification(callDetails.getTelecomCallId(),
-                    identification);
-        } catch (RemoteException e) {
-        }
-    }
 }
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 345707e..aa50991 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -64,7 +64,6 @@
     private final Bundle mIntentExtras;
     private final Bundle mExtras;
     private final long mCreationTimeMillis;
-    private final CallIdentification mCallIdentification;
     private final int mCallDirection;
 
     public ParcelableCall(
@@ -94,7 +93,6 @@
             Bundle intentExtras,
             Bundle extras,
             long creationTimeMillis,
-            CallIdentification callIdentification,
             int callDirection) {
         mId = id;
         mState = state;
@@ -122,7 +120,6 @@
         mIntentExtras = intentExtras;
         mExtras = extras;
         mCreationTimeMillis = creationTimeMillis;
-        mCallIdentification = callIdentification;
         mCallDirection = callDirection;
     }
 
@@ -314,15 +311,6 @@
     }
 
     /**
-     * Contains call identification information returned by a {@link CallScreeningService}.
-     * @return The {@link CallIdentification} for this call, or {@code null} if a
-     * {@link CallScreeningService} did not provide information.
-     */
-    public @Nullable CallIdentification getCallIdentification() {
-        return mCallIdentification;
-    }
-
-    /**
      * Indicates whether the call is an incoming or outgoing call.
      */
     public @CallDirection int getCallDirection() {
@@ -366,7 +354,6 @@
             boolean isRttCallChanged = source.readByte() == 1;
             ParcelableRttCall rttCall = source.readParcelable(classLoader);
             long creationTimeMillis = source.readLong();
-            CallIdentification callIdentification = source.readParcelable(classLoader);
             int callDirection = source.readInt();
             return new ParcelableCall(
                     id,
@@ -395,7 +382,6 @@
                     intentExtras,
                     extras,
                     creationTimeMillis,
-                    callIdentification,
                     callDirection);
         }
 
@@ -441,7 +427,6 @@
         destination.writeByte((byte) (mIsRttCallChanged ? 1 : 0));
         destination.writeParcelable(mRttCall, 0);
         destination.writeLong(mCreationTimeMillis);
-        destination.writeParcelable(mCallIdentification, 0);
         destination.writeInt(mCallDirection);
     }
 
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 3d0a3c5..391d788 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -2002,33 +2002,6 @@
     }
 
     /**
-     * Called by the default dialer to report to Telecom when the user has marked a previous
-     * incoming call as a nuisance call or not.
-     * <p>
-     * Where the user has chosen a {@link CallScreeningService} to fill the call screening role,
-     * Telecom will notify that {@link CallScreeningService} of the user's report.
-     * <p>
-     * Requires that the caller is the default dialer app.
-     *
-     * @param handle The phone number of an incoming call which the user is reporting as either a
-     *               nuisance of non-nuisance call.
-     * @param isNuisanceCall {@code true} if the user is reporting the call as a nuisance call,
-     *                       {@code false} if the user is reporting the call as a non-nuisance call.
-     */
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public void reportNuisanceCallStatus(@NonNull Uri handle, boolean isNuisanceCall) {
-        ITelecomService service = getTelecomService();
-        if (service != null) {
-            try {
-                service.reportNuisanceCallStatus(handle, isNuisanceCall,
-                        mContext.getOpPackageName());
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error calling ITelecomService#showCallScreen", e);
-            }
-        }
-    }
-
-    /**
      * Handles {@link Intent#ACTION_CALL} intents trampolined from UserCallActivity.
      * @param intent The {@link Intent#ACTION_CALL} intent to handle.
      * @hide
diff --git a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
index 1160d27..3ee3285 100644
--- a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
@@ -17,7 +17,6 @@
 package com.android.internal.telecom;
 
 import android.content.ComponentName;
-import android.telecom.CallIdentification;
 
 /**
  * Internal remote callback interface for call screening services.
@@ -37,8 +36,4 @@
             boolean shouldAddToCallLog,
             boolean shouldShowNotification,
             in ComponentName componentName);
-
-    void provideCallIdentification(
-            String callId,
-            in CallIdentification callIdentification);
 }
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 93eea56..a814c03 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -286,8 +286,6 @@
      */
     boolean isInEmergencyCall();
 
-    oneway void reportNuisanceCallStatus(in Uri address, boolean isNuisance, String callingPackage);
-
     /**
      * @see TelecomServiceImpl#handleCallIntent
      */
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 3106e40..52e0ebd 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -35,6 +35,7 @@
 import android.database.sqlite.SqliteWrapper;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Parcel;
 import android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SmsMessage;
@@ -4130,32 +4131,24 @@
          */
         public static ContentValues getContentValuesForServiceState(ServiceState state) {
             ContentValues values = new ContentValues();
-            values.put(VOICE_REG_STATE, state.getVoiceRegState());
-            values.put(DATA_REG_STATE, state.getDataRegState());
-            values.put(VOICE_ROAMING_TYPE, state.getVoiceRoamingType());
-            values.put(DATA_ROAMING_TYPE, state.getDataRoamingType());
-            values.put(VOICE_OPERATOR_ALPHA_LONG, state.getVoiceOperatorAlphaLong());
-            values.put(VOICE_OPERATOR_ALPHA_SHORT, state.getVoiceOperatorAlphaShort());
-            values.put(VOICE_OPERATOR_NUMERIC, state.getVoiceOperatorNumeric());
-            values.put(DATA_OPERATOR_ALPHA_LONG, state.getDataOperatorAlphaLong());
-            values.put(DATA_OPERATOR_ALPHA_SHORT, state.getDataOperatorAlphaShort());
-            values.put(DATA_OPERATOR_NUMERIC, state.getDataOperatorNumeric());
-            values.put(IS_MANUAL_NETWORK_SELECTION, state.getIsManualSelection());
-            values.put(RIL_VOICE_RADIO_TECHNOLOGY, state.getRilVoiceRadioTechnology());
-            values.put(RIL_DATA_RADIO_TECHNOLOGY, state.getRilDataRadioTechnology());
-            values.put(CSS_INDICATOR, state.getCssIndicator());
-            values.put(NETWORK_ID, state.getCdmaNetworkId());
-            values.put(SYSTEM_ID, state.getCdmaSystemId());
-            values.put(CDMA_ROAMING_INDICATOR, state.getCdmaRoamingIndicator());
-            values.put(CDMA_DEFAULT_ROAMING_INDICATOR, state.getCdmaDefaultRoamingIndicator());
-            values.put(CDMA_ERI_ICON_INDEX, state.getCdmaEriIconIndex());
-            values.put(CDMA_ERI_ICON_MODE, state.getCdmaEriIconMode());
-            values.put(IS_EMERGENCY_ONLY, state.isEmergencyOnly());
-            values.put(IS_USING_CARRIER_AGGREGATION, state.isUsingCarrierAggregation());
+            final Parcel p = Parcel.obtain();
+            state.writeToParcel(p, 0);
+            // Turn the parcel to byte array. Safe to do this because the content values were never
+            // written into a persistent storage. ServiceStateProvider keeps values in the memory.
+            values.put(SERVICE_STATE, p.marshall());
             return values;
         }
 
         /**
+         * The current service state.
+         *
+         * This is the entire {@link ServiceState} object in byte array.
+         *
+         * @hide
+         */
+        public static final String SERVICE_STATE = "service_state";
+
+        /**
          * An integer value indicating the current voice service state.
          * <p>
          * Valid values: {@link ServiceState#STATE_IN_SERVICE},
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java
index a15f959..a1c5bbe 100644
--- a/telephony/java/android/telephony/AvailableNetworkInfo.java
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.java
@@ -27,8 +27,8 @@
 
 /**
  * Defines available network information which includes corresponding subscription id,
- * network plmns and corresponding priority to be used for network selection by Alternative Network
- * Service.
+ * network plmns and corresponding priority to be used for network selection by Opportunistic
+ * Network Service when passed through {@link TelephonyManager#updateAvailableNetworks}
  */
 public final class AvailableNetworkInfo implements Parcelable {
 
@@ -55,15 +55,19 @@
 
     /**
      * Priority for the subscription id.
-     * Priorities are in the range of 1 to 3 where 1
-     * has the highest priority.
+     * Priorities are in the range of {@link AvailableNetworkInfo#PRIORITY_LOW} to
+     * {@link AvailableNetworkInfo#PRIORITY_HIGH}
+     * Among all networks available after network scan, subId with highest priority is chosen
+     * for network selection. If there are more than one subId with highest priority then the
+     * network with highest RSRP is chosen.
      */
     private int mPriority;
 
     /**
      * Describes the List of PLMN ids (MCC-MNC) associated with mSubId.
-     * If this entry is left empty, then the platform software will not scan the network
-     * to revalidate the input else platform will scan and verify specified PLMNs are available.
+     * Opportunistic Network Service will scan and verify specified PLMNs are available.
+     * If this entry is left empty, then the Opportunistic Network Service will not scan the network
+     * to validate the network availability.
      */
     private ArrayList<String> mMccMncs;
 
@@ -71,8 +75,8 @@
      * Returns the frequency bands associated with the {@link #getMccMncs() MCC/MNCs}.
      * Opportunistic network service will use these bands to scan.
      *
-     * When no specific bands are specified (empty array or null) CBRS band (B48) will be
-     * used for network scan.
+     * When no specific bands are specified (empty array or null) CBRS band
+     * {@link AccessNetworkConstants.EutranBand.BAND_48} will be used for network scan.
      *
      * See {@link AccessNetworkConstants} for details.
      */
@@ -89,8 +93,12 @@
     }
 
     /**
-     * Return priority for the subscription id. Valid value will be within
-     * [{@link AvailableNetworkInfo#PRIORITY_HIGH}, {@link AvailableNetworkInfo#PRIORITY_LOW}]
+     * Return priority for the subscription id.
+     * Priorities are in the range of {@link AvailableNetworkInfo#PRIORITY_LOW} to
+     * {@link AvailableNetworkInfo#PRIORITY_HIGH}
+     * Among all networks available after network scan, subId with highest priority is chosen
+     * for network selection. If there are more than one subId with highest priority then the
+     * network with highest RSRP is chosen.
      * @return priority level
      */
     public int getPriority() {
@@ -99,8 +107,9 @@
 
     /**
      * Return List of PLMN ids (MCC-MNC) associated with the sub ID.
-     * If this entry is left empty, then the platform software will not scan the network
-     * to revalidate the input.
+     * Opportunistic Network Service will scan and verify specified PLMNs are available.
+     * If this entry is left empty, then the Opportunistic Network Service will not scan the network
+     * to validate the network availability.
      * @return list of PLMN ids
      */
     public @NonNull List<String> getMccMncs() {
@@ -112,6 +121,9 @@
      *
      * The returned value is defined in either of {@link AccessNetworkConstants.GeranBand},
      * {@link AccessNetworkConstants.UtranBand} and {@link AccessNetworkConstants.EutranBand}
+     * See {@link AccessNetworkConstants.AccessNetworkType} for details regarding different network
+     * types. When no specific bands are specified (empty array or null) CBRS band
+     * {@link AccessNetworkConstants.EutranBand#BAND_48} will be used for network scan.
      */
     public @NonNull List<Integer> getBands() {
         return (List<Integer>) mBands.clone();
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 0a9b904..a567d03 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1852,6 +1852,14 @@
             "editable_wfc_roaming_mode_bool";
 
     /**
+     * Flag specifying wether to show blocking pay phone option in blocked numbers screen. Only show
+     * the option if payphone call presentation represents in the carrier's region.
+     * @hide
+     */
+    public static final java.lang.String KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL =
+            "show_blocking_pay_phone_option_bool";
+
+    /**
      * Flag specifying whether the carrier will use the WFC home network mode in roaming network.
      * {@code false} - roaming preference can be selected separately from the home preference.
      * {@code true}  - roaming preference is the same as home preference and
@@ -1888,6 +1896,16 @@
     public static final String KEY_IMSI_ENCODING_METHOD_INT = "imsi_encoding_method_int";
 
     /**
+     * Defines the sequence of sending an encrypted IMSI identity for EAP-SIM/AKA authentication.
+     * The value set as below:
+     * 1 - encrypted IMSI as EAP-RESPONSE/IDENTITY (default one).
+     * 2 - anonymous as EAP-RESPONSE/IDENTITY -> encrypted IMSI as EAP-RESPONSE/AKA|SIM-IDENTITY.
+     *
+     * @hide
+     */
+    public static final String KEY_EAP_IDENTITY_SEQUENCE_INT = "imsi_eap_identity_sequence_int";
+
+    /**
      * Time delay (in ms) after which we show the notification to switch the preferred
      * network.
      * @hide
@@ -2563,6 +2581,22 @@
             "emergency_number_prefix_string_array";
 
     /**
+     * Smart forwarding config. Smart forwarding is a feature to configure call forwarding to a
+     * different SIM in the device when one SIM is not reachable. The config here specifies a smart
+     * forwarding component that will launch UI for changing the configuration. An empty string
+     * indicates that no smart forwarding component is specified.
+     *
+     * Currently, only one non-empty configuration of smart forwarding component within system will
+     * be used when multiple SIMs are inserted.
+     *
+     * Empty string by default.
+     *
+     * @hide
+     */
+    public static final String KEY_SMART_FORWARDING_CONFIG_COMPONENT_NAME_STRING =
+            "smart_forwarding_config_component_name_string";
+
+    /**
      * Indicates when a carrier has a primary subscription and an opportunistic subscription active,
      * and when Internet data is switched to opportunistic network, whether to still show
      * signal bar of primary network. By default it will be false, meaning whenever data
@@ -2766,7 +2800,7 @@
         sDefaults.putBoolean(KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL, false);
-        sDefaults.putBoolean(KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, true);
+        sDefaults.putBoolean(KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true);
         sDefaults.putBoolean(KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, true);
@@ -3024,11 +3058,13 @@
         sDefaults.putBoolean(KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, false);
         sDefaults.putStringArray(KEY_FILTERED_CNAP_NAMES_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
+        sDefaults.putBoolean(KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL, false);
         sDefaults.putBoolean(KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false);
         sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false);
         sDefaults.putBoolean(KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL, false);
         sDefaults.putStringArray(KEY_CARRIER_WIFI_STRING_ARRAY, null);
         sDefaults.putInt(KEY_IMSI_ENCODING_METHOD_INT, 2045);
+        sDefaults.putInt(KEY_EAP_IDENTITY_SEQUENCE_INT, 1);
         sDefaults.putInt(KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT, -1);
         sDefaults.putInt(KEY_EMERGENCY_NOTIFICATION_DELAY_INT, -1);
         sDefaults.putBoolean(KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL, true);
@@ -3121,6 +3157,7 @@
         sDefaults.putBoolean(KEY_USE_USIM_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL, true);
         sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
+        sDefaults.putString(KEY_SMART_FORWARDING_CONFIG_COMPONENT_NAME_STRING, "");
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN,
                 false);
     }
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index e5aadad..3745277 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -110,6 +110,22 @@
     }
 
     /**
+     * @return MCC or null for CDMA
+     * @hide
+     */
+    public String getMccString() {
+        return mMccStr;
+    }
+
+    /**
+     * @return MNC or null for CDMA
+     * @hide
+     */
+    public String getMncString() {
+        return mMncStr;
+    }
+
+    /**
      * Returns the channel number of the cell identity.
      *
      * @hide
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index daf80f5..4c00611 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -109,6 +109,13 @@
         return new CellIdentityCdma(this);
     }
 
+    /** @hide */
+    public CellIdentityCdma sanitizeLocationInfo() {
+        return new CellIdentityCdma(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                mAlphaLong, mAlphaShort);
+    }
+
     /**
      * Take the latitude and longitude in 1/4 seconds and see if
      * the reported location is on Null Island.
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 6328afc..5e44bf2 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -97,6 +97,12 @@
         return new CellIdentityGsm(this);
     }
 
+    /** @hide */
+    public CellIdentityGsm sanitizeLocationInfo() {
+        return new CellIdentityGsm(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                CellInfo.UNAVAILABLE, mMccStr, mMncStr, mAlphaLong, mAlphaShort);
+    }
+
     /**
      * @return 3-digit Mobile Country Code, 0..999,
      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index e112004..2dd72d6 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -113,6 +113,13 @@
                 cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
     }
 
+    /** @hide */
+    public CellIdentityLte sanitizeLocationInfo() {
+        return new CellIdentityLte(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                mMccStr, mMncStr, mAlphaLong, mAlphaShort);
+    }
+
     CellIdentityLte copy() {
         return new CellIdentityLte(this);
     }
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index 4be52a3..62d23ce 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -46,7 +46,7 @@
      *
      * @hide
      */
-    public CellIdentityNr(int pci, int tac, int nrArfcn,  String mccStr, String mncStr,
+    public CellIdentityNr(int pci, int tac, int nrArfcn, String mccStr, String mncStr,
             long nci, String alphal, String alphas) {
         super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas);
         mPci = pci;
@@ -55,6 +55,12 @@
         mNci = nci;
     }
 
+    /** @hide */
+    public CellIdentityNr sanitizeLocationInfo() {
+        return new CellIdentityNr(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                mMccStr, mMncStr, CellInfo.UNAVAILABLE, mAlphaLong, mAlphaShort);
+    }
+
     /**
      * @return a CellLocation object for this CellIdentity.
      * @hide
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 19b11b6..a591bd1 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -90,6 +90,12 @@
                 cid.uarfcn, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
     }
 
+    /** @hide */
+    public CellIdentityTdscdma sanitizeLocationInfo() {
+        return new CellIdentityTdscdma(mMccStr, mMncStr, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mAlphaLong, mAlphaShort);
+    }
+
     CellIdentityTdscdma copy() {
         return new CellIdentityTdscdma(this);
     }
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index b1944af..674c40c 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -91,6 +91,13 @@
                 cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
     }
 
+    /** @hide */
+    public CellIdentityWcdma sanitizeLocationInfo() {
+        return new CellIdentityWcdma(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, mMccStr, mMncStr,
+                mAlphaLong, mAlphaShort);
+    }
+
     CellIdentityWcdma copy() {
         return new CellIdentityWcdma(this);
     }
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index 1796034..7edc91c 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -197,6 +197,11 @@
     @NonNull
     public abstract CellSignalStrength getCellSignalStrength();
 
+    /** @hide */
+    public CellInfo sanitizeLocationInfo() {
+        return null;
+    }
+
     /**
      * Gets the connection status of this cell.
      *
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index 82bb3961..a4570e4 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -90,6 +90,15 @@
     public CellSignalStrengthCdma getCellSignalStrength() {
         return mCellSignalStrengthCdma;
     }
+
+    /** @hide */
+    @Override
+    public CellInfo sanitizeLocationInfo() {
+        CellInfoCdma result = new CellInfoCdma(this);
+        result.mCellIdentityCdma = mCellIdentityCdma.sanitizeLocationInfo();
+        return result;
+    }
+
     /** @hide */
     public void setCellSignalStrength(CellSignalStrengthCdma css) {
         mCellSignalStrengthCdma = css;
diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java
index 59fcd1e..ce32bc1 100644
--- a/telephony/java/android/telephony/CellInfoGsm.java
+++ b/telephony/java/android/telephony/CellInfoGsm.java
@@ -84,6 +84,15 @@
     public CellSignalStrengthGsm getCellSignalStrength() {
         return mCellSignalStrengthGsm;
     }
+
+    /** @hide */
+    @Override
+    public CellInfo sanitizeLocationInfo() {
+        CellInfoGsm result = new CellInfoGsm(this);
+        result.mCellIdentityGsm = mCellIdentityGsm.sanitizeLocationInfo();
+        return result;
+    }
+
     /** @hide */
     public void setCellSignalStrength(CellSignalStrengthGsm css) {
         mCellSignalStrengthGsm = css;
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index 08dafe1..01ee20a 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -96,6 +96,15 @@
         if (DBG) log("getCellSignalStrength: " + mCellSignalStrengthLte);
         return mCellSignalStrengthLte;
     }
+
+    /** @hide */
+    @Override
+    public CellInfo sanitizeLocationInfo() {
+        CellInfoLte result = new CellInfoLte(this);
+        result.mCellIdentityLte = mCellIdentityLte.sanitizeLocationInfo();
+        return result;
+    }
+
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public void setCellSignalStrength(CellSignalStrengthLte css) {
diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java
index 0227610..ba4a907 100644
--- a/telephony/java/android/telephony/CellInfoNr.java
+++ b/telephony/java/android/telephony/CellInfoNr.java
@@ -36,6 +36,13 @@
         mCellSignalStrength = CellSignalStrengthNr.CREATOR.createFromParcel(in);
     }
 
+    private CellInfoNr(CellInfoNr other, boolean sanitizeLocationInfo) {
+        super(other);
+        mCellIdentity = sanitizeLocationInfo ? other.mCellIdentity.sanitizeLocationInfo()
+                : other.mCellIdentity;
+        mCellSignalStrength = other.mCellSignalStrength;
+    }
+
     @Override
     @NonNull
     public CellIdentity getCellIdentity() {
@@ -48,6 +55,12 @@
         return mCellSignalStrength;
     }
 
+    /** @hide */
+    @Override
+    public CellInfo sanitizeLocationInfo() {
+        return new CellInfoNr(this, true);
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(super.hashCode(), mCellIdentity, mCellSignalStrength);
diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java
index 1830086..ccafda6 100644
--- a/telephony/java/android/telephony/CellInfoTdscdma.java
+++ b/telephony/java/android/telephony/CellInfoTdscdma.java
@@ -91,6 +91,14 @@
     }
 
     /** @hide */
+    @Override
+    public CellInfo sanitizeLocationInfo() {
+        CellInfoTdscdma result = new CellInfoTdscdma(this);
+        result.mCellIdentityTdscdma = mCellIdentityTdscdma.sanitizeLocationInfo();
+        return result;
+    }
+
+    /** @hide */
     public void setCellSignalStrength(CellSignalStrengthTdscdma css) {
         mCellSignalStrengthTdscdma = css;
     }
diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java
index 02dbb1a..1b32178 100644
--- a/telephony/java/android/telephony/CellInfoWcdma.java
+++ b/telephony/java/android/telephony/CellInfoWcdma.java
@@ -84,6 +84,15 @@
     public CellSignalStrengthWcdma getCellSignalStrength() {
         return mCellSignalStrengthWcdma;
     }
+
+    /** @hide */
+    @Override
+    public CellInfo sanitizeLocationInfo() {
+        CellInfoWcdma result = new CellInfoWcdma(this);
+        result.mCellIdentityWcdma = mCellIdentityWcdma.sanitizeLocationInfo();
+        return result;
+    }
+
     /** @hide */
     public void setCellSignalStrength(CellSignalStrengthWcdma css) {
         mCellSignalStrengthWcdma = css;
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index fbf488e..2cb369d 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -74,16 +74,25 @@
     private final LteVopsSupportInfo mLteVopsSupportInfo;
 
     /**
+     * Indicates if it's using carrier aggregation
+     *
+     * @hide
+     */
+    public boolean mIsUsingCarrierAggregation;
+
+    /**
      * @hide
      */
     DataSpecificRegistrationInfo(
             int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
-            boolean isEnDcAvailable, LteVopsSupportInfo lteVops) {
+            boolean isEnDcAvailable, LteVopsSupportInfo lteVops,
+            boolean isUsingCarrierAggregation) {
         this.maxDataCalls = maxDataCalls;
         this.isDcNrRestricted = isDcNrRestricted;
         this.isNrAvailable = isNrAvailable;
         this.isEnDcAvailable = isEnDcAvailable;
         this.mLteVopsSupportInfo = lteVops;
+        this.mIsUsingCarrierAggregation = isUsingCarrierAggregation;
     }
 
     private DataSpecificRegistrationInfo(Parcel source) {
@@ -92,6 +101,7 @@
         isNrAvailable = source.readBoolean();
         isEnDcAvailable = source.readBoolean();
         mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
+        mIsUsingCarrierAggregation = source.readBoolean();
     }
 
     @Override
@@ -101,6 +111,7 @@
         dest.writeBoolean(isNrAvailable);
         dest.writeBoolean(isEnDcAvailable);
         mLteVopsSupportInfo.writeToParcel(dest, flags);
+        dest.writeBoolean(mIsUsingCarrierAggregation);
     }
 
     @Override
@@ -116,7 +127,8 @@
                 .append(" isDcNrRestricted = " + isDcNrRestricted)
                 .append(" isNrAvailable = " + isNrAvailable)
                 .append(" isEnDcAvailable = " + isEnDcAvailable)
-                .append(mLteVopsSupportInfo.toString())
+                .append(" " + mLteVopsSupportInfo.toString())
+                .append(" mIsUsingCarrierAggregation = " + mIsUsingCarrierAggregation)
                 .append(" }")
                 .toString();
     }
@@ -124,7 +136,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable,
-                mLteVopsSupportInfo);
+                mLteVopsSupportInfo, mIsUsingCarrierAggregation);
     }
 
     @Override
@@ -138,7 +150,8 @@
                 && this.isDcNrRestricted == other.isDcNrRestricted
                 && this.isNrAvailable == other.isNrAvailable
                 && this.isEnDcAvailable == other.isEnDcAvailable
-                && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo);
+                && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo)
+                && this.mIsUsingCarrierAggregation == other.mIsUsingCarrierAggregation;
     }
 
     public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR =
@@ -161,4 +174,22 @@
     public LteVopsSupportInfo getLteVopsSupportInfo() {
         return mLteVopsSupportInfo;
     }
+
+    /**
+     * Set the flag indicating if using carrier aggregation.
+     *
+     * @param isUsingCarrierAggregation {@code true} if using carrier aggregation.
+     * @hide
+     */
+    public void setIsUsingCarrierAggregation(boolean isUsingCarrierAggregation) {
+        mIsUsingCarrierAggregation = isUsingCarrierAggregation;
+    }
+
+    /**
+     * @return {@code true} if using carrier aggregation.
+     * @hide
+     */
+    public boolean isUsingCarrierAggregation() {
+        return mIsUsingCarrierAggregation;
+    }
 }
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 1dc2997..7b9f6d5 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -251,12 +251,13 @@
                                    @Nullable CellIdentity cellIdentity, int maxDataCalls,
                                    boolean isDcNrRestricted, boolean isNrAvailable,
                                    boolean isEndcAvailable,
-                                   LteVopsSupportInfo lteVopsSupportInfo) {
+                                   LteVopsSupportInfo lteVopsSupportInfo,
+                                   boolean isUsingCarrierAggregation) {
         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
                 emergencyOnly, availableServices, cellIdentity);
-
         mDataSpecificInfo = new DataSpecificRegistrationInfo(
-                maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo);
+                maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo,
+                isUsingCarrierAggregation);
         updateNrState(mDataSpecificInfo);
     }
 
@@ -367,6 +368,13 @@
      * @hide
      */
     public void setAccessNetworkTechnology(@NetworkType int tech) {
+        if (tech == TelephonyManager.NETWORK_TYPE_LTE_CA) {
+            // For old device backward compatibility support
+            tech = TelephonyManager.NETWORK_TYPE_LTE;
+            if (mDataSpecificInfo != null) {
+                mDataSpecificInfo.setIsUsingCarrierAggregation(true);
+            }
+        }
         mAccessNetworkTechnology = tech;
     }
 
diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java
index 119f587..17b7963f 100644
--- a/telephony/java/android/telephony/PhoneCapability.java
+++ b/telephony/java/android/telephony/PhoneCapability.java
@@ -30,6 +30,25 @@
  * @hide
  */
 public class PhoneCapability implements Parcelable {
+    // Hardcoded default DSDS capability.
+    public static final PhoneCapability DEFAULT_DSDS_CAPABILITY;
+    // Hardcoded default Single SIM single standby capability.
+    public static final PhoneCapability DEFAULT_SSSS_CAPABILITY;
+
+    static {
+        ModemInfo modemInfo1 = new ModemInfo(0, 0, true, true);
+        ModemInfo modemInfo2 = new ModemInfo(1, 0, true, true);
+
+        List<ModemInfo> logicalModemList = new ArrayList<>();
+        logicalModemList.add(modemInfo1);
+        logicalModemList.add(modemInfo2);
+        DEFAULT_DSDS_CAPABILITY = new PhoneCapability(1, 1, 0, logicalModemList, false);
+
+        logicalModemList = new ArrayList<>();
+        logicalModemList.add(modemInfo1);
+        DEFAULT_SSSS_CAPABILITY = new PhoneCapability(1, 1, 0, logicalModemList, false);
+    }
+
     public final int maxActiveVoiceCalls;
     public final int maxActiveData;
     public final int max5G;
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 549c044..b75e515 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -2016,7 +2016,16 @@
     private static boolean isEmergencyNumberInternal(int subId, String number,
                                                      String defaultCountryIso,
                                                      boolean useExactMatch) {
-        return TelephonyManager.getDefault().isEmergencyNumber(number);
+        try {
+            if (useExactMatch) {
+                return TelephonyManager.getDefault().isEmergencyNumber(number);
+            } else {
+                return TelephonyManager.getDefault().isPotentialEmergencyNumber(number);
+            }
+        } catch (RuntimeException ex) {
+            Rlog.e(LOG_TAG, "isEmergencyNumberInternal: RuntimeException: " + ex);
+        }
+        return false;
     }
 
     /**
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 918bf60..373c5d2 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -297,8 +297,11 @@
      *  it could be the current active opportunistic subscription in use, or the
      *  subscription user selected as default data subscription in DSDS mode.
      *
-     *  Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
-     *  READ_PHONE_STATE}
+     *  Requires Permission: No permission is required to listen, but notification requires
+     *  {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} or the calling
+     *  app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges})
+     *  on any active subscription.
+     *
      *  @see #onActiveDataSubscriptionIdChanged
      */
     public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000;
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index a794ba1..d2c0705 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -312,18 +312,6 @@
     private boolean mIsManualNetworkSelection;
 
     private boolean mIsEmergencyOnly;
-    /**
-     * TODO: remove mRilVoiceRadioTechnology after completely migrate to
-     * {@link TelephonyManager.NetworkType}
-     */
-    @RilRadioTechnology
-    private int mRilVoiceRadioTechnology;
-    /**
-     * TODO: remove mRilDataRadioTechnology after completely migrate to
-     * {@link TelephonyManager.NetworkType}
-     */
-    @RilRadioTechnology
-    private int mRilDataRadioTechnology;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private boolean mCssIndicator;
@@ -340,9 +328,6 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private int mCdmaEriIconMode;
 
-    @UnsupportedAppUsage
-    private boolean mIsUsingCarrierAggregation;
-
     @FrequencyRange
     private int mNrFrequencyRange;
     private int mChannelNumber;
@@ -420,8 +405,6 @@
         mDataOperatorAlphaShort = s.mDataOperatorAlphaShort;
         mDataOperatorNumeric = s.mDataOperatorNumeric;
         mIsManualNetworkSelection = s.mIsManualNetworkSelection;
-        mRilVoiceRadioTechnology = s.mRilVoiceRadioTechnology;
-        mRilDataRadioTechnology = s.mRilDataRadioTechnology;
         mCssIndicator = s.mCssIndicator;
         mNetworkId = s.mNetworkId;
         mSystemId = s.mSystemId;
@@ -430,7 +413,6 @@
         mCdmaEriIconIndex = s.mCdmaEriIconIndex;
         mCdmaEriIconMode = s.mCdmaEriIconMode;
         mIsEmergencyOnly = s.mIsEmergencyOnly;
-        mIsUsingCarrierAggregation = s.mIsUsingCarrierAggregation;
         mChannelNumber = s.mChannelNumber;
         mCellBandwidths = s.mCellBandwidths == null ? null :
                 Arrays.copyOf(s.mCellBandwidths, s.mCellBandwidths.length);
@@ -457,8 +439,6 @@
         mDataOperatorAlphaShort = in.readString();
         mDataOperatorNumeric = in.readString();
         mIsManualNetworkSelection = in.readInt() != 0;
-        mRilVoiceRadioTechnology = in.readInt();
-        mRilDataRadioTechnology = in.readInt();
         mCssIndicator = (in.readInt() != 0);
         mNetworkId = in.readInt();
         mSystemId = in.readInt();
@@ -467,7 +447,6 @@
         mCdmaEriIconIndex = in.readInt();
         mCdmaEriIconMode = in.readInt();
         mIsEmergencyOnly = in.readInt() != 0;
-        mIsUsingCarrierAggregation = in.readInt() != 0;
         mLteEarfcnRsrpBoost = in.readInt();
         mNetworkRegistrationInfos = new ArrayList<>();
         in.readList(mNetworkRegistrationInfos, NetworkRegistrationInfo.class.getClassLoader());
@@ -486,8 +465,6 @@
         out.writeString(mDataOperatorAlphaShort);
         out.writeString(mDataOperatorNumeric);
         out.writeInt(mIsManualNetworkSelection ? 1 : 0);
-        out.writeInt(mRilVoiceRadioTechnology);
-        out.writeInt(mRilDataRadioTechnology);
         out.writeInt(mCssIndicator ? 1 : 0);
         out.writeInt(mNetworkId);
         out.writeInt(mSystemId);
@@ -496,7 +473,6 @@
         out.writeInt(mCdmaEriIconIndex);
         out.writeInt(mCdmaEriIconMode);
         out.writeInt(mIsEmergencyOnly ? 1 : 0);
-        out.writeInt(mIsUsingCarrierAggregation ? 1 : 0);
         out.writeInt(mLteEarfcnRsrpBoost);
         out.writeList(mNetworkRegistrationInfos);
         out.writeInt(mChannelNumber);
@@ -568,7 +544,7 @@
     @DuplexMode
     public int getDuplexMode() {
         // only support LTE duplex mode
-        if (!isLte(mRilDataRadioTechnology)) {
+        if (!isLte(getRilDataRadioTechnology())) {
             return DUPLEX_MODE_UNKNOWN;
         }
 
@@ -850,8 +826,6 @@
                 mDataOperatorAlphaShort,
                 mDataOperatorNumeric,
                 mIsManualNetworkSelection,
-                mRilVoiceRadioTechnology,
-                mRilDataRadioTechnology,
                 mCssIndicator,
                 mNetworkId,
                 mSystemId,
@@ -860,7 +834,6 @@
                 mCdmaEriIconIndex,
                 mCdmaEriIconMode,
                 mIsEmergencyOnly,
-                mIsUsingCarrierAggregation,
                 mLteEarfcnRsrpBoost,
                 mNetworkRegistrationInfos,
                 mNrFrequencyRange);
@@ -871,7 +844,7 @@
         if (!(o instanceof ServiceState)) return false;
         ServiceState s = (ServiceState) o;
 
-        return (mVoiceRegState == s.mVoiceRegState
+        return mVoiceRegState == s.mVoiceRegState
                 && mDataRegState == s.mDataRegState
                 && mIsManualNetworkSelection == s.mIsManualNetworkSelection
                 && mChannelNumber == s.mChannelNumber
@@ -882,8 +855,6 @@
                 && equalsHandlesNulls(mDataOperatorAlphaLong, s.mDataOperatorAlphaLong)
                 && equalsHandlesNulls(mDataOperatorAlphaShort, s.mDataOperatorAlphaShort)
                 && equalsHandlesNulls(mDataOperatorNumeric, s.mDataOperatorNumeric)
-                && equalsHandlesNulls(mRilVoiceRadioTechnology, s.mRilVoiceRadioTechnology)
-                && equalsHandlesNulls(mRilDataRadioTechnology, s.mRilDataRadioTechnology)
                 && equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
                 && equalsHandlesNulls(mNetworkId, s.mNetworkId)
                 && equalsHandlesNulls(mSystemId, s.mSystemId)
@@ -891,7 +862,6 @@
                 && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
                         s.mCdmaDefaultRoamingIndicator)
                 && mIsEmergencyOnly == s.mIsEmergencyOnly
-                && mIsUsingCarrierAggregation == s.mIsUsingCarrierAggregation)
                 && (mNetworkRegistrationInfos == null
                 ? s.mNetworkRegistrationInfos == null : s.mNetworkRegistrationInfos != null
                 && mNetworkRegistrationInfos.containsAll(s.mNetworkRegistrationInfos))
@@ -1035,27 +1005,27 @@
             .append(", mDataOperatorAlphaShort=").append(mDataOperatorAlphaShort)
             .append(", isManualNetworkSelection=").append(mIsManualNetworkSelection)
             .append(mIsManualNetworkSelection ? "(manual)" : "(automatic)")
-            .append(", mRilVoiceRadioTechnology=").append(mRilVoiceRadioTechnology)
-            .append("(" + rilRadioTechnologyToString(mRilVoiceRadioTechnology) + ")")
-            .append(", mRilDataRadioTechnology=").append(mRilDataRadioTechnology)
-            .append("(" + rilRadioTechnologyToString(mRilDataRadioTechnology) + ")")
+            .append(", getRilVoiceRadioTechnology=").append(getRilVoiceRadioTechnology())
+            .append("(" + rilRadioTechnologyToString(getRilVoiceRadioTechnology()) + ")")
+            .append(", getRilDataRadioTechnology=").append(getRilDataRadioTechnology())
+            .append("(" + rilRadioTechnologyToString(getRilDataRadioTechnology()) + ")")
             .append(", mCssIndicator=").append(mCssIndicator ? "supported" : "unsupported")
             .append(", mNetworkId=").append(mNetworkId)
             .append(", mSystemId=").append(mSystemId)
             .append(", mCdmaRoamingIndicator=").append(mCdmaRoamingIndicator)
             .append(", mCdmaDefaultRoamingIndicator=").append(mCdmaDefaultRoamingIndicator)
             .append(", mIsEmergencyOnly=").append(mIsEmergencyOnly)
-            .append(", mIsUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
+            .append(", isUsingCarrierAggregation=").append(isUsingCarrierAggregation())
             .append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
             .append(", mNetworkRegistrationInfos=").append(mNetworkRegistrationInfos)
             .append(", mNrFrequencyRange=").append(mNrFrequencyRange)
             .append("}").toString();
     }
 
-    private void setNullState(int state) {
-        if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setNullState=" + state);
-        mVoiceRegState = state;
-        mDataRegState = state;
+    private void init() {
+        if (DBG) Rlog.d(LOG_TAG, "init");
+        mVoiceRegState = STATE_OUT_OF_SERVICE;
+        mDataRegState = STATE_OUT_OF_SERVICE;
         mChannelNumber = -1;
         mCellBandwidths = new int[0];
         mVoiceOperatorAlphaLong = null;
@@ -1065,8 +1035,6 @@
         mDataOperatorAlphaShort = null;
         mDataOperatorNumeric = null;
         mIsManualNetworkSelection = false;
-        mRilVoiceRadioTechnology = 0;
-        mRilDataRadioTechnology = 0;
         mCssIndicator = false;
         mNetworkId = -1;
         mSystemId = -1;
@@ -1075,18 +1043,28 @@
         mCdmaEriIconIndex = -1;
         mCdmaEriIconMode = -1;
         mIsEmergencyOnly = false;
-        mIsUsingCarrierAggregation = false;
         mLteEarfcnRsrpBoost = 0;
-        mNetworkRegistrationInfos = new ArrayList<>();
         mNrFrequencyRange = FREQUENCY_RANGE_UNKNOWN;
+        addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
+                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
+                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
+                .build());
+        addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
+                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
+                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
+                .build());
     }
 
     public void setStateOutOfService() {
-        setNullState(STATE_OUT_OF_SERVICE);
+        init();
     }
 
     public void setStateOff() {
-        setNullState(STATE_POWER_OFF);
+        init();
+        mVoiceRegState = STATE_POWER_OFF;
+        mDataRegState = STATE_POWER_OFF;
     }
 
     public void setState(int state) {
@@ -1304,8 +1282,8 @@
         m.putString("data-operator-alpha-short", mDataOperatorAlphaShort);
         m.putString("data-operator-numeric", mDataOperatorNumeric);
         m.putBoolean("manual", mIsManualNetworkSelection);
-        m.putInt("radioTechnology", mRilVoiceRadioTechnology);
-        m.putInt("dataRadioTechnology", mRilDataRadioTechnology);
+        m.putInt("radioTechnology", getRilVoiceRadioTechnology());
+        m.putInt("dataRadioTechnology", getRadioTechnology());
         m.putBoolean("cssIndicator", mCssIndicator);
         m.putInt("networkId", mNetworkId);
         m.putInt("systemId", mSystemId);
@@ -1313,7 +1291,7 @@
         m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
         m.putBoolean("emergencyOnly", mIsEmergencyOnly);
         m.putBoolean("isDataRoamingFromRegistration", getDataRoamingFromRegistration());
-        m.putBoolean("isUsingCarrierAggregation", mIsUsingCarrierAggregation);
+        m.putBoolean("isUsingCarrierAggregation", isUsingCarrierAggregation());
         m.putInt("LteEarfcnRsrpBoost", mLteEarfcnRsrpBoost);
         m.putInt("ChannelNumber", mChannelNumber);
         m.putIntArray("CellBandwidths", mCellBandwidths);
@@ -1323,13 +1301,9 @@
     /** @hide */
     @TestApi
     public void setRilVoiceRadioTechnology(@RilRadioTechnology int rt) {
-        if (rt == RIL_RADIO_TECHNOLOGY_LTE_CA) {
-            rt = RIL_RADIO_TECHNOLOGY_LTE;
-        }
-
-        this.mRilVoiceRadioTechnology = rt;
-
-        // sync to network registration state
+        Rlog.e(LOG_TAG, "ServiceState.setRilVoiceRadioTechnology() called. It's encouraged to "
+                + "use addNetworkRegistrationInfo() instead *******");
+        // Sync to network registration state
         NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         if (regState == null) {
@@ -1339,24 +1313,18 @@
                     .build();
             addNetworkRegistrationInfo(regState);
         }
-        regState.setAccessNetworkTechnology(
-                rilRadioTechnologyToNetworkType(mRilVoiceRadioTechnology));
+        regState.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
     }
 
+
     /** @hide */
     @TestApi
     public void setRilDataRadioTechnology(@RilRadioTechnology int rt) {
-        if (rt == RIL_RADIO_TECHNOLOGY_LTE_CA) {
-            rt = RIL_RADIO_TECHNOLOGY_LTE;
-            this.mIsUsingCarrierAggregation = true;
-        } else {
-            this.mIsUsingCarrierAggregation = false;
-        }
-        this.mRilDataRadioTechnology = rt;
-        if (VDBG) Rlog.d(LOG_TAG, "[ServiceState] setRilDataRadioTechnology=" +
-                mRilDataRadioTechnology);
-
-        // sync to network registration state
+        Rlog.e(LOG_TAG, "ServiceState.setRilDataRadioTechnology() called. It's encouraged to "
+                + "use addNetworkRegistrationInfo() instead *******");
+        // Sync to network registration state. Always write down the WWAN transport. For AP-assisted
+        // mode device, use addNetworkRegistrationInfo() to set the correct transport if RAT
+        // is IWLAN.
         NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
 
@@ -1367,18 +1335,32 @@
                     .build();
             addNetworkRegistrationInfo(regState);
         }
-        regState.setAccessNetworkTechnology(
-                rilRadioTechnologyToNetworkType(mRilDataRadioTechnology));
+        regState.setAccessNetworkTechnology(rilRadioTechnologyToNetworkType(rt));
     }
 
     /** @hide */
     public boolean isUsingCarrierAggregation() {
-        return mIsUsingCarrierAggregation;
+        NetworkRegistrationInfo nri = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        if (nri != null) {
+            DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
+            if (dsri != null) {
+                return dsri.isUsingCarrierAggregation();
+            }
+        }
+        return false;
     }
 
     /** @hide */
     public void setIsUsingCarrierAggregation(boolean ca) {
-        mIsUsingCarrierAggregation = ca;
+        NetworkRegistrationInfo nri = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        if (nri != null) {
+            DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
+            if (dsri != null) {
+                dsri.setIsUsingCarrierAggregation(ca);
+            }
+        }
     }
 
     /**
@@ -1435,12 +1417,29 @@
     /** @hide */
     @UnsupportedAppUsage
     public int getRilVoiceRadioTechnology() {
-        return this.mRilVoiceRadioTechnology;
+        NetworkRegistrationInfo wwanRegInfo = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        if (wwanRegInfo != null) {
+            return networkTypeToRilRadioTechnology(wwanRegInfo.getAccessNetworkTechnology());
+        }
+        return RIL_RADIO_TECHNOLOGY_UNKNOWN;
     }
     /** @hide */
     @UnsupportedAppUsage
     public int getRilDataRadioTechnology() {
-        return this.mRilDataRadioTechnology;
+        NetworkRegistrationInfo wwanRegInfo = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        NetworkRegistrationInfo wlanRegInfo = getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+        if (wlanRegInfo != null
+                && wlanRegInfo.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_IWLAN
+                && wlanRegInfo.getRegistrationState()
+                == NetworkRegistrationInfo.REGISTRATION_STATE_HOME) {
+            return RIL_RADIO_TECHNOLOGY_IWLAN;
+        } else if (wwanRegInfo != null) {
+            return networkTypeToRilRadioTechnology(wwanRegInfo.getAccessNetworkTechnology());
+        }
+        return RIL_RADIO_TECHNOLOGY_UNKNOWN;
     }
     /**
      * @hide
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 07ffaac..63d427a 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -17,18 +17,16 @@
 package android.telephony;
 
 import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
 import android.app.PendingIntent;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothMapClient;
-import android.bluetooth.BluetoothProfile;
 import android.content.ActivityNotFoundException;
 import android.content.ContentValues;
 import android.content.Context;
@@ -41,7 +39,6 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.telecom.PhoneAccount;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -50,6 +47,8 @@
 import com.android.internal.telephony.ISms;
 import com.android.internal.telephony.SmsRawData;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -72,7 +71,6 @@
  */
 public final class SmsManager {
     private static final String TAG = "SmsManager";
-    private static final boolean DBG = false;
 
     /**
      * A psuedo-subId that represents the default subId at any given time. The actual subId it
@@ -353,42 +351,11 @@
             throw new IllegalArgumentException("Invalid message body");
         }
 
-        // A Manager code accessing another manager is *not* acceptable, in Android.
-        // In this particular case, it is unavoidable because of the following:
-        // If the subscription for this SmsManager instance belongs to a remote SIM
-        // then a listener to get BluetoothMapClient proxy needs to be started up.
-        // Doing that is possible only in a foreground thread or as a system user.
-        // i.e., Can't be done in ISms service.
-        // For that reason, SubscriptionManager needs to be accessed here to determine
-        // if the subscription belongs to a remote SIM.
-        // Ideally, there should be another API in ISms to service messages going thru
-        // remote SIM subscriptions (and ISms should be tweaked to be able to access
-        // BluetoothMapClient proxy)
-        Context context = ActivityThread.currentApplication().getApplicationContext();
-        SubscriptionManager manager = (SubscriptionManager) context
-                .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-        int subId = getSubscriptionId();
-        SubscriptionInfo info = manager.getActiveSubscriptionInfo(subId);
-        if (DBG) {
-            Log.d(TAG, "for subId: " + subId + ", subscription-info: " + info);
-        }
-
-        /* If the Subscription associated with this SmsManager instance belongs to a remote-sim,
-         * then send the message thru the remote-sim subscription.
-         */
-        if (info != null
-                && info.getSubscriptionType() == SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM) {
-            if (DBG) Log.d(TAG, "sending message thru bluetooth");
-            sendTextMessageBluetooth(destinationAddress, scAddress, text, sentIntent,
-                    deliveryIntent, info);
-            return;
-        }
-
         try {
             // If the subscription is invalid or default, we will use the default phone to send the
             // SMS and possibly fail later in the SMS sending process.
-            ISms iccISms = getISmsServiceOrThrow();
-            iccISms.sendTextForSubscriber(subId, ActivityThread.currentPackageName(),
+            ISms iSms = getISmsServiceOrThrow();
+            iSms.sendTextForSubscriber(getSubscriptionId(), ActivityThread.currentPackageName(),
                     destinationAddress,
                     scAddress, text, sentIntent, deliveryIntent,
                     persistMessage);
@@ -397,82 +364,6 @@
         }
     }
 
-    private void sendTextMessageBluetooth(String destAddr, String scAddress,
-            String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
-            SubscriptionInfo info) {
-        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (btAdapter == null) {
-            // No bluetooth service on this platform?
-            sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_NO_SERVICE);
-            return;
-        }
-        BluetoothDevice device = btAdapter.getRemoteDevice(info.getIccId());
-        if (device == null) {
-            if (DBG) Log.d(TAG, "Bluetooth device addr invalid: " + info.getIccId());
-            sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_NO_SERVICE);
-            return;
-        }
-        btAdapter.getProfileProxy(ActivityThread.currentApplication().getApplicationContext(),
-                new MapMessageSender(destAddr, text, device, sentIntent, deliveryIntent),
-                BluetoothProfile.MAP_CLIENT);
-    }
-
-    private class MapMessageSender implements BluetoothProfile.ServiceListener {
-        final Uri[] mDestAddr;
-        private String mMessage;
-        final BluetoothDevice mDevice;
-        final PendingIntent mSentIntent;
-        final PendingIntent mDeliveryIntent;
-        MapMessageSender(final String destAddr, final String message, final BluetoothDevice device,
-                final PendingIntent sentIntent, final PendingIntent deliveryIntent) {
-            super();
-            mDestAddr = new Uri[] {new Uri.Builder()
-                    .appendPath(destAddr)
-                    .scheme(PhoneAccount.SCHEME_TEL)
-                    .build()};
-            mMessage = message;
-            mDevice = device;
-            mSentIntent = sentIntent;
-            mDeliveryIntent = deliveryIntent;
-        }
-
-        @Override
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (DBG) Log.d(TAG, "Service connected");
-            if (profile != BluetoothProfile.MAP_CLIENT) return;
-            BluetoothMapClient mapProfile = (BluetoothMapClient) proxy;
-            if (mMessage != null) {
-                if (DBG) Log.d(TAG, "Sending message thru bluetooth");
-                mapProfile.sendMessage(mDevice, mDestAddr, mMessage, mSentIntent, mDeliveryIntent);
-                mMessage = null;
-            }
-            BluetoothAdapter.getDefaultAdapter()
-                    .closeProfileProxy(BluetoothProfile.MAP_CLIENT, mapProfile);
-        }
-
-        @Override
-        public void onServiceDisconnected(int profile) {
-            if (mMessage != null) {
-                if (DBG) Log.d(TAG, "Bluetooth disconnected before sending the message");
-                sendErrorInPendingIntent(mSentIntent, SmsManager.RESULT_ERROR_NO_SERVICE);
-                mMessage = null;
-            }
-        }
-    }
-
-    private void sendErrorInPendingIntent(PendingIntent intent, int errorCode) {
-        if (intent == null) {
-            return;
-        }
-        try {
-            intent.send(errorCode);
-        } catch (PendingIntent.CanceledException e) {
-            // PendingIntent is cancelled. ignore sending this error code back to
-            // caller.
-            if (DBG) Log.d(TAG, "PendingIntent.CanceledException: " + e.getMessage());
-        }
-    }
-
     /**
      * Send a text based SMS without writing it into the SMS Provider.
      *
@@ -522,8 +413,8 @@
         }
 
         try {
-            ISms iccISms = getISmsServiceOrThrow();
-            iccISms.sendTextForSubscriberWithSelfPermissions(getSubscriptionId(),
+            ISms iSms = getISmsServiceOrThrow();
+            iSms.sendTextForSubscriberWithSelfPermissions(getSubscriptionId(),
                     ActivityThread.currentPackageName(),
                     destinationAddress,
                     scAddress, text, sentIntent, deliveryIntent, persistMessage);
@@ -606,9 +497,9 @@
         }
 
         try {
-             ISms iccISms = getISmsServiceOrThrow();
-            if (iccISms != null) {
-                iccISms.sendTextForSubscriberWithOptions(getSubscriptionId(),
+            ISms iSms = getISmsServiceOrThrow();
+            if (iSms != null) {
+                iSms.sendTextForSubscriberWithOptions(getSubscriptionId(),
                         ActivityThread.currentPackageName(), destinationAddress, scAddress, text,
                         sentIntent, deliveryIntent, persistMessage,  priority, expectMore,
                         validityPeriod);
@@ -667,9 +558,9 @@
                     "Invalid pdu format. format must be either 3gpp or 3gpp2");
         }
         try {
-            ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            if (iccISms != null) {
-                iccISms.injectSmsPduForSubscriber(
+            ISms iSms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+            if (iSms != null) {
+                iSms.injectSmsPduForSubscriber(
                         getSubscriptionId(), pdu, format, receivedIntent);
             }
         } catch (RemoteException ex) {
@@ -755,8 +646,8 @@
 
         if (parts.size() > 1) {
             try {
-                ISms iccISms = getISmsServiceOrThrow();
-                iccISms.sendMultipartTextForSubscriber(getSubscriptionId(),
+                ISms iSms = getISmsServiceOrThrow();
+                iSms.sendMultipartTextForSubscriber(getSubscriptionId(),
                         ActivityThread.currentPackageName(),
                         destinationAddress, scAddress, parts,
                         sentIntents, deliveryIntents, persistMessage);
@@ -887,9 +778,9 @@
 
         if (parts.size() > 1) {
             try {
-                 ISms iccISms = getISmsServiceOrThrow();
-                if (iccISms != null) {
-                    iccISms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
+                ISms iSms = getISmsServiceOrThrow();
+                if (iSms != null) {
+                    iSms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
                             ActivityThread.currentPackageName(), destinationAddress, scAddress,
                             parts, sentIntents, deliveryIntents, persistMessage, priority,
                             expectMore, validityPeriod);
@@ -975,8 +866,8 @@
         }
 
         try {
-            ISms iccISms = getISmsServiceOrThrow();
-            iccISms.sendDataForSubscriber(getSubscriptionId(), ActivityThread.currentPackageName(),
+            ISms iSms = getISmsServiceOrThrow();
+            iSms.sendDataForSubscriber(getSubscriptionId(), ActivityThread.currentPackageName(),
                     destinationAddress, scAddress, destinationPort & 0xFFFF,
                     data, sentIntent, deliveryIntent);
         } catch (RemoteException ex) {
@@ -1002,8 +893,8 @@
         }
 
         try {
-            ISms iccISms = getISmsServiceOrThrow();
-            iccISms.sendDataForSubscriberWithSelfPermissions(getSubscriptionId(),
+            ISms iSms = getISmsServiceOrThrow();
+            iSms.sendDataForSubscriberWithSelfPermissions(getSubscriptionId(),
                     ActivityThread.currentPackageName(), destinationAddress, scAddress,
                     destinationPort & 0xFFFF, data, sentIntent, deliveryIntent);
         } catch (RemoteException ex) {
@@ -1060,14 +951,13 @@
      * @return associated subscription id
      */
     public int getSubscriptionId() {
-        final int subId = (mSubId == DEFAULT_SUBSCRIPTION_ID)
-                ? getDefaultSmsSubscriptionId() : mSubId;
+        final int subId = getSubIdOrDefault();
         boolean isSmsSimPickActivityNeeded = false;
         final Context context = ActivityThread.currentApplication().getApplicationContext();
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                isSmsSimPickActivityNeeded = iccISms.isSmsSimPickActivityNeeded(subId);
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                isSmsSimPickActivityNeeded = iSms.isSmsSimPickActivityNeeded(subId);
             }
         } catch (RemoteException ex) {
             Log.e(TAG, "Exception in getSubscriptionId");
@@ -1094,15 +984,26 @@
     }
 
     /**
+     * @return the subscription ID associated with this {@link SmsManager} or the default set by the
+     * user if this instance was created using {@link SmsManager#getDefault}.
+     *
+     * If there is no default set by the user, this method returns
+     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
+     */
+    private int getSubIdOrDefault() {
+        return (mSubId == DEFAULT_SUBSCRIPTION_ID) ? getDefaultSmsSubscriptionId() : mSubId;
+    }
+
+    /**
      * Returns the ISms service, or throws an UnsupportedOperationException if
      * the service does not exist.
      */
     private static ISms getISmsServiceOrThrow() {
-        ISms iccISms = getISmsService();
-        if (iccISms == null) {
+        ISms iSms = getISmsService();
+        if (iSms == null) {
             throw new UnsupportedOperationException("Sms is not supported");
         }
-        return iccISms;
+        return iSms;
     }
 
     private static ISms getISmsService() {
@@ -1131,9 +1032,9 @@
             throw new IllegalArgumentException("pdu is NULL");
         }
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                success = iccISms.copyMessageToIccEfForSubscriber(getSubscriptionId(),
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                success = iSms.copyMessageToIccEfForSubscriber(getSubscriptionId(),
                         ActivityThread.currentPackageName(),
                         status, pdu, smsc);
             }
@@ -1162,9 +1063,9 @@
         Arrays.fill(pdu, (byte)0xff);
 
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                success = iccISms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
                         ActivityThread.currentPackageName(),
                         messageIndex, STATUS_ON_ICC_FREE, pdu);
             }
@@ -1194,9 +1095,9 @@
         boolean success = false;
 
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                success = iccISms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
                         ActivityThread.currentPackageName(),
                         messageIndex, newStatus, pdu);
             }
@@ -1221,9 +1122,9 @@
         List<SmsRawData> records = null;
 
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                records = iccISms.getAllMessagesFromIccEfForSubscriber(
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                records = iSms.getAllMessagesFromIccEfForSubscriber(
                         getSubscriptionId(),
                         ActivityThread.currentPackageName());
             }
@@ -1258,10 +1159,11 @@
         boolean success = false;
 
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                success = iccISms.enableCellBroadcastForSubscriber(
-                        getSubscriptionId(), messageIdentifier, ranType);
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                // If getSubIdOrDefault() returns INVALID, we will use the default phone internally.
+                success = iSms.enableCellBroadcastForSubscriber(getSubIdOrDefault(),
+                        messageIdentifier, ranType);
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1294,10 +1196,11 @@
         boolean success = false;
 
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                success = iccISms.disableCellBroadcastForSubscriber(
-                        getSubscriptionId(), messageIdentifier, ranType);
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                // If getSubIdOrDefault() returns INVALID, we will use the default phone internally.
+                success = iSms.disableCellBroadcastForSubscriber(getSubIdOrDefault(),
+                        messageIdentifier, ranType);
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1337,9 +1240,10 @@
             throw new IllegalArgumentException("endMessageId < startMessageId");
         }
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                success = iccISms.enableCellBroadcastRangeForSubscriber(getSubscriptionId(),
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                // If getSubIdOrDefault() returns INVALID, we will use the default phone internally.
+                success = iSms.enableCellBroadcastRangeForSubscriber(getSubIdOrDefault(),
                         startMessageId, endMessageId, ranType);
             }
         } catch (RemoteException ex) {
@@ -1380,9 +1284,10 @@
             throw new IllegalArgumentException("endMessageId < startMessageId");
         }
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                success = iccISms.disableCellBroadcastRangeForSubscriber(getSubscriptionId(),
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                // If getSubIdOrDefault() returns INVALID, we will use the default phone internally.
+                success = iSms.disableCellBroadcastRangeForSubscriber(getSubIdOrDefault(),
                         startMessageId, endMessageId, ranType);
             }
         } catch (RemoteException ex) {
@@ -1432,9 +1337,9 @@
     public boolean isImsSmsSupported() {
         boolean boSupported = false;
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                boSupported = iccISms.isImsSmsSupportedForSubscriber(getSubscriptionId());
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                boSupported = iSms.isImsSmsSupportedForSubscriber(getSubscriptionId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1457,9 +1362,9 @@
     public String getImsSmsFormat() {
         String format = com.android.internal.telephony.SmsConstants.FORMAT_UNKNOWN;
         try {
-            ISms iccISms = getISmsService();
-            if (iccISms != null) {
-                format = iccISms.getImsSmsFormatForSubscriber(getSubscriptionId());
+            ISms iSms = getISmsService();
+            if (iSms != null) {
+                format = iSms.getImsSmsFormatForSubscriber(getSubscriptionId());
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1473,10 +1378,10 @@
      * @return the default SMS subscription id
      */
     public static int getDefaultSmsSubscriptionId() {
-        ISms iccISms = null;
+        ISms iSms = null;
         try {
-            iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            return iccISms.getPreferredSmsSubscription();
+            iSms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+            return iSms.getPreferredSmsSubscription();
         } catch (RemoteException ex) {
             return -1;
         } catch (NullPointerException ex) {
@@ -1492,10 +1397,10 @@
      */
     @UnsupportedAppUsage
     public boolean isSMSPromptEnabled() {
-        ISms iccISms = null;
+        ISms iSms = null;
         try {
-            iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
-            return iccISms.isSMSPromptEnabled();
+            iSms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+            return iSms.isSMSPromptEnabled();
         } catch (RemoteException ex) {
             return false;
         } catch (NullPointerException ex) {
@@ -1972,8 +1877,8 @@
             throw new IllegalArgumentException("Empty message URI");
         }
         try {
-            ISms iccISms = getISmsServiceOrThrow();
-            iccISms.sendStoredText(
+            ISms iSms = getISmsServiceOrThrow();
+            iSms.sendStoredText(
                     getSubscriptionId(), ActivityThread.currentPackageName(), messageUri,
                     scAddress, sentIntent, deliveryIntent);
         } catch (RemoteException ex) {
@@ -2020,8 +1925,8 @@
             throw new IllegalArgumentException("Empty message URI");
         }
         try {
-            ISms iccISms = getISmsServiceOrThrow();
-            iccISms.sendStoredMultipartText(
+            ISms iSms = getISmsServiceOrThrow();
+            iSms.sendStoredMultipartText(
                     getSubscriptionId(), ActivityThread.currentPackageName(), messageUri,
                     scAddress, sentIntents, deliveryIntents);
         } catch (RemoteException ex) {
@@ -2327,4 +2232,84 @@
         return filtered;
     }
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"SMS_CATEGORY_"},
+            value = {
+                    SmsManager.SMS_CATEGORY_NOT_SHORT_CODE,
+                    SmsManager.SMS_CATEGORY_FREE_SHORT_CODE,
+                    SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE,
+                    SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE,
+                    SmsManager.SMS_CATEGORY_PREMIUM_SHORT_CODE})
+    public @interface SmsShortCodeCategory {}
+
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for regular
+     * phone numbers.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0;
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for free
+     * (no cost) short codes.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1;
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
+     * standard rate (non-premium)
+     * short codes.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2;
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for possible
+     * premium short codes.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
+     * premium short codes.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4;
+
+    /**
+     * Check if the destination address is a possible premium short code.
+     * NOTE: the caller is expected to strip non-digits from the destination number with
+     * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
+     *
+     * @param destAddress the destination address to test for possible short code
+     * @param countryIso the ISO country code
+     *
+     * @return
+     * {@link SmsManager#SMS_CATEGORY_NOT_SHORT_CODE},
+     * {@link SmsManager#SMS_CATEGORY_FREE_SHORT_CODE},
+     * {@link SmsManager#SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE},
+     * {@link SmsManager#SMS_CATEGORY_PREMIUM_SHORT_CODE}, or
+     * {@link SmsManager#SMS_CATEGORY_STANDARD_SHORT_CODE}
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @TestApi
+    public @SmsShortCodeCategory int checkSmsShortCodeDestination(
+            String destAddress, String countryIso) {
+        try {
+            ISms iccISms = getISmsServiceOrThrow();
+            if (iccISms != null) {
+                return iccISms.checkSmsShortCodeDestination(getSubscriptionId(),
+                        ActivityThread.currentPackageName(), destAddress, countryIso);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "checkSmsShortCodeDestination() RemoteException", e);
+        }
+        return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
+    }
 }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 14eac87..a933da7 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2587,8 +2587,7 @@
      *              {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}.
      * @param executor The executor of where the callback will execute.
      * @param callback Callback will be triggered once it succeeds or failed.
-     *                 See {@link TelephonyManager.SetOpportunisticSubscriptionResult}
-     *                 for more details. Pass null if don't care about the result.
+     *                 Pass null if don't care about the result.
      *
      * @hide
      *
@@ -2596,7 +2595,8 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
-            @Nullable @CallbackExecutor Executor executor, @Nullable  Consumer<Integer> callback) {
+            @Nullable @CallbackExecutor Executor executor, @Nullable
+            @TelephonyManager.SetOpportunisticSubscriptionResult Consumer<Integer> callback) {
         if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 5df7bf7..f393cba 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1321,7 +1321,7 @@
 
     /**
      * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} to indicate the
-     * subscription which has changed.
+     * subscription which has changed; or in general whenever a subscription ID needs specified.
      */
     public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.extra.SUBSCRIPTION_ID";
 
@@ -1439,13 +1439,24 @@
 
     /**
      * Integer intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED}
-     * to indicate whether a SIM selection is needed to choose default subscription.
+     * to indicate what type of SIM selection is needed.
      *
      * @hide
      */
     public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE =
             "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE";
 
+    /** @hide */
+    @IntDef({
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE,
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA,
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_VOICE,
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_SMS,
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DefaultSubscriptionSelectType{}
+
     /**
      * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
      * to indicate there's no need to re-select any default subscription.
@@ -1477,20 +1488,11 @@
     /**
      * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
      * to indicate user to decide whether current SIM should be preferred for all
-     * data / voice / sms.
+     * data / voice / sms. {@link #EXTRA_SUBSCRIPTION_ID} will specified to indicate
+     * which subscription should be the default subscription.
      * @hide
      */
-    public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES = 4;
-
-    /**
-     * Integer intent extra to be used with
-     * {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES}
-     * to indicate which SIM is being selected.
-     *
-     * @hide
-     */
-    public static final String EXTRA_DEFAULT_SUBSCRIPTION_ID =
-            "android.telephony.extra.DEFAULT_SUBSCRIPTION_ID";
+    public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4;
 
     //
     //
@@ -4843,22 +4845,18 @@
      * Registers a listener object to receive notification of changes
      * in specified telephony states.
      * <p>
-     * To register a listener, pass a {@link PhoneStateListener} and specify at least one telephony
-     * state of interest in the events argument.
+     * To register a listener, pass a {@link PhoneStateListener}
+     * and specify at least one telephony state of interest in
+     * the events argument.
      *
-     * At registration, and when a specified telephony state changes, the telephony manager invokes
-     * the appropriate callback method on the listener object and passes the current (updated)
-     * values.
+     * At registration, and when a specified telephony state
+     * changes, the telephony manager invokes the appropriate
+     * callback method on the listener object and passes the
+     * current (updated) values.
      * <p>
-     * To un-register a listener, pass the listener object and set the events argument to
+     * To unregister a listener, pass the listener object and set the
+     * events argument to
      * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0).
-     *
-     * If this TelephonyManager object has been created with {@link #createForSubscriptionId},
-     * applies to the given subId. Otherwise, applies to
-     * {@link SubscriptionManager#getDefaultSubscriptionId()}. To listen events for multiple subIds,
-     * pass a separate listener object to each TelephonyManager object created with
-     * {@link #createForSubscriptionId}.
-     *
      * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
      * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
      * {@link SecurityException} will be thrown otherwise.
@@ -4873,18 +4871,17 @@
         if (mContext == null) return;
         try {
             boolean notifyNow = (getITelephony() != null);
+            // If the listener has not explicitly set the subId (for example, created with the
+            // default constructor), replace the subId so it will listen to the account the
+            // telephony manager is created with.
+            if (listener.mSubId == null) {
+                listener.mSubId = mSubId;
+            }
+
             ITelephonyRegistry registry = getTelephonyRegistry();
             if (registry != null) {
-                // listen to the subId the telephony manager is created with. Ignore subId in
-                // PhoneStateListener.
-                registry.listenForSubscriber(mSubId, getOpPackageName(),
+                registry.listenForSubscriber(listener.mSubId, getOpPackageName(),
                         listener.callback, events, notifyNow);
-                // TODO: remove this once we remove PhoneStateListener constructor with subId.
-                if (events == PhoneStateListener.LISTEN_NONE) {
-                    listener.mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-                } else {
-                    listener.mSubId = mSubId;
-                }
             } else {
                 Rlog.w(TAG, "telephony registry not ready.");
             }
@@ -6957,6 +6954,17 @@
      * app has carrier privileges (see {@link #hasCarrierPrivileges})
      * and {@link android.Manifest.permission#ACCESS_FINE_LOCATION}.
      *
+     * If the system-wide location switch is off, apps may still call this API, with the
+     * following constraints:
+     * <ol>
+     *     <li>The app must hold the {@code android.permission.NETWORK_SCAN} permission.</li>
+     *     <li>The app must not supply any specific bands or channels to scan.</li>
+     *     <li>The app must only specify MCC/MNC pairs that are
+     *     associated to a SIM in the device.</li>
+     *     <li>Returned results will have no meaningful info other than signal strength
+     *     and MCC/MNC info.</li>
+     * </ol>
+     *
      * @param request Contains all the RAT with bands/channels that need to be scanned.
      * @param executor The executor through which the callback should be invoked. Since the scan
      *        request may trigger multiple callbacks and they must be invoked in the same order as
@@ -7195,10 +7203,21 @@
      * @hide
      */
     public boolean getTetherApnRequired() {
+        return getTetherApnRequired(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
+    }
+
+    /**
+     * Check whether DUN APN is required for tethering with subId.
+     *
+     * @param subId the id of the subscription to require tethering.
+     * @return {@code true} if DUN APN is required for tethering.
+     * @hide
+     */
+    public boolean getTetherApnRequired(int subId) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                return telephony.getTetherApnRequired();
+                return telephony.getTetherApnRequiredForSubscriber(subId);
         } catch (RemoteException ex) {
             Rlog.e(TAG, "hasMatchedTetherApnSetting RemoteException", ex);
         } catch (NullPointerException ex) {
@@ -10539,6 +10558,9 @@
     /**
      * Set preferred opportunistic data subscription id.
      *
+     * Switch internet data to preferred opportunistic data subscription id. This api
+     * can result in lose of internet connectivity for short period of time while internet data
+     * is handed over.
      * <p>Requires that the calling app has carrier privileges on both primary and
      * secondary subscriptions (see
      * {@link #hasCarrierPrivileges}), or has permission
@@ -10617,9 +10639,11 @@
      *
      * This api should be called to inform OpportunisticNetwork Service about the availability
      * of a network at the current location. This information will be used by OpportunisticNetwork
-     * service to decide to attach to the network opportunistically. If an empty list is passed,
+     * service to enable modem stack and to attach to the network. If an empty list is passed,
      * it is assumed that no network is available and will result in disabling the modem stack
-     * to save power.
+     * to save power. This api do not switch internet data once network attach is completed.
+     * Use {@link TelephonyManager#setPreferredOpportunisticDataSubscription}
+     * to switch internet data after network attach is complete.
      * Requires that the calling app has carrier privileges on both primary and
      * secondary subscriptions (see {@link #hasCarrierPrivileges}), or has permission
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
@@ -10690,6 +10714,25 @@
     }
 
     /**
+     * It indicates whether modem is enabled or not per slot.
+     * It's the corresponding status of {@link #enableModemForSlot}.
+     *
+     * @param slotIndex which slot it's checking.
+     * @hide
+     */
+    public boolean isModemEnabledForSlot(int slotIndex) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.isModemEnabledForSlot(slotIndex, mContext.getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+            Log.e(TAG, "enableModem RemoteException", ex);
+        }
+        return false;
+    }
+
+    /**
      * Broadcast intent action for network country code changes.
      *
      * <p>
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index 91f74b8..28747da 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -53,6 +53,11 @@
     public static final int CALLBACK_SCAN_ERROR = 2;
     /** @hide */
     public static final int CALLBACK_SCAN_COMPLETE = 3;
+    /** @hide */
+    public static final int CALLBACK_RESTRICTED_SCAN_RESULTS = 4;
+
+    /** @hide */
+    public static final int INVALID_SCAN_ID = -1;
 
     /**
      * The caller of
@@ -129,6 +134,7 @@
                 }
 
                 switch (message.what) {
+                    case CALLBACK_RESTRICTED_SCAN_RESULTS:
                     case CALLBACK_SCAN_RESULTS:
                         try {
                             final Bundle b = message.getData();
@@ -137,9 +143,9 @@
                             for (int i = 0; i < parcelables.length; i++) {
                                 ci[i] = (CellInfo) parcelables[i];
                             }
-                            executor.execute(() ->{
+                            executor.execute(() -> {
                                 Rlog.d(TAG, "onResults: " + ci.toString());
-                                callback.onResults((List<CellInfo>) Arrays.asList(ci));
+                                callback.onResults(Arrays.asList(ci));
                             });
                         } catch (Exception e) {
                             Rlog.e(TAG, "Exception in networkscan callback onResults", e);
@@ -200,6 +206,10 @@
             if (telephony != null) {
                 int scanId = telephony.requestNetworkScan(
                         subId, request, mMessenger, new Binder(), callingPackage);
+                if (scanId == INVALID_SCAN_ID) {
+                    Rlog.e(TAG, "Failed to initiate network scan");
+                    return null;
+                }
                 saveScanInfo(scanId, request, executor, callback);
                 return new NetworkScan(scanId, subId);
             }
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index cde10ea..96a2514 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -485,7 +485,7 @@
     public boolean isEnabled() {
         // In the future, this may reach out to IEuiccController (if non-null) to check any dynamic
         // restrictions.
-        return getIEuiccController() != null;
+        return getIEuiccController() != null && refreshCardIdIfUninitialized();
     }
 
     /**
@@ -499,7 +499,7 @@
      */
     @Nullable
     public String getEid() {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             return null;
         }
         try {
@@ -522,7 +522,7 @@
     @SystemApi
     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     public int getOtaStatus() {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             return EUICC_OTA_STATUS_UNAVAILABLE;
         }
         try {
@@ -557,7 +557,7 @@
     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     public void downloadSubscription(DownloadableSubscription subscription,
             boolean switchAfterDownload, PendingIntent callbackIntent) {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             sendUnavailableError(callbackIntent);
             return;
         }
@@ -619,7 +619,7 @@
     @SystemApi
     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             PendingIntent callbackIntent =
                     resolutionIntent.getParcelableExtra(
                             EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
@@ -656,7 +656,7 @@
     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     public void getDownloadableSubscriptionMetadata(
             DownloadableSubscription subscription, PendingIntent callbackIntent) {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             sendUnavailableError(callbackIntent);
             return;
         }
@@ -686,7 +686,7 @@
     @SystemApi
     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             sendUnavailableError(callbackIntent);
             return;
         }
@@ -705,7 +705,7 @@
      */
     @Nullable
     public EuiccInfo getEuiccInfo() {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             return null;
         }
         try {
@@ -730,7 +730,7 @@
      */
     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             sendUnavailableError(callbackIntent);
             return;
         }
@@ -770,7 +770,7 @@
      */
     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             sendUnavailableError(callbackIntent);
             return;
         }
@@ -796,7 +796,7 @@
     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     public void updateSubscriptionNickname(
             int subscriptionId, @Nullable String nickname, @NonNull PendingIntent callbackIntent) {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             sendUnavailableError(callbackIntent);
             return;
         }
@@ -820,7 +820,7 @@
     @SystemApi
     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     public void eraseSubscriptions(PendingIntent callbackIntent) {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             sendUnavailableError(callbackIntent);
             return;
         }
@@ -850,7 +850,7 @@
      * @hide
      */
     public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) {
-        if (!refreshCardIdIfUninitialized()) {
+        if (!isEnabled()) {
             sendUnavailableError(callbackIntent);
             return;
         }
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 8cdf6a2..cc037e3 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.StringDef;
 import android.annotation.SystemApi;
 import android.annotation.WorkerThread;
 import android.content.Context;
@@ -38,25 +39,36 @@
 
 import com.android.internal.telephony.ITelephony;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.concurrent.Executor;
 
 /**
  * Manages IMS provisioning and configuration parameters, as well as callbacks for apps to listen
  * to changes in these configurations.
  *
- * Note: IMS provisioning keys are defined per carrier or OEM using OMA-DM or other provisioning
- * applications and may vary. For compatibility purposes, the first 100 integer values used in
- * {@link #setProvisioningIntValue(int, int)} have been reserved for existing provisioning keys
- * previously defined in the Android framework. Some common constants have been defined in this
- * class to make integrating with other system apps easier. USE WITH CARE!
+ * IMS provisioning keys are defined per carrier or OEM using OMA-DM or other provisioning
+ * applications and may vary. It is up to the carrier and OEM applications to ensure that the
+ * correct provisioning keys are being used when integrating with a vendor's ImsService.
  *
- * To avoid collisions, please use String based configurations when possible:
- * {@link #setProvisioningStringValue(int, String)} and {@link #getProvisioningStringValue(int)}.
+ * Note: For compatibility purposes, the integer values [0 - 99] used in
+ * {@link #setProvisioningIntValue(int, int)} have been reserved for existing provisioning keys
+ * previously defined in the Android framework. Please do not redefine new provisioning keys in this
+ * range or it may generate collisions with existing keys. Some common constants have also been
+ * defined in this class to make integrating with other system apps easier.
  * @hide
  */
 @SystemApi
 public class ProvisioningManager {
 
+    /**@hide*/
+    @StringDef(prefix = "STRING_QUERY_RESULT_ERROR_", value = {
+            STRING_QUERY_RESULT_ERROR_GENERIC,
+            STRING_QUERY_RESULT_ERROR_NOT_READY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StringResultError {}
+
     /**
      * The query from {@link #getProvisioningStringValue(int)} has resulted in an unspecified error.
      */
@@ -268,14 +280,13 @@
      * This operation is blocking and should not be performed on the UI thread.
      *
      * @param key A String that represents the provisioning key, which is defined by the OEM.
-     * @return a String value for the provided key, {@code null} if the key doesn't exist, or one
-     * of the following error codes: {@link #STRING_QUERY_RESULT_ERROR_GENERIC},
-     * {@link #STRING_QUERY_RESULT_ERROR_NOT_READY}.
+     * @return a String value for the provided key, {@code null} if the key doesn't exist, or
+     * {@link StringResultError} if there was an error getting the value for the provided key.
      * @throws IllegalArgumentException if the key provided was invalid.
      */
     @WorkerThread
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public @Nullable String getProvisioningStringValue(int key) {
+    public @Nullable @StringResultError String getProvisioningStringValue(int key) {
         try {
             return getITelephony().getImsProvisioningString(mSubId, key);
         } catch (RemoteException e) {
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index b51eda3..c34feed 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -588,4 +588,11 @@
      */
     void getSmsMessagesForFinancialApp(
         int subId, String callingPkg, in Bundle params, in IFinancialSmsCallback callback);
+
+    /**
+     * Check if the destination is a possible premium short code.
+     *
+     * @param destAddress the destination address to test for possible short code
+     */
+    int checkSmsShortCodeDestination(int subId, String callingApk, String destAddress, String countryIso);
 }
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index 12c5c30..aa1f94f 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -202,4 +202,10 @@
             int subId, String callingPkg, Bundle params, IFinancialSmsCallback callback) {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public int checkSmsShortCodeDestination(
+            int subid, String callingApk, String destAddress, String countryIso) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d98f8d8..8332ffe 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -788,12 +788,13 @@
     int getPreferredNetworkType(int subId);
 
     /**
-     * Check whether DUN APN is required for tethering.
+     * Check whether DUN APN is required for tethering with subId.
      *
+     * @param subId the id of the subscription to require tethering.
      * @return {@code true} if DUN APN is required for tethering.
      * @hide
      */
-    boolean getTetherApnRequired();
+    boolean getTetherApnRequiredForSubscriber(int subId);
 
     /**
     * Enables framework IMS and triggers IMS Registration.
@@ -1957,5 +1958,7 @@
     /**
      * Get the IRadio HAL Version encoded as 100 * MAJOR_VERSION + MINOR_VERSION or -1 if unknown
      */
-     int getRadioHalVersion();
+    int getRadioHalVersion();
+
+    boolean isModemEnabledForSlot(int slotIndex, String callingPackage);
 }
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 4886a3f..c9b038c 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -123,6 +123,19 @@
                 context, TELEPHONY_SUPPLIER, subId, pid, uid, callingPackage, message);
     }
 
+    /**
+     * Check whether the calling packages has carrier privileges for the passing subscription.
+     * @return {@code true} if the caller has carrier privileges, {@false} otherwise.
+     */
+    public static boolean checkCarrierPrivilegeForSubId(int subId) {
+        if (SubscriptionManager.isValidSubscriptionId(subId)
+                && getCarrierPrivilegeStatus(TELEPHONY_SUPPLIER, subId, Binder.getCallingUid())
+                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+            return true;
+        }
+        return false;
+    }
+
     @VisibleForTesting
     public static boolean checkReadPhoneState(
             Context context, Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid,
@@ -151,6 +164,63 @@
         // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been
         // revoked.
         AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        return appOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, uid, callingPackage)
+                == AppOpsManager.MODE_ALLOWED;
+    }
+
+    /**
+     * Check whether the app with the given pid/uid can read phone state, or has carrier
+     * privileges on any active subscription.
+     *
+     * <p>If the app does not have carrier privilege, this method will return {@code false} instead
+     * of throwing a SecurityException. Therefore, the callers cannot tell the difference
+     * between M+ apps which declare the runtime permission but do not have it, and pre-M apps
+     * which declare the static permission but had access revoked via AppOps. Apps in the former
+     * category expect SecurityExceptions; apps in the latter don't. So this method is suitable for
+     * use only if the behavior in both scenarios is meant to be identical.
+     *
+     * @return {@code true} if the app can read phone state or has carrier privilege;
+     *         {@code false} otherwise.
+     */
+    public static boolean checkReadPhoneStateOnAnyActiveSub(
+            Context context, int pid, int uid, String callingPackage, String message) {
+        return checkReadPhoneStateOnAnyActiveSub(context, TELEPHONY_SUPPLIER, pid, uid,
+                    callingPackage, message);
+    }
+
+    @VisibleForTesting
+    public static boolean checkReadPhoneStateOnAnyActiveSub(
+            Context context, Supplier<ITelephony> telephonySupplier, int pid, int uid,
+            String callingPackage, String message) {
+        try {
+            context.enforcePermission(
+                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid, uid, message);
+
+            // SKIP checking for run-time permission since caller has PRIVILEGED permission
+            return true;
+        } catch (SecurityException privilegedPhoneStateException) {
+            try {
+                context.enforcePermission(
+                        android.Manifest.permission.READ_PHONE_STATE, pid, uid, message);
+            } catch (SecurityException phoneStateException) {
+                SubscriptionManager sm = (SubscriptionManager) context.getSystemService(
+                        Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+                int[] activeSubIds = sm.getActiveSubscriptionIdList();
+                for (int activeSubId : activeSubIds) {
+                    // If we don't have the runtime permission, but do have carrier privileges, that
+                    // suffices for reading phone state.
+                    if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid)
+                            == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+
+        // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been
+        // revoked.
+        AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
         return appOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, uid, callingPackage) ==
                 AppOpsManager.MODE_ALLOWED;
     }
@@ -204,9 +274,7 @@
         }
         // Calling packages with carrier privileges will also have access to device identifiers, but
         // this may be removed in a future release.
-        if (SubscriptionManager.isValidSubscriptionId(subId) && getCarrierPrivilegeStatus(
-                TELEPHONY_SUPPLIER, subId, uid)
-                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+        if (checkCarrierPrivilegeForSubId(subId)) {
             return true;
         }
         // else the calling package is not authorized to access the device identifiers; call
@@ -243,9 +311,7 @@
         }
         // If the calling package has carrier privileges then allow access to the subscriber
         // identifiers.
-        if (SubscriptionManager.isValidSubscriptionId(subId) && getCarrierPrivilegeStatus(
-                TELEPHONY_SUPPLIER, subId, uid)
-                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+        if (checkCarrierPrivilegeForSubId(subId)) {
             return true;
         }
         return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
@@ -279,8 +345,8 @@
         // Allow access to a device / profile owner app.
         DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
-        if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccessAsUser(
-                callingPackage, Binder.getCallingUserHandle().getIdentifier())) {
+        if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccess(
+                callingPackage, pid, uid)) {
             return true;
         }
         return false;
@@ -365,9 +431,7 @@
                         uid) == PackageManager.PERMISSION_GRANTED) {
                     return false;
                 }
-                if (SubscriptionManager.isValidSubscriptionId(subId)
-                        && getCarrierPrivilegeStatus(TELEPHONY_SUPPLIER, subId, uid)
-                        == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+                if (checkCarrierPrivilegeForSubId(subId)) {
                     return false;
                 }
             }
diff --git a/tests/FlickerTests/AndroidTest.xml b/tests/FlickerTests/AndroidTest.xml
index 41cb74a..e36f976 100644
--- a/tests/FlickerTests/AndroidTest.xml
+++ b/tests/FlickerTests/AndroidTest.xml
@@ -17,6 +17,7 @@
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="com.android.server.wm.flicker"/>
+        <option name="exclude-annotation" value="org.junit.Ignore" />
         <option name="shell-timeout" value="6600s" />
         <option name="test-timeout" value="6000s" />
         <option name="hidden-api-checks" value="false" />
diff --git a/packages/PackageInstaller/Android.mk b/tests/GamePerformance/Android.mk
similarity index 73%
rename from packages/PackageInstaller/Android.mk
rename to tests/GamePerformance/Android.mk
index ab5483c..58654de 100644
--- a/packages/PackageInstaller/Android.mk
+++ b/tests/GamePerformance/Android.mk
@@ -16,17 +16,24 @@
 
 include $(CLEAR_VARS)
 
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := PackageInstaller
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
 
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVILEGED_MODULE := true
+LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner
+
+LOCAL_PACKAGE_NAME := GamePerformance
+
 LOCAL_PRIVATE_PLATFORM_APIS := true
 
-LOCAL_STATIC_JAVA_LIBRARIES := xz-java
-LOCAL_STATIC_ANDROID_LIBRARIES := androidx.leanback_leanback
+LOCAL_CERTIFICATE := platform
+
 
 include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/tests/GamePerformance/AndroidManifest.xml b/tests/GamePerformance/AndroidManifest.xml
new file mode 100644
index 0000000..b331e2c
--- /dev/null
+++ b/tests/GamePerformance/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.gameperformance">
+    <uses-sdk android:minSdkVersion="25"/>
+    <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <application android:theme="@style/noeffects">
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="android.gameperformance.GamePerformanceActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="android.gameperformance">
+    </instrumentation>
+</manifest>
diff --git a/tests/GamePerformance/res/values/themes.xml b/tests/GamePerformance/res/values/themes.xml
new file mode 100644
index 0000000..6313071
--- /dev/null
+++ b/tests/GamePerformance/res/values/themes.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<resources>
+    <style name="noeffects" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen">
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:fadingEdge">none</item>
+        <item name="android:windowContentTransitions">false</item>
+        <item name="android:windowAnimationStyle">@null</item>
+    </style>
+</resources>
diff --git a/tests/GamePerformance/src/android/gameperformance/ATraceRunner.java b/tests/GamePerformance/src/android/gameperformance/ATraceRunner.java
new file mode 100644
index 0000000..25754fd
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/ATraceRunner.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.gameperformance;
+
+import java.io.BufferedReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import android.app.Instrumentation;
+import android.os.AsyncTask;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+/**
+ * Helper that runs atrace command for required duration and category. Results are read from
+ * the output of atrace and serialized to the provided file. We cannot use direct atrace to
+ * file because atrace is executed in UI automator context and analysis is done in test context.
+ * In last case output file is not accessible from the both contexts.
+ */
+public class ATraceRunner extends AsyncTask<Void, Integer, Boolean>{
+    private final static String TAG = "ATraceRunner";
+
+    // Report that atrace is done.
+    public interface Delegate {
+        public void onProcessed(boolean success);
+    }
+
+    private final Instrumentation mInstrumentation;
+    private final String mOutput;
+    private final int mTimeInSeconds;
+    private final String mCategory;
+    private final Delegate mDelegate;
+
+    public ATraceRunner(Instrumentation instrumentation,
+                        String output,
+                        int timeInSeconds,
+                        String category,
+                        Delegate delegate) {
+        mInstrumentation = instrumentation;
+        mOutput = output;
+        mTimeInSeconds = timeInSeconds;
+        mCategory = category;
+        mDelegate = delegate;
+    }
+
+    @Override
+    protected Boolean doInBackground(Void... params) {
+        BufferedReader bufferedReader = null;
+        FileWriter writer = null;
+        try {
+            // Run the command.
+            final String cmd = "atrace -t " + mTimeInSeconds + " " + mCategory;
+            Log.i(TAG, "Running atrace... " + cmd);
+            writer = new FileWriter(mOutput);
+            final ParcelFileDescriptor fd =
+                    mInstrumentation.getUiAutomation().executeShellCommand(cmd);
+            bufferedReader = new BufferedReader(
+                    new InputStreamReader(new ParcelFileDescriptor.AutoCloseInputStream(fd)));
+            String line;
+            while ((line = bufferedReader.readLine()) != null) {
+                writer.write(line);
+                writer.write("\n");
+            }
+            Log.i(TAG, "Running atrace... DONE");
+            return true;
+        } catch (IOException e) {
+            Log.i(TAG, "atrace failed", e);
+            return false;
+        } finally {
+            Utils.closeQuietly(bufferedReader);
+            Utils.closeQuietly(writer);
+        }
+    }
+
+    @Override
+    protected void onPostExecute(Boolean result) {
+        mDelegate.onProcessed(result);
+    }
+
+}
diff --git a/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java b/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java
new file mode 100644
index 0000000..2b37280
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.gameperformance;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+
+public class CustomOpenGLView extends GLSurfaceView {
+    private Random mRandom;
+    private List<Long> mFrameTimes;
+
+    public CustomOpenGLView(Context context) {
+        super(context);
+
+        mRandom = new Random();
+        mFrameTimes = new ArrayList<Long>();
+
+        setEGLContextClientVersion(2);
+
+        setRenderer(new GLSurfaceView.Renderer() {
+            @Override
+            public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+                GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+                gl.glClearDepthf(1.0f);
+                gl.glEnable(GL10.GL_DEPTH_TEST);
+                gl.glDepthFunc(GL10.GL_LEQUAL);
+
+                gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
+                          GL10.GL_NICEST);            }
+
+            @Override
+            public void onSurfaceChanged(GL10 gl, int width, int height) {
+                GLES20.glViewport(0, 0, width, height);
+            }
+
+            @Override
+            public void onDrawFrame(GL10 gl) {
+                GLES20.glClearColor(
+                        mRandom.nextFloat(), mRandom.nextFloat(), mRandom.nextFloat(), 1.0f);
+                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+                synchronized (mFrameTimes) {
+                    mFrameTimes.add(System.currentTimeMillis());
+                }
+            }
+        });
+        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
+    }
+
+    /**
+     * Resets frame times in order to calculate fps for different test pass.
+     */
+    public void resetFrameTimes() {
+        synchronized (mFrameTimes) {
+            mFrameTimes.clear();
+        }
+    }
+
+    /**
+     * Returns current fps based on collected frame times.
+     */
+    public double getFps() {
+        synchronized (mFrameTimes) {
+            if (mFrameTimes.size() < 2) {
+                return 0.0f;
+            }
+            return 1000.0 * mFrameTimes.size() /
+                    (mFrameTimes.get(mFrameTimes.size() - 1) - mFrameTimes.get(0));
+        }
+    }
+}
diff --git a/tests/GamePerformance/src/android/gameperformance/CustomSurfaceView.java b/tests/GamePerformance/src/android/gameperformance/CustomSurfaceView.java
new file mode 100644
index 0000000..a46668d
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/CustomSurfaceView.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.gameperformance;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Trace;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+/**
+ * Minimal SurfaceView that sends buffer on request.
+ */
+public class CustomSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
+    // Tag for trace when buffer is requested.
+    public final static String LOCAL_REQUEST_BUFFER = "localRequestBuffer";
+    // Tag for trace when buffer is posted.
+    public final static String LOCAL_POST_BUFFER = "localPostBuffer";
+
+    private final Object mSurfaceLock = new Object();
+    // Keeps frame times. Used to calculate fps.
+    private List<Long> mFrameTimes;
+    // Surface to send.
+    private Surface mSurface;
+    private Handler mHandler;
+
+    private Runnable mInvalidateSurfaceTask = new Runnable() {
+        @Override
+        public void run() {
+            synchronized (mSurfaceLock) {
+                if (mSurface == null) {
+                    return;
+                }
+                invalidateSurface(true, true);
+                mHandler.post(this);
+            }
+        }
+    };
+
+    public CustomSurfaceView(Context context) {
+        super(context);
+        mFrameTimes = new ArrayList<Long>();
+        getHolder().addCallback(this);
+        getHolder().setFormat(PixelFormat.OPAQUE);
+
+        HandlerThread thread = new HandlerThread("SurfaceInvalidator");
+        thread.start();
+        mHandler = new Handler(thread.getLooper());
+    }
+
+    /**
+     * Resets frame times in order to calculate fps for different test pass.
+     */
+    public void resetFrameTimes() {
+        synchronized (mSurfaceLock) {
+            mFrameTimes.clear();
+        }
+    }
+
+    /**
+     * Returns current fps based on collected frame times.
+     */
+    public double getFps() {
+        synchronized (mSurfaceLock) {
+            if (mFrameTimes.size() < 2) {
+                return 0.0f;
+            }
+            return 1000.0 * mFrameTimes.size() /
+                    (mFrameTimes.get(mFrameTimes.size() - 1) - mFrameTimes.get(0));
+        }
+    }
+
+    /**
+     * Invalidates surface.
+     * @param traceCalls set to true in case we need register trace calls. Not used for warm-up.
+     * @param drawFps perform drawing current fps on surface to have some payload on surface.
+     */
+    public void invalidateSurface(boolean traceCalls, boolean drawFps) {
+        synchronized (mSurfaceLock) {
+            if (mSurface == null) {
+                throw new IllegalStateException("Surface is not ready");
+            }
+            if (traceCalls) {
+                Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, LOCAL_REQUEST_BUFFER);
+            }
+            Canvas canvas = mSurface.lockHardwareCanvas();
+            if (traceCalls) {
+                Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
+            }
+
+            if (drawFps) {
+                int textSize = canvas.getHeight() / 24;
+                Paint paint = new Paint();
+                paint.setTextSize(textSize);
+                paint.setColor(0xFFFF8040);
+                canvas.drawARGB(92, 255, 255, 255);
+                canvas.drawText("FPS: " + String.format("%.2f", getFps()), 10, 300, paint);
+            }
+
+            if (traceCalls) {
+                Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, LOCAL_POST_BUFFER);
+            }
+            mSurface.unlockCanvasAndPost(canvas);
+            if (traceCalls) {
+                Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
+            }
+
+            mFrameTimes.add(System.currentTimeMillis());
+        }
+    }
+
+    /**
+     * Wait until surface is created and ready to use or return immediately if surface
+     * already exists.
+     */
+    public void waitForSurfaceReady() {
+        synchronized (mSurfaceLock) {
+            if (mSurface == null) {
+                try {
+                    mSurfaceLock.wait(5000);
+                } catch(InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (mSurface == null)
+                throw new IllegalStateException("Surface is not ready.");
+        }
+    }
+
+    /**
+     * Waits until surface is destroyed or return immediately if surface does not exist.
+     */
+    public void waitForSurfaceDestroyed() {
+        synchronized (mSurfaceLock) {
+            if (mSurface != null) {
+                try {
+                    mSurfaceLock.wait(5000);
+                } catch(InterruptedException e) {
+                }
+            }
+            if (mSurface != null)
+                throw new IllegalStateException("Surface still exists.");
+        }
+    }
+
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+        // This method is always called at least once, after surfaceCreated.
+        synchronized (mSurfaceLock) {
+            mSurface = holder.getSurface();
+            mSurfaceLock.notify();
+            mHandler.post(mInvalidateSurfaceTask);
+        }
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        synchronized (mSurfaceLock) {
+            mHandler.removeCallbacks(mInvalidateSurfaceTask);
+            mSurface = null;
+            mSurfaceLock.notify();
+        }
+    }
+}
diff --git a/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java b/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java
new file mode 100644
index 0000000..b0e6196
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.gameperformance;
+
+import java.util.concurrent.CountDownLatch;
+
+import android.app.Activity;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.RelativeLayout;
+
+/**
+ * Minimal activity that holds SurfaceView or GLSurfaceView.
+ * call attachSurfaceView or attachOpenGLView to switch views.
+ */
+public class GamePerformanceActivity extends Activity {
+    private CustomSurfaceView mSurfaceView = null;
+    private CustomOpenGLView mOpenGLView = null;
+    private RelativeLayout mRootLayout;
+
+    public void attachSurfaceView() throws InterruptedException {
+        synchronized (mRootLayout) {
+            if (mSurfaceView != null) {
+                return;
+            }
+            final CountDownLatch latch = new CountDownLatch(1);
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    if (mOpenGLView != null) {
+                        mRootLayout.removeView(mOpenGLView);
+                        mOpenGLView = null;
+                    }
+                    mSurfaceView = new CustomSurfaceView(GamePerformanceActivity.this);
+                    mRootLayout.addView(mSurfaceView);
+                    latch.countDown();
+                }
+            });
+            latch.await();
+            mSurfaceView.waitForSurfaceReady();
+        }
+    }
+
+    public void attachOpenGLView() throws InterruptedException {
+        synchronized (mRootLayout) {
+            if (mOpenGLView != null) {
+                return;
+            }
+            final CountDownLatch latch = new CountDownLatch(1);
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    if (mSurfaceView != null) {
+                        mRootLayout.removeView(mSurfaceView);
+                        mSurfaceView = null;
+                    }
+                    mOpenGLView = new CustomOpenGLView(GamePerformanceActivity.this);
+                    mRootLayout.addView(mOpenGLView);
+                    latch.countDown();
+                }
+            });
+            latch.await();
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+        // To layouts in parent. First contains list of Surfaces and second
+        // controls. Controls stay on top.
+        mRootLayout = new RelativeLayout(this);
+        mRootLayout.setLayoutParams(new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT));
+
+        Rect rect = new Rect();
+        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
+
+        mOpenGLView =  new CustomOpenGLView(this);
+        mRootLayout.addView(mOpenGLView);
+
+        setContentView(mRootLayout);
+    }
+
+    public void resetFrameTimes() {
+        if (mSurfaceView != null) {
+            mSurfaceView.resetFrameTimes();
+        } else if (mOpenGLView != null) {
+            mOpenGLView.resetFrameTimes();
+        } else {
+            throw new IllegalStateException("Nothing attached");
+        }
+    }
+
+    public double getFps() {
+        if (mSurfaceView != null) {
+            return mSurfaceView.getFps();
+        } else if (mOpenGLView != null) {
+            return mOpenGLView.getFps();
+        } else {
+            throw new IllegalStateException("Nothing attached");
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java
new file mode 100644
index 0000000..e5de7d7
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.gameperformance;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Trace;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+public class GamePerformanceTest extends
+        ActivityInstrumentationTestCase2<GamePerformanceActivity> {
+    private final static String TAG = "GamePerformanceTest";
+
+    private final static int GRAPHIC_BUFFER_WARMUP_LOOP_CNT = 60;
+
+    public GamePerformanceTest() {
+        super(GamePerformanceActivity.class);
+    }
+
+    @SmallTest
+    public void testGraphicBufferMetrics() throws IOException, InterruptedException {
+        Bundle status = new Bundle();
+
+        for (int i = 0; i < 2; ++i) {
+            if (i == 0) {
+                getActivity().attachSurfaceView();
+            } else {
+                getActivity().attachOpenGLView();
+            }
+
+            // Perform warm-up.
+            Thread.sleep(2000);
+
+            // Once atrace is done, this one is triggered.
+            CountDownLatch latch = new CountDownLatch(1);
+
+            final String passTag = i == 0 ? "surface" : "opengl";
+            final String output = (new File(getInstrumentation().getContext().getFilesDir(),
+                    "atrace_" + passTag + ".log")).getAbsolutePath();
+            Log.i(TAG, "Collecting traces to " + output);
+            new ATraceRunner(getInstrumentation(), output, 5, "gfx", new ATraceRunner.Delegate() {
+                @Override
+                public void onProcessed(boolean success) {
+                    latch.countDown();
+                }
+            }).execute();
+
+            // Reset frame times and perform invalidation loop while atrace is running.
+            getActivity().resetFrameTimes();
+            latch.await();
+
+            // Copy results.
+            final Map<String, Double> metrics =
+                    GraphicBufferMetrics.processGraphicBufferResult(output, passTag);
+            for (Map.Entry<String, Double> metric : metrics.entrySet()) {
+                status.putDouble(metric.getKey(), metric.getValue());
+            }
+            // Also record FPS.
+            status.putDouble(passTag + "_fps", getActivity().getFps());
+        }
+
+        getInstrumentation().sendStatus(Activity.RESULT_OK, status);
+    }
+}
diff --git a/tests/GamePerformance/src/android/gameperformance/GraphicBufferMetrics.java b/tests/GamePerformance/src/android/gameperformance/GraphicBufferMetrics.java
new file mode 100644
index 0000000..dffce1a
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/GraphicBufferMetrics.java
@@ -0,0 +1,530 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.gameperformance;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/**
+ * Utility class that performs analysis of atrace logs. This is implemented without Android
+ * dependencies and therefore can be used in stand-alone mode.
+ * Idea of this is to track atrace gfx event from graphics buffer producer/consumer.
+ * We analyze here from surfaceflinger
+ *   queueBuffer - event when buffer was queued.
+ *   acquireBuffer - event when buffer was requested for composition.
+ *   releaseBuffer - even when buffer was released after composition.
+ * This also track events, issued locally
+ *   localPostBuffer - event when buffer was posted from the local app.
+ *
+ *  queueBuffer, acquireBuffer, releaseBuffer is accompanied with buffer name so we
+ *  can track life-cycle of particular buffer.
+ *  We don't have such information for localPostBuffer, however we can track next queueBuffer
+ *  from surfaceflinger corresponds to previous localPostBuffer.
+ *
+ *  Following results are calculated:
+ *    post_time_[min/max/avr]_mcs - time for localPostBuffer duration.
+ *    ready_time_[min/max/avr]_mcs - time from localPostBuffer to when buffer was acquired by
+ *                                   surfaceflinger.
+ *    latency_[min/max/avr]_mcs - time from localPostBuffer to when buffer was released by
+ *                                 surfaceflinger.
+ *    missed_frame_percents - percentage of missed frames (frames that do not have right sequence
+ *                            of events).
+ *
+ * Following is example of atrace logs from different platforms
+ *            <...>-5237  (-----) [000] ...1   228.380392: tracing_mark_write: B|11|SurfaceView - android.gameperformance/android.gameperformance.GamePerformanceActivity#0: 2
+ *   surfaceflinger-5855  ( 5855) [001] ...1   169.627364: tracing_mark_write: B|24|acquireBuffer
+ *   HwBinder:617_2-652   (  617) [002] d..1 360262.921756: sde_evtlog: 617|sde_encoder_virt_atomic_check:855|19|0|0|0|0|0|0|0|0|0|0|0|0|0|0
+ */
+public class GraphicBufferMetrics {
+    private final static String TAG = "GraphicBufferMetrics";
+
+    private final static String KEY_POST_TIME = "post_time";
+    private final static String KEY_READY_TIME = "ready_time";
+    private final static String KEY_LATENCY = "latency";
+    private final static String SUFFIX_MIN = "min";
+    private final static String SUFFIX_MAX = "max";
+    private final static String SUFFIX_MEDIAN = "median";
+    private final static String KEY_MISSED_FRAME_RATE = "missed_frame_percents";
+
+    private final static int EVENT_POST_BUFFER = 0;
+    private final static int EVENT_QUEUE_BUFFER = 1;
+    private final static int EVENT_ACQUIRE_BUFFER = 2;
+    private final static int EVENT_RELEASE_BUFFER = 3;
+
+    // atrace prints this line. Used as a marker to make sure that we can parse its output.
+    private final static String ATRACE_HEADER =
+            "#           TASK-PID    TGID   CPU#  ||||    TIMESTAMP  FUNCTION";
+
+    private final static String[] KNOWN_PHRASES = new String[] {
+            "capturing trace... done", "TRACE:"};
+    private final static List<String> KNWON_PHRASES_LIST = Arrays.asList(KNOWN_PHRASES);
+
+    // Type of the atrace event we can parse and analyze.
+    private final static String FUNCTION_TRACING_MARK_WRITE = "tracing_mark_write";
+
+    // Trace event we can ignore. It contains current timestamp information for the atrace output.
+    private final static String TRACE_EVENT_CLOCK_SYNC = "trace_event_clock_sync:";
+
+    // Threshold we consider test passes successfully. If we cannot collect enough amount of frames
+    // let fail the test. 50 is calculated 10 frames per second running for five seconds.
+    private final static int MINIMAL_SAMPLE_CNT_TO_PASS = 50;
+
+    /**
+     * Raw event in atrace. Stored hierarchically.
+     */
+    private static class RawEvent {
+        // Parent of this event or null for the root holder.
+        public final RawEvent mParent;
+        // Time of the event in mcs.
+        public final long mTime;
+        // Duration of the event in mcs.
+        public long mDuration;
+        // Name/body of the event.
+        public final String mName;
+        // Children events.
+        public final List<RawEvent> mChildren;
+
+        public RawEvent(RawEvent parent, long time, String name) {
+            mParent = parent;
+            mTime = time;
+            mName = name;
+            mDuration = -1;
+            mChildren = new ArrayList<>();
+        }
+
+        /**
+         * Recursively finds child events.
+         * @param path specify path to events. For example a/b. That means to find child with name
+         *             'a' of the current event and in this child find child with name 'b'. Path
+         *             can consist from only one segment and that means we analyze only children of
+         *             the current event.
+         * @param collector to collect found events.
+         */
+        public void findEvents(String path, List<RawEvent> collector) {
+            final int separator = path.indexOf('/');
+            final String current = separator > 0 ? path.substring(0, separator) : path;
+            final String nextPath = separator > 0 ? path.substring(separator + 1) : null;
+            for (RawEvent child : mChildren) {
+                if (child.mName.equals(current)) {
+                    if (nextPath != null) {
+                        child.findEvents(nextPath, collector);
+                    } else {
+                        collector.add(child);
+                    }
+                }
+            }
+        }
+
+        public void dump(String prefix) {
+            System.err.print(prefix);
+            System.err.println(mTime + "[" + mDuration + "] " + mName);
+            for (RawEvent e : mChildren) {
+                e.dump(prefix + "  ");
+            }
+        }
+    }
+
+    /**
+     * Describes graphic buffer event. local post, queued, acquired, released.
+     */
+    private static class BufferEvent {
+        public final int mType;
+        public final long mTime;
+        public final long mDuration;
+        public final String mBufferId;
+
+        public BufferEvent(int type, long time, long duration, String bufferId) {
+            mType = type;
+            mTime = time;
+            mDuration = duration;
+            mBufferId = bufferId;
+        }
+
+        @Override
+        public String toString() {
+            return "Type: " + mType + ". Time: " + mTime +
+                    "[" + mDuration + "]. Buffer: " + mBufferId + ".";
+        }
+    }
+
+    /**
+     * Returns true if given char is digit.
+     */
+    private static boolean isDigitChar(char c) {
+        return (c >= '0') && (c <= '9');
+    }
+
+    /**
+     * Returns true if given char is digit or '.'.
+     */
+    private static boolean isDoubleDigitChar(char c) {
+        return (c == '.') || isDigitChar(c);
+    }
+
+    /**
+     * Convert timestamp string that represents double value in seconds to long time that represents
+     * timestamp in microseconds.
+     */
+    private static long getTimeStamp(String timeStampStr) {
+        return (long)(1000000.0 * Double.parseDouble(timeStampStr));
+    }
+
+    /**
+     * Reads atrace log and build event model. Result is a map, where key specifies event for the
+     * particular thread. Value is the synthetic root RawEvent that holds all events for the
+     * thread. Events are stored hierarchically.
+     */
+    private static Map<Integer, RawEvent> buildEventModel(String fileName) throws IOException {
+        Map<Integer, RawEvent> result = new HashMap<>();
+
+        BufferedReader bufferedReader = null;
+        String line = "";
+        boolean headerDetected = false;
+        try {
+            bufferedReader = new BufferedReader(new FileReader(fileName));
+            while ((line = bufferedReader.readLine()) != null) {
+                // Make sure we find comment that describes output format we can with.
+                headerDetected |= line.equals(ATRACE_HEADER);
+                // Skip comments.
+                if (line.startsWith("#")) {
+                    continue;
+                }
+                // Skip known service output
+                if (KNWON_PHRASES_LIST.contains(line)) {
+                    continue;
+                }
+
+                if (!headerDetected) {
+                    // We don't know the format of this line.
+                    throw new IllegalStateException("Header was not detected");
+                }
+
+                // TASK-PID in header exists at position 12. PID position 17 should contains first
+                // digit of thread id after the '-'.
+                if (!isDigitChar(line.charAt(17)) || line.charAt(16) != '-') {
+                    throw new IllegalStateException("Failed to parse thread id: " + line);
+                }
+                int rightIndex = line.indexOf(' ', 17);
+                final String threadIdStr = line.substring(17, rightIndex);
+                final int threadId = Integer.parseInt(threadIdStr);
+
+                // TIMESTAMP in header exists at position 45
+                // This position should point in the middle of timestamp which is ended by ':'.
+                int leftIndex = 45;
+                while (isDoubleDigitChar(line.charAt(leftIndex))) {
+                    --leftIndex;
+                }
+                rightIndex = line.indexOf(':', 45);
+
+                final String timeStampString = line.substring(leftIndex + 1, rightIndex);
+                final long timeStampMcs = getTimeStamp(timeStampString);
+
+                // Find function name, pointed by FUNCTION. Long timestamp can shift if position
+                // so use end of timestamp to find the function which is ended by ':'.
+                leftIndex = rightIndex + 1;
+                while (Character.isWhitespace(line.charAt(leftIndex))) {
+                    ++leftIndex;
+                }
+                rightIndex = line.indexOf(':', leftIndex);
+                final String function = line.substring(leftIndex, rightIndex);
+
+                if (!function.equals(FUNCTION_TRACING_MARK_WRITE)) {
+                    continue;
+                }
+
+                // Rest of the line is event body.
+                leftIndex = rightIndex + 1;
+                while (Character.isWhitespace(line.charAt(leftIndex))) {
+                    ++leftIndex;
+                }
+
+                final String event = line.substring(leftIndex);
+                if (event.startsWith(TRACE_EVENT_CLOCK_SYNC)) {
+                    continue;
+                }
+
+                // Parse event, for example:
+                // B|615|SurfaceView - android.gameperformance.GamePerformanceActivity#0: 1
+                // E|615
+                // C|11253|operation id|2
+                StringTokenizer eventTokenizer = new StringTokenizer(event, "|");
+                final String eventType = eventTokenizer.nextToken();
+
+                // Attach root on demand.
+                if (!result.containsKey(threadId)) {
+                    result.put(threadId, new RawEvent(null /* parent */,
+                                                      timeStampMcs,
+                                                      "#ROOT_" + threadId));
+                }
+
+                switch (eventType) {
+                case "B": {
+                        // Log entry starts.
+                        eventTokenizer.nextToken(); // PID
+                        String eventText = eventTokenizer.nextToken();
+                        while (eventTokenizer.hasMoreTokens()) {
+                            eventText += " ";
+                            eventText += eventTokenizer.nextToken();
+                        }
+                        RawEvent parent = result.get(threadId);
+                        RawEvent current = new RawEvent(parent, timeStampMcs, eventText);
+                        parent.mChildren.add(current);
+                        result.put(threadId, current);
+                    }
+                    break;
+                case "E": {
+                        // Log entry ends.
+                        RawEvent current = result.get(threadId);
+                        current.mDuration = timeStampMcs - current.mTime;
+                        if (current.mParent == null) {
+                            // Detect a tail of the previous call. Remove last child element if it
+                            // exists once it does not belong to the root.
+                            if (!current.mChildren.isEmpty()) {
+                                current.mChildren.remove(current.mChildren.size() -1);
+                            }
+                        } else {
+                            result.put(threadId, current.mParent);
+                        }
+                    }
+                    break;
+                case "C":
+                    // Counter, ignore
+                    break;
+                default:
+                    throw new IllegalStateException(
+                            "Unrecognized trace: " + line + " # " + eventType + " # " + event);
+                }
+            }
+
+            // Detect incomplete events and detach from the root.
+            Set<Integer> threadIds = new TreeSet<>();
+            threadIds.addAll(result.keySet());
+            for (int threadId : threadIds) {
+                RawEvent root = result.get(threadId);
+                if (root.mParent == null) {
+                    // Last trace was closed.
+                    continue;
+                }
+                // Find the root.
+                while (root.mParent != null) {
+                    root = root.mParent;
+                }
+                // Discard latest incomplete element.
+                root.mChildren.remove(root.mChildren.size() - 1);
+                result.put(threadId, root);
+            }
+        } catch (Exception e) {
+            throw new IOException("Failed to process " + line, e);
+        } finally {
+            Utils.closeQuietly(bufferedReader);
+        }
+
+        return result;
+    }
+
+    /**
+     * Processes provided atrace log and calculates graphics buffer metrics.
+     * @param fileName name of atrace log file.
+     * @param testTag tag to separate results for the different passes.
+     */
+    public static Map<String, Double> processGraphicBufferResult(
+            String fileName, String testTag) throws IOException {
+        final Map<Integer, RawEvent> model = buildEventModel(fileName);
+
+        List<RawEvent> collectorPostBuffer = new ArrayList<>();
+        List<RawEvent> collectorQueueBuffer = new ArrayList<>();
+        List<RawEvent> collectorReleaseBuffer = new ArrayList<>();
+        List<RawEvent> collectorAcquireBuffer = new ArrayList<>();
+
+        // Collect required events.
+        for (RawEvent root : model.values()) {
+            // Surface view
+            root.findEvents("localPostBuffer", collectorPostBuffer);
+            // OpengGL view
+            root.findEvents("eglSwapBuffersWithDamageKHR", collectorPostBuffer);
+
+            root.findEvents("queueBuffer", collectorQueueBuffer);
+            root.findEvents("onMessageReceived/handleMessageInvalidate/latchBuffer/" +
+                    "updateTexImage/acquireBuffer",
+                    collectorAcquireBuffer);
+            // PI stack
+            root.findEvents(
+                    "onMessageReceived/handleMessageRefresh/postComposition/releaseBuffer",
+                    collectorReleaseBuffer);
+            // NYC stack
+            root.findEvents(
+                    "onMessageReceived/handleMessageRefresh/releaseBuffer",
+                    collectorReleaseBuffer);
+        }
+
+        // Convert raw event to buffer events.
+        List<BufferEvent> bufferEvents = new ArrayList<>();
+        for (RawEvent event : collectorPostBuffer) {
+            bufferEvents.add(
+                    new BufferEvent(EVENT_POST_BUFFER, event.mTime, event.mDuration, null));
+        }
+        toBufferEvents(EVENT_QUEUE_BUFFER, collectorQueueBuffer, bufferEvents);
+        toBufferEvents(EVENT_ACQUIRE_BUFFER, collectorAcquireBuffer, bufferEvents);
+        toBufferEvents(EVENT_RELEASE_BUFFER, collectorReleaseBuffer, bufferEvents);
+
+        // Sort events based on time. These events are originally taken from different threads so
+        // order is not always preserved.
+        Collections.sort(bufferEvents, new Comparator<BufferEvent>() {
+            @Override
+            public int compare(BufferEvent o1, BufferEvent o2) {
+                if (o1.mTime < o2.mTime) {
+                    return -1;
+                } if (o1.mTime > o2.mTime) {
+                    return +1;
+                } else {
+                    return 0;
+                }
+            }
+        });
+
+        // Collect samples.
+        List<Long> postTimes = new ArrayList<>();
+        List<Long> readyTimes = new ArrayList<>();
+        List<Long> latencyTimes = new ArrayList<>();
+        long missedCnt = 0;
+
+        for (int i = 0; i < bufferEvents.size(); ++i) {
+            if (bufferEvents.get(i).mType != EVENT_POST_BUFFER) {
+                continue;
+            }
+            final int queueIndex = findNextOfType(bufferEvents, i + 1, EVENT_QUEUE_BUFFER);
+            if (queueIndex < 0) {
+                break;
+            }
+            final int acquireIndex = findNextOfBufferId(bufferEvents, queueIndex + 1,
+                    bufferEvents.get(queueIndex).mBufferId);
+            if (acquireIndex < 0) {
+                break;
+            }
+            if (bufferEvents.get(acquireIndex).mType != EVENT_ACQUIRE_BUFFER) {
+                // Was not actually presented.
+                ++missedCnt;
+                continue;
+            }
+            final int releaseIndex = findNextOfBufferId(bufferEvents, acquireIndex + 1,
+                    bufferEvents.get(queueIndex).mBufferId);
+            if (releaseIndex < 0) {
+                break;
+            }
+            if (bufferEvents.get(releaseIndex).mType != EVENT_RELEASE_BUFFER) {
+                // Was not actually presented.
+                ++missedCnt;
+                continue;
+            }
+
+            postTimes.add(bufferEvents.get(i).mDuration);
+            readyTimes.add(
+                    bufferEvents.get(acquireIndex).mTime - bufferEvents.get(i).mTime);
+            latencyTimes.add(
+                    bufferEvents.get(releaseIndex).mTime - bufferEvents.get(i).mTime);
+        }
+
+        if (postTimes.size() < MINIMAL_SAMPLE_CNT_TO_PASS) {
+            throw new IllegalStateException("Too few sample cnt: " + postTimes.size() +". " +
+                    MINIMAL_SAMPLE_CNT_TO_PASS + " is required.");
+        }
+
+        Map<String, Double> status = new TreeMap<>();
+        addResults(status, testTag, KEY_POST_TIME, postTimes);
+        addResults(status, testTag, KEY_READY_TIME, readyTimes);
+        addResults(status, testTag, KEY_LATENCY, latencyTimes);
+        status.put(testTag + "_" + KEY_MISSED_FRAME_RATE,
+                100.0 * missedCnt / (missedCnt + postTimes.size()));
+        return status;
+    }
+
+    private static void addResults(
+            Map<String, Double> status, String tag, String key, List<Long> times) {
+        Collections.sort(times);
+        long min = times.get(0);
+        long max = times.get(0);
+        for (long time : times) {
+            min = Math.min(min, time);
+            max = Math.max(max, time);
+        }
+        status.put(tag + "_" + key + "_" + SUFFIX_MIN, (double)min);
+        status.put(tag + "_" + key + "_" + SUFFIX_MAX, (double)max);
+        status.put(tag + "_" + key + "_" + SUFFIX_MEDIAN, (double)times.get(times.size() / 2));
+    }
+
+    // Helper to convert surface flinger events to buffer events.
+    private static void toBufferEvents(
+            int type, List<RawEvent> rawEvents, List<BufferEvent> bufferEvents) {
+        for (RawEvent event : rawEvents) {
+            if (event.mChildren.isEmpty()) {
+                throw new IllegalStateException("Buffer name is expected");
+            }
+            final String bufferName = event.mChildren.get(0).mName;
+            if (bufferName.startsWith("SurfaceView - android.gameperformance")) {
+                bufferEvents.add(
+                        new BufferEvent(type, event.mTime, event.mDuration, bufferName));
+            }
+        }
+    }
+
+    private static int findNextOfType(List<BufferEvent> events, int startIndex, int type) {
+        for (int i = startIndex; i < events.size(); ++i) {
+            if (events.get(i).mType == type) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private static int findNextOfBufferId(
+            List<BufferEvent> events, int startIndex, String bufferId) {
+        for (int i = startIndex; i < events.size(); ++i) {
+            if (bufferId.equals(events.get(i).mBufferId)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public static void main(String[] args) {
+        if (args.length != 1) {
+            System.err.println("Usage: " + TAG + " atrace.log");
+            return;
+        }
+
+        try {
+            System.out.println("Results:");
+            for (Map.Entry<?, ?> entry :
+                processGraphicBufferResult(args[0], "default").entrySet()) {
+                System.out.println("    " + entry.getKey() + " = " + entry.getValue());
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/tests/GamePerformance/src/android/gameperformance/Utils.java b/tests/GamePerformance/src/android/gameperformance/Utils.java
new file mode 100644
index 0000000..6481971
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/Utils.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.gameperformance;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+public class Utils {
+    public static void closeQuietly(Closeable closeable) {
+        try {
+            if (closeable != null) {
+                closeable.close();
+            }
+        } catch (IOException e) {
+            // Ignore
+        }
+    }
+}
diff --git a/tests/Internal/Android.bp b/tests/Internal/Android.bp
index 4cb9f8d..e233fed 100644
--- a/tests/Internal/Android.bp
+++ b/tests/Internal/Android.bp
@@ -10,6 +10,7 @@
         "junit",
         "androidx.test.rules",
         "mockito-target-minus-junit4",
+        "truth-prebuilt",
     ],
     java_resource_dirs: ["res"],
     certificate: "platform",
diff --git a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
index 300182d..768e47c 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.internal.colorextraction.types;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -67,6 +69,36 @@
     }
 
     @Test
+    public void extractInto_fromBitmap() {
+        Tonal tonal = new Tonal(InstrumentationRegistry.getContext());
+        GradientColors normal = new GradientColors();
+        GradientColors dark = new GradientColors();
+        GradientColors extraDark = new GradientColors();
+        WallpaperColors wallColors = new WallpaperColors(Color.valueOf(Color.RED), null, null,
+                WallpaperColors.HINT_FROM_BITMAP);
+
+        // WHEN colors are extracted from a wallpaper with only a red primary color.
+        tonal.extractInto(wallColors, normal, dark, extraDark);
+        // THEN the main extracted color is red
+        assertThat(normal.getMainColor()).isEqualTo(Color.RED);
+    }
+
+    @Test
+    public void extractInto_supportsDarkText() {
+        Tonal tonal = new Tonal(InstrumentationRegistry.getContext());
+        GradientColors normal = new GradientColors();
+        GradientColors dark = new GradientColors();
+        GradientColors extraDark = new GradientColors();
+        WallpaperColors wallColors = new WallpaperColors(Color.valueOf(Color.RED), null, null,
+                WallpaperColors.HINT_SUPPORTS_DARK_TEXT);
+
+        // WHEN colors are extracted from a wallpaper with only a red primary color.
+        tonal.extractInto(wallColors, normal, dark, extraDark);
+        // THEN the main extracted color is red
+        assertThat(normal.getMainColor()).isEqualTo(Color.RED);
+    }
+
+    @Test
     public void colorRange_containsColor() {
         Tonal.ColorRange colorRange = new Tonal.ColorRange(new Range<>(0f, 50f),
                 new Range<>(0f, 1f), new Range<>(0f, 1f));
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index d0c2612..28af7ce 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -19,11 +19,16 @@
 import static com.android.server.PackageWatchdog.TRIGGER_FAILURE_COUNT;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import android.content.Context;
 import android.content.pm.VersionedPackage;
+import android.os.Handler;
+import android.os.RemoteException;
 import android.os.test.TestLooper;
+import android.util.AtomicFile;
 
 import androidx.test.InstrumentationRegistry;
 
@@ -36,11 +41,14 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
-// TODO(zezeozue): Write test without using PackageWatchdog#getPackages. Just rely on
+// TODO: Write test without using PackageWatchdog#getPackages. Just rely on
 // behavior of observers receiving crash notifications or not to determine if it's registered
+// TODO: Use Truth in tests.
 /**
  * Test PackageWatchdog.
  */
@@ -77,12 +85,11 @@
         TestObserver observer3 = new TestObserver(OBSERVER_NAME_3);
 
         // Start observing for observer1 which will be unregistered
-        watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false);
+        watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
         // Start observing for observer2 which will expire
-        watchdog.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION,
-                false);
+        watchdog.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION);
         // Start observing for observer3 which will have expiry duration reduced
-        watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), LONG_DURATION, false);
+        watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), LONG_DURATION);
 
         // Verify packages observed at start
         // 1
@@ -145,9 +152,8 @@
         TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
         TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
 
-        watchdog1.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false);
-        watchdog1.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION,
-                false);
+        watchdog1.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
+        watchdog1.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION);
 
         // Verify 2 observers are registered and saved internally
         // 1
@@ -193,8 +199,8 @@
         TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
         TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
 
-        watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION, false);
-        watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false);
+        watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION);
+        watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
 
         // Then fail APP_A below the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT - 1; i++) {
@@ -220,8 +226,8 @@
         TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
 
 
-        watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION, false);
-        watchdog.startObservingHealth(observer1, Arrays.asList(APP_B), SHORT_DURATION, false);
+        watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION);
+        watchdog.startObservingHealth(observer1, Arrays.asList(APP_B), SHORT_DURATION);
 
         // Then fail APP_C (not observed) above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -255,7 +261,7 @@
                 }
             };
 
-        watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION, false);
+        watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
 
         // Then fail APP_A (different version) above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -288,13 +294,13 @@
 
         // Start observing for all impact observers
         watchdog.startObservingHealth(observerNone, Arrays.asList(APP_A, APP_B, APP_C, APP_D),
-                SHORT_DURATION, false);
+                SHORT_DURATION);
         watchdog.startObservingHealth(observerHigh, Arrays.asList(APP_A, APP_B, APP_C),
-                SHORT_DURATION, false);
+                SHORT_DURATION);
         watchdog.startObservingHealth(observerMid, Arrays.asList(APP_A, APP_B),
-                SHORT_DURATION, false);
+                SHORT_DURATION);
         watchdog.startObservingHealth(observerLow, Arrays.asList(APP_A),
-                SHORT_DURATION, false);
+                SHORT_DURATION);
 
         // Then fail all apps above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -346,8 +352,8 @@
                 PackageHealthObserverImpact.USER_IMPACT_MEDIUM);
 
         // Start observing for observerFirst and observerSecond with failure handling
-        watchdog.startObservingHealth(observerFirst, Arrays.asList(APP_A), LONG_DURATION, false);
-        watchdog.startObservingHealth(observerSecond, Arrays.asList(APP_A), LONG_DURATION, false);
+        watchdog.startObservingHealth(observerFirst, Arrays.asList(APP_A), LONG_DURATION);
+        watchdog.startObservingHealth(observerSecond, Arrays.asList(APP_A), LONG_DURATION);
 
         // Then fail APP_A above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -424,8 +430,8 @@
                 PackageHealthObserverImpact.USER_IMPACT_HIGH);
 
         // Start observing for observer1 and observer2 with failure handling
-        watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION, false);
-        watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false);
+        watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION);
+        watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
 
         // Then fail APP_A above the threshold
         for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -442,11 +448,12 @@
     }
 
     /**
-     * Test explicit health check status determines package failure or success on expiry
+     * Test package passing explicit health checks does not fail and vice versa.
      */
     @Test
-    public void testPackageFailureExplicitHealthCheck() throws Exception {
-        PackageWatchdog watchdog = createWatchdog();
+    public void testExplicitHealthChecks() throws Exception {
+        TestController controller = new TestController();
+        PackageWatchdog watchdog = createWatchdog(controller, true /* withPackagesReady */);
         TestObserver observer1 = new TestObserver(OBSERVER_NAME_1,
                 PackageHealthObserverImpact.USER_IMPACT_HIGH);
         TestObserver observer2 = new TestObserver(OBSERVER_NAME_2,
@@ -457,21 +464,36 @@
 
         // Start observing with explicit health checks for APP_A and APP_B respectively
         // with observer1 and observer2
-        watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, true);
-        watchdog.startObservingHealth(observer2, Arrays.asList(APP_B), SHORT_DURATION, true);
-        // Explicit health check passed for APP_A (observer1 is aware)
-        watchdog.onExplicitHealthCheckPassed(APP_A);
-        // Start observing APP_A with explicit health checks for observer3.
+        controller.setSupportedPackages(Arrays.asList(APP_A, APP_B));
+        watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
+        watchdog.startObservingHealth(observer2, Arrays.asList(APP_B), SHORT_DURATION);
+
+        // Run handler so requests are dispatched to the controller
+        mTestLooper.dispatchAll();
+
+        // Verify we requested health checks for APP_A and APP_B
+        List<String> requestedPackages = controller.getRequestedPackages();
+        assertEquals(2, requestedPackages.size());
+        assertEquals(APP_A, requestedPackages.get(0));
+        assertEquals(APP_B, requestedPackages.get(1));
+
+        // Then health check passed for APP_A (observer1 is aware)
+        controller.setPackagePassed(APP_A);
+
+        // Then start observing APP_A with explicit health checks for observer3.
         // Observer3 didn't exist when we got the explicit health check above, so
         // it starts out with a non-passing explicit health check and has to wait for a pass
         // otherwise it would be notified of APP_A failure on expiry
-        watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), SHORT_DURATION, true);
+        watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), SHORT_DURATION);
 
         // Then expire observers
         Thread.sleep(SHORT_DURATION);
         // Run handler so package failures are dispatched to observers
         mTestLooper.dispatchAll();
 
+        // Verify we cancelled all requests on expiry
+        assertEquals(0, controller.getRequestedPackages().size());
+
         // Verify observer1 is not notified
         assertEquals(0, observer1.mFailedPackages.size());
 
@@ -484,9 +506,96 @@
         assertEquals(APP_A, observer3.mFailedPackages.get(0));
     }
 
+    /**
+     * Test explicit health check state can be disabled and enabled correctly.
+     */
+    @Test
+    public void testExplicitHealthCheckStateChanges() throws Exception {
+        TestController controller = new TestController();
+        PackageWatchdog watchdog = createWatchdog(controller, true /* withPackagesReady */);
+        TestObserver observer = new TestObserver(OBSERVER_NAME_1,
+                PackageHealthObserverImpact.USER_IMPACT_MEDIUM);
+
+        // Start observing with explicit health checks for APP_A and APP_B
+        controller.setSupportedPackages(Arrays.asList(APP_A, APP_B, APP_C));
+        watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
+        watchdog.startObservingHealth(observer, Arrays.asList(APP_B), LONG_DURATION);
+
+        // Run handler so requests are dispatched to the controller
+        mTestLooper.dispatchAll();
+
+        // Verify we requested health checks for APP_A and APP_B
+        List<String> requestedPackages = controller.getRequestedPackages();
+        assertEquals(2, requestedPackages.size());
+        assertEquals(APP_A, requestedPackages.get(0));
+        assertEquals(APP_B, requestedPackages.get(1));
+
+        // Disable explicit health checks (marks APP_A and APP_B as passed)
+        watchdog.setExplicitHealthCheckEnabled(false);
+
+        // Run handler so requests/cancellations are dispatched to the controller
+        mTestLooper.dispatchAll();
+
+        // Verify all checks are cancelled
+        assertEquals(0, controller.getRequestedPackages().size());
+
+        // Then expire APP_A
+        Thread.sleep(SHORT_DURATION);
+        mTestLooper.dispatchAll();
+
+        // Verify APP_A is not failed (APP_B) is not expired yet
+        assertEquals(0, observer.mFailedPackages.size());
+
+        // Re-enable explicit health checks
+        watchdog.setExplicitHealthCheckEnabled(true);
+
+        // Run handler so requests/cancellations are dispatched to the controller
+        mTestLooper.dispatchAll();
+
+        // Verify no requests are made cos APP_A is expired and APP_B was marked as passed
+        assertEquals(0, controller.getRequestedPackages().size());
+
+        // Then set new supported packages
+        controller.setSupportedPackages(Arrays.asList(APP_C));
+        // Start observing APP_A and APP_C; only APP_C has support for explicit health checks
+        watchdog.startObservingHealth(observer, Arrays.asList(APP_A, APP_C), SHORT_DURATION);
+
+        // Run handler so requests/cancellations are dispatched to the controller
+        mTestLooper.dispatchAll();
+
+        // Verify requests are only made for APP_C
+        requestedPackages = controller.getRequestedPackages();
+        assertEquals(1, requestedPackages.size());
+        assertEquals(APP_C, requestedPackages.get(0));
+
+        // Then expire APP_A and APP_C
+        Thread.sleep(SHORT_DURATION);
+        mTestLooper.dispatchAll();
+
+        // Verify only APP_C is failed because explicit health checks was not supported for APP_A
+        assertEquals(1, observer.mFailedPackages.size());
+        assertEquals(APP_C, observer.mFailedPackages.get(0));
+    }
+
     private PackageWatchdog createWatchdog() {
-        return new PackageWatchdog(InstrumentationRegistry.getContext(),
-                mTestLooper.getLooper());
+        return createWatchdog(new TestController(), true /* withPackagesReady */);
+    }
+
+    private PackageWatchdog createWatchdog(TestController controller, boolean withPackagesReady) {
+        Context context = InstrumentationRegistry.getContext();
+        AtomicFile policyFile =
+                new AtomicFile(new File(context.getFilesDir(), "package-watchdog.xml"));
+        Handler handler = new Handler(mTestLooper.getLooper());
+        PackageWatchdog watchdog =
+                new PackageWatchdog(context, policyFile, handler, handler, controller);
+        // Verify controller is not automatically started
+        assertFalse(controller.mIsEnabled);
+        if (withPackagesReady) {
+            watchdog.onPackagesReady();
+            // Verify controller by default is started when packages are ready
+            assertTrue(controller.mIsEnabled);
+        }
+        return watchdog;
     }
 
     private static class TestObserver implements PackageHealthObserver {
@@ -517,4 +626,69 @@
             return mName;
         }
     }
+
+    private static class TestController extends ExplicitHealthCheckController {
+        TestController() {
+            super(null /* controller */);
+        }
+
+        private boolean mIsEnabled;
+        private List<String> mSupportedPackages = new ArrayList<>();
+        private List<String> mRequestedPackages = new ArrayList<>();
+        private Runnable mStateChangedRunnable;
+        private Consumer<String> mPassedConsumer;
+
+        @Override
+        public void request(String packageName) throws RemoteException {
+            if (!mRequestedPackages.contains(packageName)) {
+                mRequestedPackages.add(packageName);
+            }
+        }
+
+        @Override
+        public void cancel(String packageName) throws RemoteException {
+            mRequestedPackages.remove(packageName);
+        }
+
+        @Override
+        public void getSupportedPackages(Consumer<List<String>> consumer) throws RemoteException {
+            consumer.accept(mIsEnabled ? mSupportedPackages : Collections.emptyList());
+        }
+
+        @Override
+        public void getRequestedPackages(Consumer<List<String>> consumer) throws RemoteException {
+            // Pass copy to prevent ConcurrentModificationException during test
+            consumer.accept(
+                    mIsEnabled ? new ArrayList<>(mRequestedPackages) : Collections.emptyList());
+        }
+
+        @Override
+        public void setEnabled(boolean enabled) {
+            mIsEnabled = enabled;
+            mStateChangedRunnable.run();
+        }
+
+        @Override
+        public void setCallbacks(Runnable stateChangedRunnable, Consumer<String> passedConsumer) {
+            mStateChangedRunnable = stateChangedRunnable;
+            mPassedConsumer = passedConsumer;
+        }
+
+        public void setSupportedPackages(List<String> packages) {
+            mSupportedPackages.clear();
+            mSupportedPackages.addAll(packages);
+        }
+
+        public void setPackagePassed(String packageName) {
+            mPassedConsumer.accept(packageName);
+        }
+
+        public List<String> getRequestedPackages() {
+            if (mIsEnabled) {
+                return mRequestedPackages;
+            } else {
+                return Collections.emptyList();
+            }
+        }
+    }
 }
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index 834743d..d41a5d6 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -108,10 +108,6 @@
             }
 
             // The app should not be available for rollback.
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is uninstalled and when the previously
-            // available rollback, if any, is removed.
-            Thread.sleep(1000);
             assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
 
             // There should be no recently committed rollbacks for this package.
@@ -127,10 +123,6 @@
             assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // The app should now be available for rollback.
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is installed and when the rollback
-            // is made available.
-            Thread.sleep(1000);
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
                     rm.getAvailableRollbacks(), TEST_APP_A);
             assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
@@ -187,11 +179,6 @@
             assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
 
             // Both test apps should now be available for rollback.
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is installed and when the rollback
-            // is made available.
-            Thread.sleep(1000);
-
             RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
                     rm.getAvailableRollbacks(), TEST_APP_A);
             assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
@@ -246,11 +233,6 @@
             assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
 
             // The app should now be available for rollback.
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is installed and when the rollback
-            // is made available.
-            Thread.sleep(1000);
-
             RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
                     rm.getAvailableRollbacks(), TEST_APP_A);
             assertRollbackInfoForAandB(rollbackA);
@@ -297,10 +279,6 @@
             assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // The app should now be available for rollback.
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is installed and when the rollback
-            // is made available.
-            Thread.sleep(1000);
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
                     rm.getAvailableRollbacks(), TEST_APP_A);
 
@@ -481,10 +459,6 @@
             assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
             // The app should now be available for rollback.
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is installed and when the rollback
-            // is made available.
-            Thread.sleep(1000);
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
                     rm.getAvailableRollbacks(), TEST_APP_A);
             assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
@@ -610,10 +584,6 @@
 
             // Both test apps should now be available for rollback, and the
             // RollbackInfo returned for the rollbacks should be correct.
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is installed and when the rollback
-            // is made available.
-            Thread.sleep(1000);
             RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
                     rm.getAvailableRollbacks(), TEST_APP_A);
             assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
@@ -709,11 +679,6 @@
             // been enabled.
             assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is installed and when the rollback
-            // would be made available.
-            Thread.sleep(1000);
-
             RollbackTestUtils.adoptShellPermissionIdentity(
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
             RollbackManager rm = RollbackTestUtils.getRollbackManager();
@@ -745,11 +710,6 @@
             // been enabled because the test app is not a module.
             assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
 
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is installed and when the rollback
-            // would be made available.
-            Thread.sleep(1000);
-
             RollbackManager rm = RollbackTestUtils.getRollbackManager();
             assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
         } finally {
@@ -844,10 +804,6 @@
 
             // Both test apps should now be available for rollback, and the
             // targetPackage returned for rollback should be correct.
-            // TODO: See if there is a way to remove this race condition
-            // between when the app is installed and when the rollback
-            // is made available.
-            Thread.sleep(1000);
             RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
                     rm.getAvailableRollbacks(), TEST_APP_A);
             assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
diff --git a/tests/TouchLatency/app/build.gradle b/tests/TouchLatency/app/build.gradle
index 2594322..04a8788 100644
--- a/tests/TouchLatency/app/build.gradle
+++ b/tests/TouchLatency/app/build.gradle
@@ -6,7 +6,7 @@
 
     defaultConfig {
         applicationId "com.prefabulated.touchlatency"
-        minSdkVersion 21
+        minSdkVersion 28
         targetSdkVersion 28
         versionCode 1
         versionName "1.0"
diff --git a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
index 360c22f..ba77a74 100644
--- a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
+++ b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
@@ -24,11 +24,15 @@
 import android.os.Bundle;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.Display;
+import android.view.Display.Mode;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
 import android.os.Trace;
+import android.view.Window;
+import android.view.WindowManager;
 import java.math.RoundingMode;
 import java.text.DecimalFormat;
 
@@ -219,14 +223,30 @@
 }
 
 public class TouchLatencyActivity extends Activity {
+    private Mode mDisplayModes[];
+    private int mCurrentModeIndex;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
         Trace.beginSection("TouchLatencyActivity onCreate");
         setContentView(R.layout.activity_touch_latency);
 
         mTouchView = findViewById(R.id.canvasView);
+
+        WindowManager wm = getWindowManager();
+        Display display = wm.getDefaultDisplay();
+        mDisplayModes = display.getSupportedModes();
+        Mode currentMode = getWindowManager().getDefaultDisplay().getMode();
+
+        for (int i = 0; i < mDisplayModes.length; i++) {
+            if (currentMode.getModeId() == mDisplayModes[i].getModeId()) {
+                mCurrentModeIndex = i;
+                break;
+            }
+        }
+
         Trace.endSection();
     }
 
@@ -236,10 +256,35 @@
         Trace.beginSection("TouchLatencyActivity onCreateOptionsMenu");
         // Inflate the menu; this adds items to the action bar if it is present.
         getMenuInflater().inflate(R.menu.menu_touch_latency, menu);
+        if (mDisplayModes.length > 1) {
+            MenuItem menuItem = menu.findItem(R.id.display_mode);
+            Mode currentMode = getWindowManager().getDefaultDisplay().getMode();
+            updateDisplayMode(menuItem, currentMode);
+        }
         Trace.endSection();
         return true;
     }
 
+
+    private void updateDisplayMode(MenuItem menuItem, Mode displayMode) {
+        int fps = (int) displayMode.getRefreshRate();
+        menuItem.setTitle(fps + "hz");
+        menuItem.setVisible(true);
+    }
+
+    public void changeDisplayMode(MenuItem item) {
+        Window w = getWindow();
+        WindowManager.LayoutParams params = w.getAttributes();
+
+        int modeIndex = (mCurrentModeIndex + 1) % mDisplayModes.length;
+        params.preferredDisplayModeId = mDisplayModes[modeIndex].getModeId();
+        w.setAttributes(params);
+
+        updateDisplayMode(item, mDisplayModes[modeIndex]);
+        mCurrentModeIndex = modeIndex;
+    }
+
+
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         Trace.beginSection("TouchLatencyActivity onOptionsItemSelected");
@@ -251,6 +296,8 @@
         //noinspection SimplifiableIfStatement
         if (id == R.id.action_settings) {
             mTouchView.changeMode(item);
+        } else if (id == R.id.display_mode) {
+            changeDisplayMode(item);
         }
 
         Trace.endSection();
diff --git a/tests/TouchLatency/app/src/main/res/layout/activity_touch_latency.xml b/tests/TouchLatency/app/src/main/res/layout/activity_touch_latency.xml
index 8d20ff2..6257576 100644
--- a/tests/TouchLatency/app/src/main/res/layout/activity_touch_latency.xml
+++ b/tests/TouchLatency/app/src/main/res/layout/activity_touch_latency.xml
@@ -18,6 +18,7 @@
     android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
     android:paddingRight="@dimen/activity_horizontal_margin"
     android:paddingTop="@dimen/activity_vertical_margin"
+    android:keepScreenOn="true"
     android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".TouchLatencyActivity">
 
     <com.prefabulated.touchlatency.TouchLatencyView
diff --git a/tests/TouchLatency/app/src/main/res/menu/menu_touch_latency.xml b/tests/TouchLatency/app/src/main/res/menu/menu_touch_latency.xml
index 5aef72e..52be919 100644
--- a/tests/TouchLatency/app/src/main/res/menu/menu_touch_latency.xml
+++ b/tests/TouchLatency/app/src/main/res/menu/menu_touch_latency.xml
@@ -15,6 +15,14 @@
 -->
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools" tools:context=".TouchLatencyActivity">
-    <item android:id="@+id/action_settings" android:title="@string/mode"
-        android:orderInCategory="100" android:showAsAction="always" />
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="101"
+        android:showAsAction="always"
+        android:title="@string/mode"/>
+    <item
+        android:id="@+id/display_mode"
+        android:showAsAction="ifRoom"
+        android:title="@string/display_mode"
+        android:visible="false"/>
 </menu>
diff --git a/tests/TouchLatency/app/src/main/res/values/strings.xml b/tests/TouchLatency/app/src/main/res/values/strings.xml
index b97f095..771992c 100644
--- a/tests/TouchLatency/app/src/main/res/values/strings.xml
+++ b/tests/TouchLatency/app/src/main/res/values/strings.xml
@@ -17,4 +17,5 @@
     <string name="app_name">Touch Latency</string>
 
     <string name="mode">Touch</string>
+    <string name="display_mode">Mode</string>
 </resources>
diff --git a/tests/net/java/android/net/IpPrefixTest.java b/tests/net/java/android/net/IpPrefixTest.java
index 3cc0e36..abf019a 100644
--- a/tests/net/java/android/net/IpPrefixTest.java
+++ b/tests/net/java/android/net/IpPrefixTest.java
@@ -231,7 +231,6 @@
         assertFalse(p.contains(Address("2001:db8:f00::ace:d00e")));
         assertFalse(p.contains(Address("2001:db8:f00::bad:d00d")));
         assertFalse(p.contains(Address("2001:4868:4860::8888")));
-        assertFalse(p.contains((InetAddress)null));
         assertFalse(p.contains(Address("8.8.8.8")));
 
         p = new IpPrefix("192.0.2.0/23");
diff --git a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java b/tests/net/java/android/net/ipmemorystore/ParcelableTests.java
index 76cccc9..1a3ea609 100644
--- a/tests/net/java/android/net/ipmemorystore/ParcelableTests.java
+++ b/tests/net/java/android/net/ipmemorystore/ParcelableTests.java
@@ -44,6 +44,8 @@
         assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable())));
 
         builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
+        // lease will expire in two hours
+        builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 7_200_000);
         // groupHint stays null this time around
         builder.setDnsAddresses(Collections.emptyList());
         builder.setMtu(18);
@@ -51,6 +53,7 @@
         assertEquals(in, new NetworkAttributes(parcelingRoundTrip(in.toParcelable())));
 
         builder.setAssignedV4Address((Inet4Address) Inet4Address.getByName("6.7.8.9"));
+        builder.setAssignedV4AddressExpiry(System.currentTimeMillis() + 3_600_000);
         builder.setGroupHint("groupHint");
         builder.setDnsAddresses(Arrays.asList(
                 InetAddress.getByName("ACA1:652B:0911:DE8F:1200:115E:913B:AA2A"),
@@ -66,7 +69,7 @@
         // Verify that this test does not miss any new field added later.
         // If any field is added to NetworkAttributes it must be tested here for parceling
         // roundtrip.
-        assertEquals(4, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
+        assertEquals(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
                 .filter(f -> !Modifier.isStatic(f.getModifiers())).count());
     }
 
diff --git a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
index 3e86e77..21a4988 100644
--- a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
+++ b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
@@ -25,8 +25,6 @@
 
 import android.net.DhcpResults;
 import android.net.LinkAddress;
-import android.net.StaticIpConfiguration;
-import android.net.apf.ApfCapabilities;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -43,21 +41,16 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class IpConfigurationParcelableUtilTest {
-    private StaticIpConfiguration mStaticIpConfiguration;
     private DhcpResults mDhcpResults;
 
     @Before
     public void setUp() {
-        mStaticIpConfiguration = new StaticIpConfiguration();
-        mStaticIpConfiguration.ipAddress = new LinkAddress(parseNumericAddress("2001:db8::42"), 64);
-        mStaticIpConfiguration.gateway = parseNumericAddress("192.168.42.42");
-        mStaticIpConfiguration.dnsServers.add(parseNumericAddress("2001:db8::43"));
-        mStaticIpConfiguration.dnsServers.add(parseNumericAddress("192.168.43.43"));
-        mStaticIpConfiguration.domains = "example.com";
-        // Any added StaticIpConfiguration field must be included in equals() to be tested properly
-        assertFieldCountEquals(4, StaticIpConfiguration.class);
-
-        mDhcpResults = new DhcpResults(mStaticIpConfiguration);
+        mDhcpResults = new DhcpResults();
+        mDhcpResults.ipAddress = new LinkAddress(parseNumericAddress("2001:db8::42"), 64);
+        mDhcpResults.gateway = parseNumericAddress("192.168.42.42");
+        mDhcpResults.dnsServers.add(parseNumericAddress("2001:db8::43"));
+        mDhcpResults.dnsServers.add(parseNumericAddress("192.168.43.43"));
+        mDhcpResults.domains = "example.com";
         mDhcpResults.serverAddress = (Inet4Address) parseNumericAddress("192.168.44.44");
         mDhcpResults.vendorInfo = "TEST_VENDOR_INFO";
         mDhcpResults.leaseDuration = 3600;
@@ -67,46 +60,35 @@
     }
 
     @Test
-    public void testParcelUnparcelStaticConfiguration() {
-        doStaticConfigurationParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcelStaticConfiguration_NullIpAddress() {
-        mStaticIpConfiguration.ipAddress = null;
-        doStaticConfigurationParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcelStaticConfiguration_NullGateway() {
-        mStaticIpConfiguration.gateway = null;
-        doStaticConfigurationParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcelStaticConfiguration_NullDomains() {
-        mStaticIpConfiguration.domains = null;
-        doStaticConfigurationParcelUnparcelTest();
-    }
-
-    @Test
-    public void testParcelUnparcelStaticConfiguration_EmptyDomains() {
-        mStaticIpConfiguration.domains = "";
-        doStaticConfigurationParcelUnparcelTest();
-    }
-
-    private void doStaticConfigurationParcelUnparcelTest() {
-        final StaticIpConfiguration unparceled =
-                fromStableParcelable(toStableParcelable(mStaticIpConfiguration));
-        assertEquals(mStaticIpConfiguration, unparceled);
-    }
-
-    @Test
     public void testParcelUnparcelDhcpResults() {
         doDhcpResultsParcelUnparcelTest();
     }
 
     @Test
+    public void testParcelUnparcelDhcpResults_NullIpAddress() {
+        mDhcpResults.ipAddress = null;
+        doDhcpResultsParcelUnparcelTest();
+    }
+
+    @Test
+    public void testParcelUnparcelDhcpResults_NullGateway() {
+        mDhcpResults.gateway = null;
+        doDhcpResultsParcelUnparcelTest();
+    }
+
+    @Test
+    public void testParcelUnparcelDhcpResults_NullDomains() {
+        mDhcpResults.domains = null;
+        doDhcpResultsParcelUnparcelTest();
+    }
+
+    @Test
+    public void testParcelUnparcelDhcpResults_EmptyDomains() {
+        mDhcpResults.domains = "";
+        doDhcpResultsParcelUnparcelTest();
+    }
+
+    @Test
     public void testParcelUnparcelDhcpResults_NullServerAddress() {
         mDhcpResults.serverAddress = null;
         doDhcpResultsParcelUnparcelTest();
@@ -122,10 +104,4 @@
         final DhcpResults unparceled = fromStableParcelable(toStableParcelable(mDhcpResults));
         assertEquals(mDhcpResults, unparceled);
     }
-
-    @Test
-    public void testParcelUnparcelApfCapabilities() {
-        final ApfCapabilities caps = new ApfCapabilities(123, 456, 789);
-        assertEquals(caps, fromStableParcelable(toStableParcelable(caps)));
-    }
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 1151214..44380cc 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -104,6 +104,7 @@
 import android.net.ConnectivityManager.PacketKeepaliveCallback;
 import android.net.ConnectivityManager.TooManyRequestsException;
 import android.net.ConnectivityThread;
+import android.net.IDnsResolver;
 import android.net.INetd;
 import android.net.INetworkMonitor;
 import android.net.INetworkMonitorCallbacks;
@@ -212,7 +213,6 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
 import java.util.function.Predicate;
 
 /**
@@ -241,6 +241,7 @@
     private static final String CLAT_PREFIX = "v4-";
     private static final String MOBILE_IFNAME = "test_rmnet_data0";
     private static final String WIFI_IFNAME = "test_wlan0";
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
 
     private MockContext mServiceContext;
     private WrappedConnectivityService mService;
@@ -257,6 +258,7 @@
     @Mock INetworkManagementService mNetworkManagementService;
     @Mock INetworkStatsService mStatsService;
     @Mock INetworkPolicyManager mNpm;
+    @Mock IDnsResolver mMockDnsResolver;
     @Mock INetd mMockNetd;
     @Mock NetworkStackClient mNetworkStack;
 
@@ -497,9 +499,8 @@
             };
 
             try {
-                doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected();
+                doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any());
                 doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt());
-                doAnswer(validateAnswer).when(mNetworkMonitor).setAcceptPartialConnectivity();
             } catch (RemoteException e) {
                 fail(e.getMessage());
             }
@@ -1055,8 +1056,8 @@
 
         public WrappedConnectivityService(Context context, INetworkManagementService netManager,
                 INetworkStatsService statsService, INetworkPolicyManager policyManager,
-                IpConnectivityLog log, INetd netd) {
-            super(context, netManager, statsService, policyManager, log);
+                IpConnectivityLog log, INetd netd, IDnsResolver dnsResolver) {
+            super(context, netManager, statsService, policyManager, dnsResolver, log);
             mNetd = netd;
             mLingerDelayMs = TEST_LINGER_DELAY_MS;
         }
@@ -1220,7 +1221,8 @@
                 mStatsService,
                 mNpm,
                 mock(IpConnectivityLog.class),
-                mMockNetd);
+                mMockNetd,
+                mMockDnsResolver);
 
         final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor =
                 ArgumentCaptor.forClass(INetworkPolicyListener.class);
@@ -2554,8 +2556,7 @@
         verifyActiveNetwork(TRANSPORT_CELLULAR);
     }
 
-    // TODO(b/128426024): deflake and re-enable
-    // @Test
+    @Test
     public void testPartialConnectivity() {
         // Register network callback.
         NetworkRequest request = new NetworkRequest.Builder()
@@ -2579,20 +2580,24 @@
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         callback.assertNoCallback();
 
+        // With HTTPS probe disabled, NetworkMonitor should pass the network validation with http
+        // probe.
+        mWiFiNetworkAgent.setNetworkValid();
         // If the user chooses yes to use this partial connectivity wifi, switch the default
         // network to wifi and check if wifi becomes valid or not.
         mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */,
                 false /* always */);
-        // With https probe disabled, NetworkMonitor should pass the network validation with http
-        // probe.
-        mWiFiNetworkAgent.setNetworkValid();
+        // If user accepts partial connectivity network,
+        // NetworkMonitor#setAcceptPartialConnectivity() should be called too.
         waitForIdle();
         try {
-            verify(mWiFiNetworkAgent.mNetworkMonitor,
-                    timeout(TIMEOUT_MS).times(1)).setAcceptPartialConnectivity();
+            verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
         } catch (RemoteException e) {
             fail(e.getMessage());
         }
+        // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
+        // validated.
+        mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
         NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED,
                 mWiFiNetworkAgent);
@@ -2622,6 +2627,15 @@
         // acceptUnvalidated is also used as setting for accepting partial networks.
         mWiFiNetworkAgent.explicitlySelected(true /* acceptUnvalidated */);
         mWiFiNetworkAgent.connect(true);
+        // If user accepted partial connectivity network before,
+        // NetworkMonitor#setAcceptPartialConnectivity() will be called in
+        // ConnectivityService#updateNetworkInfo().
+        waitForIdle();
+        try {
+            verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
+        } catch (RemoteException e) {
+            fail(e.getMessage());
+        }
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
         nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
@@ -2636,23 +2650,33 @@
         // NET_CAPABILITY_PARTIAL_CONNECTIVITY.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.explicitlySelected(true /* acceptUnvalidated */);
+        // Current design cannot send multi-testResult from NetworkMonitor to ConnectivityService.
+        // So, if user accepts partial connectivity, NetworkMonitor will send PARTIAL_CONNECTIVITY
+        // to ConnectivityService first then send VALID. Once NetworkMonitor support
+        // multi-testResult, this test case also need to be changed to meet the new design.
         mWiFiNetworkAgent.connectWithPartialConnectivity();
-        callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        // TODO: If the user accepted partial connectivity, we shouldn't switch to wifi until
-        // NetworkMonitor detects partial connectivity
-        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
-        mWiFiNetworkAgent.setNetworkValid();
+        // If user accepted partial connectivity network before,
+        // NetworkMonitor#setAcceptPartialConnectivity() will be called in
+        // ConnectivityService#updateNetworkInfo().
         waitForIdle();
         try {
-            verify(mWiFiNetworkAgent.mNetworkMonitor,
-                    timeout(TIMEOUT_MS).times(1)).setAcceptPartialConnectivity();
+            verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
         } catch (RemoteException e) {
             fail(e.getMessage());
         }
+        callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
-        callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent);
-        // Wifi should be the default network.
+        // TODO: If the user accepted partial connectivity, we shouldn't switch to wifi until
+        // NetworkMonitor detects partial connectivity
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent);
+        mWiFiNetworkAgent.setNetworkValid();
+        // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
+        // validated.
+        mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
+        callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        mWiFiNetworkAgent.disconnect();
+        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
     }
 
     @Test
@@ -3023,6 +3047,47 @@
     }
 
     @Test
+    public void testInvalidSignalStrength() {
+        NetworkRequest r = new NetworkRequest.Builder()
+                .addCapability(NET_CAPABILITY_INTERNET)
+                .addTransportType(TRANSPORT_WIFI)
+                .setSignalStrength(-75)
+                .build();
+        // Registering a NetworkCallback with signal strength but w/o NETWORK_SIGNAL_STRENGTH_WAKEUP
+        // permission should get SecurityException.
+        try {
+            mCm.registerNetworkCallback(r, new NetworkCallback());
+            fail("Expected SecurityException filing a callback with signal strength");
+        } catch (SecurityException expected) {
+            // expected
+        }
+
+        try {
+            mCm.registerNetworkCallback(r, PendingIntent.getService(
+                    mServiceContext, 0, new Intent(), 0));
+            fail("Expected SecurityException filing a callback with signal strength");
+        } catch (SecurityException expected) {
+            // expected
+        }
+
+        // Requesting a Network with signal strength should get IllegalArgumentException.
+        try {
+            mCm.requestNetwork(r, new NetworkCallback());
+            fail("Expected IllegalArgumentException filing a request with signal strength");
+        } catch (IllegalArgumentException expected) {
+            // expected
+        }
+
+        try {
+            mCm.requestNetwork(r, PendingIntent.getService(
+                    mServiceContext, 0, new Intent(), 0));
+            fail("Expected IllegalArgumentException filing a request with signal strength");
+        } catch (IllegalArgumentException expected) {
+            // expected
+        }
+    }
+
+    @Test
     public void testRegisterDefaultNetworkCallback() throws Exception {
         final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
         mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
@@ -4022,8 +4087,13 @@
         callback3.expectStopped();
     }
 
+    @FunctionalInterface
+    private interface ThrowingConsumer<T> {
+        void accept(T t) throws Exception;
+    }
+
     // Helper method to prepare the executor and run test
-    private void runTestWithSerialExecutors(Consumer<Executor> functor) {
+    private void runTestWithSerialExecutors(ThrowingConsumer<Executor> functor) throws Exception {
         final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor();
         final Executor executorInline = (Runnable r) -> r.run();
         functor.accept(executorSingleThread);
@@ -4032,23 +4102,15 @@
     }
 
     @Test
-    public void testNattSocketKeepalives() {
-        runTestWithSerialExecutors(executor -> {
-            try {
-                doTestNattSocketKeepalivesWithExecutor(executor);
-                doTestNattSocketKeepalivesFdWithExecutor(executor);
-            } catch (Exception e) {
-                fail(e.getMessage());
-            }
-        });
+    public void testNattSocketKeepalives() throws Exception {
+        runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor));
+        runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor));
     }
 
     private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception {
         // TODO: 1. Move this outside of ConnectivityServiceTest.
         //       2. Make test to verify that Nat-T keepalive socket is created by IpSecService.
         //       3. Mock ipsec service.
-        //       4. Find a free port instead of a fixed port.
-        final int srcPort = 12345;
         final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
         final InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
         final InetAddress myIPv6 = InetAddress.getByName("2001:db8::1");
@@ -4059,7 +4121,8 @@
         final int invalidKaInterval = 9;
 
         final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
-        final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(srcPort);
+        final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket();
+        final int srcPort = testSocket.getPort();
 
         LinkProperties lp = new LinkProperties();
         lp.setInterfaceName("wlan12");
@@ -4179,6 +4242,7 @@
 
         // Check that keepalive slots start from 1 and increment. The first one gets slot 1.
         mWiFiNetworkAgent.setExpectedKeepaliveSlot(1);
+        int srcPort2 = 0;
         try (SocketKeepalive ka = mCm.createSocketKeepalive(
                 myNet, testSocket, myIPv4, dstIPv4, executor, callback)) {
             ka.start(validKaInterval);
@@ -4186,7 +4250,8 @@
 
             // The second one gets slot 2.
             mWiFiNetworkAgent.setExpectedKeepaliveSlot(2);
-            final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket(6789);
+            final UdpEncapsulationSocket testSocket2 = mIpSec.openUdpEncapsulationSocket();
+            srcPort2 = testSocket2.getPort();
             TestSocketKeepaliveCallback callback2 = new TestSocketKeepaliveCallback(executor);
             try (SocketKeepalive ka2 = mCm.createSocketKeepalive(
                     myNet, testSocket2, myIPv4, dstIPv4, executor, callback2)) {
@@ -4204,20 +4269,18 @@
             }
         }
 
+        // Check that there is no port leaked after all keepalives and sockets are closed.
+        assertFalse(isUdpPortInUse(srcPort));
+        assertFalse(isUdpPortInUse(srcPort2));
+
         mWiFiNetworkAgent.disconnect();
         waitFor(mWiFiNetworkAgent.getDisconnectedCV());
         mWiFiNetworkAgent = null;
     }
 
     @Test
-    public void testTcpSocketKeepalives() {
-        runTestWithSerialExecutors(executor -> {
-            try {
-                doTestTcpSocketKeepalivesWithExecutor(executor);
-            } catch (Exception e) {
-                fail(e.getMessage());
-            }
-        });
+    public void testTcpSocketKeepalives() throws Exception {
+        runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor));
     }
 
     private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception {
@@ -4292,7 +4355,6 @@
     }
 
     private void doTestNattSocketKeepalivesFdWithExecutor(Executor executor) throws Exception {
-        final int srcPort = 12345;
         final InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
         final InetAddress anyIPv4 = InetAddress.getByName("0.0.0.0");
         final InetAddress dstIPv4 = InetAddress.getByName("8.8.8.8");
@@ -4311,7 +4373,8 @@
 
         // Prepare the target file descriptor, keep only one instance.
         final IpSecManager mIpSec = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
-        final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket(srcPort);
+        final UdpEncapsulationSocket testSocket = mIpSec.openUdpEncapsulationSocket();
+        final int srcPort = testSocket.getPort();
         final ParcelFileDescriptor testPfd =
                 ParcelFileDescriptor.dup(testSocket.getFileDescriptor());
         testSocket.close();
@@ -4759,14 +4822,14 @@
         ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class);
 
         // Clear any interactions that occur as a result of CS starting up.
-        reset(mNetworkManagementService);
+        reset(mMockDnsResolver);
 
-        final String[] EMPTY_STRING_ARRAY = new String[0];
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         waitForIdle();
-        verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork(
-                anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY));
-        verifyNoMoreInteractions(mNetworkManagementService);
+        verify(mMockDnsResolver, never()).setResolverConfiguration(
+                anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
+                eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+        verifyNoMoreInteractions(mMockDnsResolver);
 
         final LinkProperties cellLp = new LinkProperties();
         cellLp.setInterfaceName(MOBILE_IFNAME);
@@ -4783,28 +4846,29 @@
         mCellNetworkAgent.connect(false);
         waitForIdle();
         // CS tells netd about the empty DNS config for this network.
-        verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
-                anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY));
-        reset(mNetworkManagementService);
+        verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
+                anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
+                eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+        reset(mMockDnsResolver);
 
         cellLp.addDnsServer(InetAddress.getByName("2001:db8::1"));
         mCellNetworkAgent.sendLinkProperties(cellLp);
         waitForIdle();
-        verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+        verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
                 anyInt(), mStringArrayCaptor.capture(), any(), any(),
-                eq(""), tlsServers.capture());
+                eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
         assertEquals(1, mStringArrayCaptor.getValue().length);
         assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "2001:db8::1"));
         // Opportunistic mode.
         assertTrue(ArrayUtils.contains(tlsServers.getValue(), "2001:db8::1"));
-        reset(mNetworkManagementService);
+        reset(mMockDnsResolver);
 
         cellLp.addDnsServer(InetAddress.getByName("192.0.2.1"));
         mCellNetworkAgent.sendLinkProperties(cellLp);
         waitForIdle();
-        verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+        verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
                 anyInt(), mStringArrayCaptor.capture(), any(), any(),
-                eq(""), tlsServers.capture());
+                eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
         assertEquals(2, mStringArrayCaptor.getValue().length);
         assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
@@ -4812,7 +4876,7 @@
         assertEquals(2, tlsServers.getValue().length);
         assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
-        reset(mNetworkManagementService);
+        reset(mMockDnsResolver);
 
         final String TLS_SPECIFIER = "tls.example.com";
         final String TLS_SERVER6 = "2001:db8:53::53";
@@ -4822,22 +4886,21 @@
                 new PrivateDnsConfig(TLS_SPECIFIER, TLS_IPS).toParcel());
 
         waitForIdle();
-        verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+        verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
                 anyInt(), mStringArrayCaptor.capture(), any(), any(),
-                eq(TLS_SPECIFIER), eq(TLS_SERVERS));
+                eq(TLS_SPECIFIER), eq(TLS_SERVERS), eq(EMPTY_STRING_ARRAY));
         assertEquals(2, mStringArrayCaptor.getValue().length);
         assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
-        reset(mNetworkManagementService);
+        reset(mMockDnsResolver);
     }
 
     @Test
     public void testPrivateDnsSettingsChange() throws Exception {
-        final String[] EMPTY_STRING_ARRAY = new String[0];
         ArgumentCaptor<String[]> tlsServers = ArgumentCaptor.forClass(String[].class);
 
         // Clear any interactions that occur as a result of CS starting up.
-        reset(mNetworkManagementService);
+        reset(mMockDnsResolver);
 
         // The default on Android is opportunistic mode ("Automatic").
         setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
@@ -4850,9 +4913,10 @@
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         waitForIdle();
         // CS tells netd about the empty DNS config for this network.
-        verify(mNetworkManagementService, never()).setDnsConfigurationForNetwork(
-                anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""), eq(EMPTY_STRING_ARRAY));
-        verifyNoMoreInteractions(mNetworkManagementService);
+        verify(mMockDnsResolver, never()).setResolverConfiguration(
+                anyInt(), eq(EMPTY_STRING_ARRAY), any(), any(), eq(""),
+                eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+        verifyNoMoreInteractions(mMockDnsResolver);
 
         final LinkProperties cellLp = new LinkProperties();
         cellLp.setInterfaceName(MOBILE_IFNAME);
@@ -4871,9 +4935,9 @@
         mCellNetworkAgent.sendLinkProperties(cellLp);
         mCellNetworkAgent.connect(false);
         waitForIdle();
-        verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+        verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
                 anyInt(), mStringArrayCaptor.capture(), any(), any(),
-                eq(""), tlsServers.capture());
+                eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
         assertEquals(2, mStringArrayCaptor.getValue().length);
         assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
@@ -4881,7 +4945,7 @@
         assertEquals(2, tlsServers.getValue().length);
         assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
-        reset(mNetworkManagementService);
+        reset(mMockDnsResolver);
         cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
         cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
                 mCellNetworkAgent);
@@ -4893,26 +4957,26 @@
         assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
 
         setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
-        verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork(
+        verify(mMockDnsResolver, times(1)).setResolverConfiguration(
                 anyInt(), mStringArrayCaptor.capture(), any(), any(),
-                eq(""), eq(EMPTY_STRING_ARRAY));
+                eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
         assertEquals(2, mStringArrayCaptor.getValue().length);
         assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
-        reset(mNetworkManagementService);
+        reset(mMockDnsResolver);
         cellNetworkCallback.assertNoCallback();
 
         setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
-        verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
+        verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
                 anyInt(), mStringArrayCaptor.capture(), any(), any(),
-                eq(""), tlsServers.capture());
+                eq(""), tlsServers.capture(), eq(EMPTY_STRING_ARRAY));
         assertEquals(2, mStringArrayCaptor.getValue().length);
         assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
         assertEquals(2, tlsServers.getValue().length);
         assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
-        reset(mNetworkManagementService);
+        reset(mMockDnsResolver);
         cellNetworkCallback.assertNoCallback();
 
         setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com");
@@ -5743,6 +5807,7 @@
         cellLp.addRoute(new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME));
         cellLp.addRoute(new RouteInfo(myIpv6, null, MOBILE_IFNAME));
         reset(mNetworkManagementService);
+        reset(mMockDnsResolver);
         when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
                 .thenReturn(getClatInterfaceConfig(myIpv4));
 
@@ -5750,7 +5815,7 @@
         mCellNetworkAgent.sendLinkProperties(cellLp);
         mCellNetworkAgent.connect(true);
         networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
-        verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
+        verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
 
         // Switching default network updates TCP buffer sizes.
         verifyTcpBufferSizeChange(ConnectivityService.DEFAULT_TCP_BUFFER_SIZES);
@@ -5760,17 +5825,22 @@
         cellLp.addLinkAddress(myIpv4);
         mCellNetworkAgent.sendLinkProperties(cellLp);
         networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
-        verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId);
+        verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
+        verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(
+                eq(cellNetId), eq(EMPTY_STRING_ARRAY), any(), any(),
+                eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
 
         verifyNoMoreInteractions(mMockNetd);
+        verifyNoMoreInteractions(mMockDnsResolver);
         reset(mMockNetd);
+        reset(mMockDnsResolver);
 
         // Remove IPv4 address. Expect prefix discovery to be started again.
         cellLp.removeLinkAddress(myIpv4);
         cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
         mCellNetworkAgent.sendLinkProperties(cellLp);
         networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
-        verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
+        verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
 
         // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started.
         Nat464Xlat clat = mService.getNat464Xlat(mCellNetworkAgent);
@@ -5800,6 +5870,12 @@
         assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST);
         assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0));
 
+        verify(mMockDnsResolver, times(1)).setResolverConfiguration(
+                eq(cellNetId), mStringArrayCaptor.capture(), any(), any(),
+                eq(""), eq(EMPTY_STRING_ARRAY), eq(EMPTY_STRING_ARRAY));
+        assertEquals(1, mStringArrayCaptor.getValue().length);
+        assertTrue(ArrayUtils.contains(mStringArrayCaptor.getValue(), "8.8.8.8"));
+
         // Add ipv4 address, expect that clatd and prefix discovery are stopped and stacked
         // linkproperties are cleaned up.
         cellLp.addLinkAddress(myIpv4);
@@ -5807,7 +5883,7 @@
         mCellNetworkAgent.sendLinkProperties(cellLp);
         networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
         verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
-        verify(mMockNetd, times(1)).resolverStopPrefix64Discovery(cellNetId);
+        verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
 
         // As soon as stop is called, the linkproperties lose the stacked interface.
         networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
@@ -5822,7 +5898,9 @@
         networkCallback.assertNoCallback();
 
         verifyNoMoreInteractions(mMockNetd);
+        verifyNoMoreInteractions(mMockDnsResolver);
         reset(mMockNetd);
+        reset(mMockDnsResolver);
 
         // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.
         mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
@@ -5836,7 +5914,7 @@
         cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8"));
         mCellNetworkAgent.sendLinkProperties(cellLp);
         networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
-        verify(mMockNetd, times(1)).resolverStartPrefix64Discovery(cellNetId);
+        verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
         mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
                 kNat64PrefixString, 96);
         networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
@@ -5919,6 +5997,7 @@
 
         // Disconnect cell
         reset(mNetworkManagementService);
+        reset(mMockNetd);
         mCellNetworkAgent.disconnect();
         networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
         // LOST callback is triggered earlier than removing idle timer. Broadcast should also be
@@ -5926,8 +6005,9 @@
         // unexpectedly before network being removed.
         waitForIdle();
         verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
-        verify(mNetworkManagementService, times(1)).removeNetwork(
-                eq(mCellNetworkAgent.getNetwork().netId));
+        verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId));
+        verify(mMockDnsResolver, times(1))
+                .clearResolverConfiguration(eq(mCellNetworkAgent.getNetwork().netId));
 
         // Disconnect wifi
         ConditionVariable cv = waitForConnectivityBroadcasts(1);
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index 15ba43d..8fa0ab9 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -29,13 +29,13 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.net.IDnsResolver;
 import android.net.IpPrefix;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.Network;
 import android.net.RouteInfo;
 import android.net.shared.PrivateDnsConfig;
-import android.os.INetworkManagementService;
 import android.provider.Settings;
 import android.test.mock.MockContentResolver;
 
@@ -73,7 +73,7 @@
     MockContentResolver mContentResolver;
 
     @Mock Context mCtx;
-    @Mock INetworkManagementService mNMService;
+    @Mock IDnsResolver mMockDnsResolver;
     @Mock MockableSystemProperties mSystemProperties;
 
     @Before
@@ -83,7 +83,7 @@
         mContentResolver.addProvider(Settings.AUTHORITY,
                 new FakeSettingsProvider());
         when(mCtx.getContentResolver()).thenReturn(mContentResolver);
-        mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties);
+        mDnsManager = new DnsManager(mCtx, mMockDnsResolver, mSystemProperties);
 
         // Clear the private DNS settings
         Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "");
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 6de4aa1..142769f 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -32,6 +32,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.IDnsResolver;
 import android.net.INetd;
 import android.net.Network;
 import android.net.NetworkCapabilities;
@@ -69,6 +70,7 @@
     LingerMonitor mMonitor;
 
     @Mock ConnectivityService mConnService;
+    @Mock IDnsResolver mDnsResolver;
     @Mock INetd mNetd;
     @Mock INetworkManagementService mNMS;
     @Mock Context mCtx;
@@ -353,7 +355,7 @@
         caps.addCapability(0);
         caps.addTransportType(transport);
         NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
-                caps, 50, mCtx, null, mMisc, mConnService, mNetd, mNMS,
+                caps, 50, mCtx, null, mMisc, mConnService, mNetd, mDnsResolver, mNMS,
                 NetworkFactory.SerialNumber.NONE);
         nai.everValidated = true;
         return nai;
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
index cc09fb7..b709af1 100644
--- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.when;
 
 import android.net.ConnectivityManager;
+import android.net.IDnsResolver;
 import android.net.INetd;
 import android.net.InterfaceConfiguration;
 import android.net.IpPrefix;
@@ -63,6 +64,7 @@
 
     @Mock ConnectivityService mConnectivity;
     @Mock NetworkMisc mMisc;
+    @Mock IDnsResolver mDnsResolver;
     @Mock INetd mNetd;
     @Mock INetworkManagementService mNms;
     @Mock InterfaceConfiguration mConfig;
@@ -72,7 +74,7 @@
     Handler mHandler;
 
     Nat464Xlat makeNat464Xlat() {
-        return new Nat464Xlat(mNai, mNetd, mNms) {
+        return new Nat464Xlat(mNai, mNetd, mDnsResolver, mNms) {
             @Override protected int getNetId() {
                 return NETID;
             }
@@ -205,7 +207,7 @@
         verify(mNms).unregisterObserver(eq(nat));
         assertTrue(c.getValue().getStackedLinks().isEmpty());
         assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
-        verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
+        verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
         assertIdle(nat);
 
         // Stacked interface removed notification arrives and is ignored.
@@ -331,7 +333,7 @@
         verify(mNetd).clatdStop(eq(BASE_IFACE));
         verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
         verify(mNms).unregisterObserver(eq(nat));
-        verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
+        verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
         assertTrue(c.getValue().getStackedLinks().isEmpty());
         assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
         assertIdle(nat);
@@ -358,7 +360,7 @@
 
         verify(mNetd).clatdStop(eq(BASE_IFACE));
         verify(mNms).unregisterObserver(eq(nat));
-        verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
+        verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
         assertIdle(nat);
 
         // In-flight interface up notification arrives: no-op
@@ -390,7 +392,7 @@
 
         verify(mNetd).clatdStop(eq(BASE_IFACE));
         verify(mNms).unregisterObserver(eq(nat));
-        verify(mNetd).resolverStopPrefix64Discovery(eq(NETID));
+        verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
         assertIdle(nat);
 
         verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index 354c08f..106cd1f 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -20,10 +20,13 @@
 import static android.Manifest.permission.CHANGE_WIFI_STATE;
 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
 import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
+import static android.Manifest.permission.INTERNET;
 import static android.Manifest.permission.NETWORK_STACK;
+import static android.Manifest.permission.UPDATE_DEVICE_STATS;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
+import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.os.Process.SYSTEM_UID;
 
@@ -41,26 +44,35 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageList;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.net.INetd;
 import android.os.Build;
 import android.os.INetworkManagementService;
 import android.os.UserHandle;
+import android.util.SparseIntArray;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.LocalServices;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 
 @RunWith(AndroidJUnit4.class)
@@ -69,7 +81,11 @@
     private static final int MOCK_USER1 = 0;
     private static final int MOCK_USER2 = 1;
     private static final int MOCK_UID1 = 10001;
+    private static final int MOCK_UID2 = 10086;
+    private static final int SYSTEM_UID1 = 1000;
+    private static final int SYSTEM_UID2 = 1008;
     private static final String MOCK_PACKAGE1 = "appName1";
+    private static final String MOCK_PACKAGE2 = "appName2";
     private static final String SYSTEM_PACKAGE1 = "sysName1";
     private static final String SYSTEM_PACKAGE2 = "sysName2";
     private static final String PARTITION_SYSTEM = "system";
@@ -82,14 +98,29 @@
     @Mock private Context mContext;
     @Mock private PackageManager mPackageManager;
     @Mock private INetworkManagementService mNMS;
+    @Mock private INetd mNetdService;
+    @Mock private PackageManagerInternal mMockPmi;
 
+    private PackageManagerInternal.PackageListObserver mObserver;
     private PermissionMonitor mPermissionMonitor;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
-        mPermissionMonitor = spy(new PermissionMonitor(mContext, mNMS));
+        mPermissionMonitor = spy(new PermissionMonitor(mContext, mNMS, mNetdService));
+
+        LocalServices.removeServiceForTest(PackageManagerInternal.class);
+        LocalServices.addService(PackageManagerInternal.class, mMockPmi);
+        when(mMockPmi.getPackageList(any())).thenReturn(new PackageList(new ArrayList<String>(),
+                  /* observer */ null));
+        when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(/* empty app list */ null);
+        mPermissionMonitor.startMonitoring();
+
+        final ArgumentCaptor<PackageManagerInternal.PackageListObserver> observerCaptor =
+                ArgumentCaptor.forClass(PackageManagerInternal.PackageListObserver.class);
+        verify(mMockPmi).getPackageList(observerCaptor.capture());
+        mObserver = observerCaptor.getValue();
     }
 
     private boolean hasBgPermission(String partition, int targetSdkVersion, int uid,
@@ -104,9 +135,20 @@
     }
 
     private PackageInfo packageInfoWithPermissions(String[] permissions, String partition) {
+        int[] requestedPermissionsFlags = new int[permissions.length];
+        for (int i = 0; i < permissions.length; i++) {
+            requestedPermissionsFlags[i] = REQUESTED_PERMISSION_GRANTED;
+        }
+        return packageInfoWithPermissions(permissions, partition,
+                requestedPermissionsFlags);
+    }
+
+    private PackageInfo packageInfoWithPermissions(String[] permissions, String partition,
+            int[] requestedPermissionsFlags) {
         final PackageInfo packageInfo = new PackageInfo();
         packageInfo.requestedPermissions = permissions;
         packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.requestedPermissionsFlags = requestedPermissionsFlags;
         int privateFlags = 0;
         switch (partition) {
             case PARTITION_OEM:
@@ -337,4 +379,164 @@
             mPermissionMonitor.onPackageRemoved(UserHandle.getUid(user, uid));
         }
     }
+
+    private class NetdServiceMonitor {
+        private final HashMap<Integer, Integer> mPermissions = new HashMap<>();
+
+        NetdServiceMonitor(INetd mockNetdService) throws Exception {
+            // Add hook to verify and track result of setPermission.
+            doAnswer((InvocationOnMock invocation) -> {
+                final Object[] args = invocation.getArguments();
+                final int permission = (int) args[0];
+                for (final int uid : (int[]) args[1]) {
+                    mPermissions.put(uid, permission);
+                }
+                return null;
+            }).when(mockNetdService).trafficSetNetPermForUids(anyInt(), any(int[].class));
+        }
+
+        public void expectPermission(int permission, int[] apps) {
+            for (final int app : apps) {
+                if (!mPermissions.containsKey(app)) {
+                    fail("uid " + app + " does not exist.");
+                }
+                if (mPermissions.get(app) != permission) {
+                    fail("uid " + app + " has wrong permission: " + mPermissions.get(app));
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testPackagePermissionUpdate() throws Exception {
+        final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+        // MOCK_UID1: MOCK_PACKAGE1 only has internet permission.
+        // MOCK_UID2: MOCK_PACKAGE2 does not have any permission.
+        // SYSTEM_UID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission.
+        // SYSTEM_UID2: SYSTEM_PACKAGE2 has only update device stats permission.
+
+        SparseIntArray netdPermissionsAppIds = new SparseIntArray();
+        netdPermissionsAppIds.put(MOCK_UID1, INetd.PERMISSION_INTERNET);
+        netdPermissionsAppIds.put(MOCK_UID2, INetd.NO_PERMISSIONS);
+        netdPermissionsAppIds.put(SYSTEM_UID1, INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS);
+        netdPermissionsAppIds.put(SYSTEM_UID2, INetd.PERMISSION_UPDATE_DEVICE_STATS);
+
+        // Send the permission information to netd, expect permission updated.
+        mPermissionMonitor.sendPackagePermissionsToNetd(netdPermissionsAppIds);
+
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET,
+                new int[]{MOCK_UID1});
+        mNetdServiceMonitor.expectPermission(INetd.NO_PERMISSIONS, new int[]{MOCK_UID2});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{SYSTEM_UID1});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UPDATE_DEVICE_STATS,
+                new int[]{SYSTEM_UID2});
+
+        // Update permission of MOCK_UID1, expect new permission show up.
+        mPermissionMonitor.sendPackagePermissionsForUid(MOCK_UID1,
+                INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS);
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+
+        // Change permissions of SYSTEM_UID2, expect new permission show up and old permission
+        // revoked.
+        mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID2,
+                INetd.PERMISSION_INTERNET);
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{SYSTEM_UID2});
+
+        // Revoke permission from SYSTEM_UID1, expect no permission stored.
+        mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID1, INetd.NO_PERMISSIONS);
+        mNetdServiceMonitor.expectPermission(INetd.NO_PERMISSIONS, new int[]{SYSTEM_UID1});
+    }
+
+    private PackageInfo addPackage(String packageName, int uid, String[] permissions)
+            throws Exception {
+        PackageInfo packageInfo = packageInfoWithPermissions(permissions, PARTITION_SYSTEM);
+        when(mPackageManager.getPackageInfo(eq(packageName), anyInt())).thenReturn(packageInfo);
+        when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[]{packageName});
+        mObserver.onPackageAdded(packageName, uid);
+        return packageInfo;
+    }
+
+    @Test
+    public void testPackageInstall() throws Exception {
+        final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+
+        addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+
+        addPackage(MOCK_PACKAGE2, MOCK_UID2, new String[] {INTERNET});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID2});
+    }
+
+    @Test
+    public void testPackageInstallSharedUid() throws Exception {
+        final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+
+        PackageInfo packageInfo1 = addPackage(MOCK_PACKAGE1, MOCK_UID1,
+                new String[] {INTERNET, UPDATE_DEVICE_STATS});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+
+        // Install another package with the same uid and no permissions should not cause the UID to
+        // lose permissions.
+        PackageInfo packageInfo2 = packageInfoWithPermissions(new String[]{}, PARTITION_SYSTEM);
+        when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
+        when(mPackageManager.getPackagesForUid(MOCK_UID1))
+              .thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
+        mObserver.onPackageAdded(MOCK_PACKAGE2, MOCK_UID1);
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+    }
+
+    @Test
+    public void testPackageUninstallBasic() throws Exception {
+        final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+
+        addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+
+        when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
+        mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
+    }
+
+    @Test
+    public void testPackageUpdate() throws Exception {
+        final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+
+        addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+
+        // Remove and install the same package to simulate the update action
+        when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
+        mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
+
+        addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+    }
+
+    @Test
+    public void testPackageUninstallWithMultiplePackages() throws Exception {
+        final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+
+        addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+                | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+
+        // Mock another package with the same uid but different permissions.
+        PackageInfo packageInfo2 = packageInfoWithPermissions(new String[] {INTERNET},
+                PARTITION_SYSTEM);
+        when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
+        when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{
+                MOCK_PACKAGE2});
+
+        mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+    }
 }
diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
index bac5098..d28ab70 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.connectivity.tethering;
 
+import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
 import static android.net.ConnectivityManager.TETHERING_USB;
 import static android.net.ConnectivityManager.TETHERING_WIFI;
 import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN;
@@ -30,6 +31,8 @@
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.ContentResolver;
@@ -72,12 +75,14 @@
 
     private static final int EVENT_EM_UPDATE = 1;
     private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
+    private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
 
     @Mock private CarrierConfigManager mCarrierConfigManager;
     @Mock private Context mContext;
     @Mock private MockableSystemProperties mSystemProperties;
     @Mock private Resources mResources;
     @Mock private SharedLog mLog;
+    @Mock private EntitlementManager.OnUiEntitlementFailedListener mEntitlementFailedListener;
 
     // Like so many Android system APIs, these cannot be mocked because it is marked final.
     // We have to use the real versions.
@@ -107,18 +112,31 @@
 
     public class WrappedEntitlementManager extends EntitlementManager {
         public int fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKONWN;
-        public boolean everRunUiEntitlement = false;
+        public int uiProvisionCount = 0;
+        public int silentProvisionCount = 0;
 
         public WrappedEntitlementManager(Context ctx, StateMachine target,
-                SharedLog log, MockableSystemProperties systemProperties) {
-            super(ctx, target, log, systemProperties);
+                SharedLog log, int what, MockableSystemProperties systemProperties) {
+            super(ctx, target, log, what, systemProperties);
+        }
+
+        public void reset() {
+            fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKONWN;
+            uiProvisionCount = 0;
+            silentProvisionCount = 0;
         }
 
         @Override
         protected void runUiTetherProvisioning(int type, ResultReceiver receiver) {
-            everRunUiEntitlement = true;
+            uiProvisionCount++;
             receiver.send(fakeEntitlementResult, null);
         }
+
+        @Override
+        protected void runSilentTetherProvisioning(int type) {
+            silentProvisionCount++;
+            addDownstreamMapping(type, fakeEntitlementResult);
+        }
     }
 
     @Before
@@ -141,7 +159,9 @@
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         mMockContext = new MockContext(mContext);
         mSM = new TestStateMachine();
-        mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, mSystemProperties);
+        mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, EVENT_EM_UPDATE,
+                mSystemProperties);
+        mEnMgr.setOnUiEntitlementFailedListener(mEntitlementFailedListener);
         mEnMgr.updateConfiguration(
                 new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
     }
@@ -158,7 +178,9 @@
         // Produce some acceptable looking provision app setting if requested.
         when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
                 .thenReturn(PROVISIONING_APP_NAME);
-        // Don't disable tethering provisioning unless requested.
+        when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
+                .thenReturn(PROVISIONING_NO_UI_APP_NAME);
+       // Don't disable tethering provisioning unless requested.
         when(mSystemProperties.getBoolean(eq(EntitlementManager.DISABLE_PROVISIONING_SYSPROP_KEY),
                 anyBoolean())).thenReturn(false);
         // Act like the CarrierConfigManager is present and ready unless told otherwise.
@@ -229,7 +251,6 @@
         final CountDownLatch mCallbacklatch = new CountDownLatch(1);
         // 1. Entitlement check is not required.
         mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
-        mEnMgr.everRunUiEntitlement = false;
         ResultReceiver receiver = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -238,14 +259,15 @@
             }
         };
         mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
+        mLooper.dispatchAll();
         callbackTimeoutHelper(mCallbacklatch);
-        assertFalse(mEnMgr.everRunUiEntitlement);
+        assertEquals(0, mEnMgr.uiProvisionCount);
+        mEnMgr.reset();
 
         setupForRequiredProvisioning();
         mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
                   INVALID_SUBSCRIPTION_ID));
         // 2. No cache value and don't need to run entitlement check.
-        mEnMgr.everRunUiEntitlement = false;
         receiver = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -254,11 +276,12 @@
             }
         };
         mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
+        mLooper.dispatchAll();
         callbackTimeoutHelper(mCallbacklatch);
-        assertFalse(mEnMgr.everRunUiEntitlement);
+        assertEquals(0, mEnMgr.uiProvisionCount);
+        mEnMgr.reset();
         // 3. No cache value and ui entitlement check is needed.
         mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
-        mEnMgr.everRunUiEntitlement = false;
         receiver = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -269,10 +292,10 @@
         mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
         mLooper.dispatchAll();
         callbackTimeoutHelper(mCallbacklatch);
-        assertTrue(mEnMgr.everRunUiEntitlement);
+        assertEquals(1, mEnMgr.uiProvisionCount);
+        mEnMgr.reset();
         // 4. Cache value is TETHER_ERROR_PROVISION_FAILED and don't need to run entitlement check.
         mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
-        mEnMgr.everRunUiEntitlement = false;
         receiver = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -281,11 +304,12 @@
             }
         };
         mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
+        mLooper.dispatchAll();
         callbackTimeoutHelper(mCallbacklatch);
-        assertFalse(mEnMgr.everRunUiEntitlement);
+        assertEquals(0, mEnMgr.uiProvisionCount);
+        mEnMgr.reset();
         // 5. Cache value is TETHER_ERROR_PROVISION_FAILED and ui entitlement check is needed.
         mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
-        mEnMgr.everRunUiEntitlement = false;
         receiver = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -296,10 +320,10 @@
         mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
         mLooper.dispatchAll();
         callbackTimeoutHelper(mCallbacklatch);
-        assertTrue(mEnMgr.everRunUiEntitlement);
+        assertEquals(1, mEnMgr.uiProvisionCount);
+        mEnMgr.reset();
         // 6. Cache value is TETHER_ERROR_NO_ERROR.
         mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
-        mEnMgr.everRunUiEntitlement = false;
         receiver = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -308,10 +332,11 @@
             }
         };
         mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
+        mLooper.dispatchAll();
         callbackTimeoutHelper(mCallbacklatch);
-        assertFalse(mEnMgr.everRunUiEntitlement);
+        assertEquals(0, mEnMgr.uiProvisionCount);
+        mEnMgr.reset();
         // 7. Test get value for other downstream type.
-        mEnMgr.everRunUiEntitlement = false;
         receiver = new ResultReceiver(null) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
@@ -320,19 +345,152 @@
             }
         };
         mEnMgr.getLatestTetheringEntitlementResult(TETHERING_USB, receiver, false);
+        mLooper.dispatchAll();
         callbackTimeoutHelper(mCallbacklatch);
-        assertFalse(mEnMgr.everRunUiEntitlement);
+        assertEquals(0, mEnMgr.uiProvisionCount);
+        mEnMgr.reset();
     }
 
     void callbackTimeoutHelper(final CountDownLatch latch) throws Exception {
         if (!latch.await(1, TimeUnit.SECONDS)) {
-            fail("Timout, fail to recieve callback");
+            fail("Timout, fail to receive callback");
         }
     }
+
+    @Test
+    public void verifyPermissionResult() {
+        setupForRequiredProvisioning();
+        mEnMgr.notifyUpstream(true);
+        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+                  INVALID_SUBSCRIPTION_ID));
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+        mLooper.dispatchAll();
+        assertFalse(mEnMgr.isCellularUpstreamPermitted());
+        mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
+        mLooper.dispatchAll();
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
+        mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+        mLooper.dispatchAll();
+        assertTrue(mEnMgr.isCellularUpstreamPermitted());
+    }
+
+    @Test
+    public void verifyPermissionIfAllNotApproved() {
+        setupForRequiredProvisioning();
+        mEnMgr.notifyUpstream(true);
+        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+                  INVALID_SUBSCRIPTION_ID));
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+        mLooper.dispatchAll();
+        assertFalse(mEnMgr.isCellularUpstreamPermitted());
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
+        mLooper.dispatchAll();
+        assertFalse(mEnMgr.isCellularUpstreamPermitted());
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
+        mLooper.dispatchAll();
+        assertFalse(mEnMgr.isCellularUpstreamPermitted());
+    }
+
+    @Test
+    public void verifyPermissionIfAnyApproved() {
+        setupForRequiredProvisioning();
+        mEnMgr.notifyUpstream(true);
+        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+                  INVALID_SUBSCRIPTION_ID));
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
+        mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+        mLooper.dispatchAll();
+        assertTrue(mEnMgr.isCellularUpstreamPermitted());
+        mLooper.dispatchAll();
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
+        mLooper.dispatchAll();
+        assertTrue(mEnMgr.isCellularUpstreamPermitted());
+        mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
+        mLooper.dispatchAll();
+        assertFalse(mEnMgr.isCellularUpstreamPermitted());
+
+    }
+
+    @Test
+    public void testRunTetherProvisioning() {
+        setupForRequiredProvisioning();
+        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+                INVALID_SUBSCRIPTION_ID));
+        // 1. start ui provisioning, upstream is mobile
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
+        mEnMgr.notifyUpstream(true);
+        mLooper.dispatchAll();
+        mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
+        mLooper.dispatchAll();
+        assertEquals(1, mEnMgr.uiProvisionCount);
+        assertEquals(0, mEnMgr.silentProvisionCount);
+        assertTrue(mEnMgr.isCellularUpstreamPermitted());
+        mEnMgr.reset();
+        // 2. start no-ui provisioning
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
+        mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, false);
+        mLooper.dispatchAll();
+        assertEquals(0, mEnMgr.uiProvisionCount);
+        assertEquals(1, mEnMgr.silentProvisionCount);
+        assertTrue(mEnMgr.isCellularUpstreamPermitted());
+        mEnMgr.reset();
+        // 3. tear down mobile, then start ui provisioning
+        mEnMgr.notifyUpstream(false);
+        mLooper.dispatchAll();
+        mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
+        mLooper.dispatchAll();
+        assertEquals(0, mEnMgr.uiProvisionCount);
+        assertEquals(0, mEnMgr.silentProvisionCount);
+        mEnMgr.reset();
+        // 4. switch upstream back to mobile
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
+        mEnMgr.notifyUpstream(true);
+        mLooper.dispatchAll();
+        assertEquals(1, mEnMgr.uiProvisionCount);
+        assertEquals(0, mEnMgr.silentProvisionCount);
+        assertTrue(mEnMgr.isCellularUpstreamPermitted());
+        mEnMgr.reset();
+        // 5. tear down mobile, then switch SIM
+        mEnMgr.notifyUpstream(false);
+        mLooper.dispatchAll();
+        mEnMgr.reevaluateSimCardProvisioning();
+        assertEquals(0, mEnMgr.uiProvisionCount);
+        assertEquals(0, mEnMgr.silentProvisionCount);
+        mEnMgr.reset();
+        // 6. switch upstream back to mobile again
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.notifyUpstream(true);
+        mLooper.dispatchAll();
+        assertEquals(0, mEnMgr.uiProvisionCount);
+        assertEquals(3, mEnMgr.silentProvisionCount);
+        mEnMgr.reset();
+    }
+
+    @Test
+    public void testCallStopTetheringWhenUiProvisioningFail() {
+        setupForRequiredProvisioning();
+        mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
+                INVALID_SUBSCRIPTION_ID));
+        verify(mEntitlementFailedListener, times(0)).onUiEntitlementFailed(TETHERING_WIFI);
+        mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
+        mEnMgr.notifyUpstream(true);
+        mLooper.dispatchAll();
+        mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
+        mLooper.dispatchAll();
+        assertEquals(1, mEnMgr.uiProvisionCount);
+        verify(mEntitlementFailedListener, times(1)).onUiEntitlementFailed(TETHERING_WIFI);
+    }
+
+
     public class TestStateMachine extends StateMachine {
         public final ArrayList<Message> messages = new ArrayList<>();
-        private final State mLoggingState =
-                new EntitlementManagerTest.TestStateMachine.LoggingState();
+        private final State
+                mLoggingState = new EntitlementManagerTest.TestStateMachine.LoggingState();
 
         class LoggingState extends State {
             @Override public void enter() {
diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
index 36a1b7c..2140322 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
@@ -122,7 +122,7 @@
         mMockContext = new MockContext(mContext);
     }
 
-    private TetheringConfiguration getTetheringConfiguration(int[] legacyTetherUpstreamTypes) {
+    private TetheringConfiguration getTetheringConfiguration(int... legacyTetherUpstreamTypes) {
         when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(
                 legacyTetherUpstreamTypes);
         return new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -143,13 +143,13 @@
     public void testDunFromTelephonyManagerMeansDun() {
         when(mTelephonyManager.getTetherApnRequired()).thenReturn(true);
 
-        final TetheringConfiguration cfgWifi = getTetheringConfiguration(new int[]{TYPE_WIFI});
+        final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
         final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
-                new int[]{TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI});
+                TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI);
         final TetheringConfiguration cfgWifiDun = getTetheringConfiguration(
-                new int[]{TYPE_WIFI, TYPE_MOBILE_DUN});
+                TYPE_WIFI, TYPE_MOBILE_DUN);
         final TetheringConfiguration cfgMobileWifiHipriDun = getTetheringConfiguration(
-                new int[]{TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI, TYPE_MOBILE_DUN});
+                TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI, TYPE_MOBILE_DUN);
 
         for (TetheringConfiguration cfg : Arrays.asList(cfgWifi, cfgMobileWifiHipri,
                 cfgWifiDun, cfgMobileWifiHipriDun)) {
@@ -167,20 +167,20 @@
     public void testDunNotRequiredFromTelephonyManagerMeansNoDun() {
         when(mTelephonyManager.getTetherApnRequired()).thenReturn(false);
 
-        final TetheringConfiguration cfgWifi = getTetheringConfiguration(new int[]{TYPE_WIFI});
+        final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
         final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
-                new int[]{TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI});
+                TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI);
         final TetheringConfiguration cfgWifiDun = getTetheringConfiguration(
-                new int[]{TYPE_WIFI, TYPE_MOBILE_DUN});
+                TYPE_WIFI, TYPE_MOBILE_DUN);
         final TetheringConfiguration cfgWifiMobile = getTetheringConfiguration(
-                new int[]{TYPE_WIFI, TYPE_MOBILE});
+                TYPE_WIFI, TYPE_MOBILE);
         final TetheringConfiguration cfgWifiHipri = getTetheringConfiguration(
-                new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI});
+                TYPE_WIFI, TYPE_MOBILE_HIPRI);
         final TetheringConfiguration cfgMobileWifiHipriDun = getTetheringConfiguration(
-                new int[]{TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI, TYPE_MOBILE_DUN});
+                TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI, TYPE_MOBILE_DUN);
 
         String msg;
-        // TYPE_MOBILE_DUN should not be present in all of the combinations.
+        // TYPE_MOBILE_DUN should be present in none of the combinations.
         // TYPE_WIFI should not be affected.
         for (TetheringConfiguration cfg : Arrays.asList(cfgWifi, cfgMobileWifiHipri, cfgWifiDun,
                 cfgWifiMobile, cfgWifiHipri, cfgMobileWifiHipriDun)) {
diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
index 5a1f853..0d276cb 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
@@ -90,6 +90,7 @@
     private static final NetworkRequest mDefaultRequest = new NetworkRequest.Builder().build();
 
     @Mock private Context mContext;
+    @Mock private EntitlementManager mEntitleMgr;
     @Mock private IConnectivityManager mCS;
     @Mock private SharedLog mLog;
 
@@ -103,6 +104,7 @@
         reset(mCS);
         reset(mLog);
         when(mLog.forSubComponent(anyString())).thenReturn(mLog);
+        when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
 
         mCM = spy(new TestConnectivityManager(mContext, mCS));
         mSM = new TestStateMachine();
@@ -138,7 +140,7 @@
     @Test
     public void testDefaultNetworkIsTracked() throws Exception {
         assertTrue(mCM.hasNoCallbacks());
-        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
 
         mUNM.startObserveAllNetworks();
         assertEquals(1, mCM.trackingDefault.size());
@@ -151,7 +153,7 @@
     public void testListensForAllNetworks() throws Exception {
         assertTrue(mCM.listening.isEmpty());
 
-        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
         mUNM.startObserveAllNetworks();
         assertFalse(mCM.listening.isEmpty());
         assertTrue(mCM.isListeningForAll());
@@ -162,7 +164,7 @@
 
     @Test
     public void testCallbacksRegistered() {
-        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
         verify(mCM, times(1)).requestNetwork(
                 eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class));
         mUNM.startObserveAllNetworks();
@@ -285,7 +287,7 @@
         final Collection<Integer> preferredTypes = new ArrayList<>();
         preferredTypes.add(TYPE_WIFI);
 
-        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
         mUNM.startObserveAllNetworks();
         // There are no networks, so there is nothing to select.
         assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
@@ -319,6 +321,14 @@
         NetworkRequest netReq = (NetworkRequest) mCM.requested.values().toArray()[0];
         assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR));
         assertFalse(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN));
+        // mobile is not permitted, we should not use HIPRI.
+        when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
+        assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
+        assertEquals(0, mCM.requested.size());
+        // mobile change back to permitted, HIRPI should come back
+        when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
+        assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
+                mUNM.selectPreferredUpstreamType(preferredTypes));
 
         wifiAgent.fakeConnect();
         // WiFi is up, and we should prefer it over cell.
@@ -347,11 +357,19 @@
         netReq = (NetworkRequest) mCM.requested.values().toArray()[0];
         assertTrue(netReq.networkCapabilities.hasTransport(TRANSPORT_CELLULAR));
         assertTrue(netReq.networkCapabilities.hasCapability(NET_CAPABILITY_DUN));
+        // mobile is not permitted, we should not use DUN.
+        when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
+        assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
+        assertEquals(0, mCM.requested.size());
+        // mobile change back to permitted, DUN should come back
+        when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
+        assertSatisfiesLegacyType(TYPE_MOBILE_DUN,
+                mUNM.selectPreferredUpstreamType(preferredTypes));
     }
 
     @Test
     public void testGetCurrentPreferredUpstream() throws Exception {
-        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
         mUNM.startObserveAllNetworks();
         mUNM.updateMobileRequiresDun(false);
 
@@ -361,37 +379,46 @@
         mCM.makeDefaultNetwork(cellAgent);
         assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
 
-        // [1] WiFi connects but not validated/promoted to default -> mobile selected.
+        // [1] Mobile connects but not permitted -> null selected
+        when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
+        assertEquals(null, mUNM.getCurrentPreferredUpstream());
+        when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(true);
+
+        // [2] WiFi connects but not validated/promoted to default -> mobile selected.
         final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
         wifiAgent.fakeConnect();
         assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
 
-        // [2] WiFi validates and is promoted to the default network -> WiFi selected.
+        // [3] WiFi validates and is promoted to the default network -> WiFi selected.
         mCM.makeDefaultNetwork(wifiAgent);
         assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
 
-        // [3] DUN required, no other changes -> WiFi still selected
+        // [4] DUN required, no other changes -> WiFi still selected
         mUNM.updateMobileRequiresDun(true);
         assertEquals(wifiAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
 
-        // [4] WiFi no longer validated, mobile becomes default, DUN required -> null selected.
+        // [5] WiFi no longer validated, mobile becomes default, DUN required -> null selected.
         mCM.makeDefaultNetwork(cellAgent);
         assertEquals(null, mUNM.getCurrentPreferredUpstream());
         // TODO: make sure that a DUN request has been filed. This is currently
         // triggered by code over in Tethering, but once that has been moved
         // into UNM we should test for this here.
 
-        // [5] DUN network arrives -> DUN selected
+        // [6] DUN network arrives -> DUN selected
         final TestNetworkAgent dunAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
         dunAgent.networkCapabilities.addCapability(NET_CAPABILITY_DUN);
         dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
         dunAgent.fakeConnect();
         assertEquals(dunAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
+
+        // [7] Mobile is not permitted -> null selected
+        when(mEntitleMgr.isCellularUpstreamPermitted()).thenReturn(false);
+        assertEquals(null, mUNM.getCurrentPreferredUpstream());
     }
 
     @Test
     public void testLocalPrefixes() throws Exception {
-        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
         mUNM.startObserveAllNetworks();
 
         // [0] Test minimum set of local prefixes.
@@ -492,6 +519,26 @@
         assertTrue(local.isEmpty());
     }
 
+    @Test
+    public void testSelectMobileWhenMobileIsNotDefault() {
+        final Collection<Integer> preferredTypes = new ArrayList<>();
+        // Mobile has higher pirority than wifi.
+        preferredTypes.add(TYPE_MOBILE_HIPRI);
+        preferredTypes.add(TYPE_WIFI);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+        mUNM.startObserveAllNetworks();
+        // Setup wifi and make wifi as default network.
+        final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
+        wifiAgent.fakeConnect();
+        mCM.makeDefaultNetwork(wifiAgent);
+        // Setup mobile network.
+        final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
+        cellAgent.fakeConnect();
+
+        assertSatisfiesLegacyType(TYPE_MOBILE_HIPRI,
+                mUNM.selectPreferredUpstreamType(preferredTypes));
+        verify(mEntitleMgr, times(1)).maybeRunProvisioning();
+    }
     private void assertSatisfiesLegacyType(int legacyType, NetworkState ns) {
         if (legacyType == TYPE_NONE) {
             assertTrue(ns == null);
diff --git a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
index dc20185..a83faf3 100644
--- a/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
+++ b/tests/net/java/com/android/server/net/ipmemorystore/NetworkAttributesTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.net.ipmemorystore;
+package com.android.server.connectivity.ipmemorystore;
 
 import static org.junit.Assert.assertEquals;
 
@@ -57,6 +57,7 @@
         final NetworkAttributes na =
                 new NetworkAttributes(
                         (Inet4Address) Inet4Address.getByAddress(new byte[] {1, 2, 3, 4}),
+                        System.currentTimeMillis() + 7_200_000,
                         "some hint",
                         Arrays.asList(Inet4Address.getByAddress(new byte[] {5, 6, 7, 8}),
                                 Inet4Address.getByAddress(new byte[] {9, 0, 1, 2})),
diff --git a/tests/testables/src/android/testing/TestableContext.java b/tests/testables/src/android/testing/TestableContext.java
index fff9635..e2668bc 100644
--- a/tests/testables/src/android/testing/TestableContext.java
+++ b/tests/testables/src/android/testing/TestableContext.java
@@ -296,13 +296,13 @@
     @Override
     public void registerComponentCallbacks(ComponentCallbacks callback) {
         if (mComponent != null) mComponent.getLeakInfo(callback).addAllocation(new Throwable());
-        super.registerComponentCallbacks(callback);
+        getBaseContext().registerComponentCallbacks(callback);
     }
 
     @Override
     public void unregisterComponentCallbacks(ComponentCallbacks callback) {
         if (mComponent != null) mComponent.getLeakInfo(callback).clearAllocations();
-        super.unregisterComponentCallbacks(callback);
+        getBaseContext().unregisterComponentCallbacks(callback);
     }
 
     public TestablePermissions getTestablePermissions() {
diff --git a/tests/utils/testutils/java/com/android/server/wm/test/filters/CoreTestsFilter.java b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
similarity index 77%
rename from tests/utils/testutils/java/com/android/server/wm/test/filters/CoreTestsFilter.java
rename to tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
index 1a81c2c..e0d74e0 100644
--- a/tests/utils/testutils/java/com/android/server/wm/test/filters/CoreTestsFilter.java
+++ b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
@@ -26,23 +26,25 @@
  * <p>Use this filter when running FrameworksCoreTests as
  * <pre>
  * adb shell am instrument -w \
- *     -e filter com.android.server.wm.test.filters.CoreTestsFilter  \
+ *     -e filter com.android.server.wm.test.filters.FrameworksTestsFilter  \
  *     -e selectTest_verbose true \
  *     com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
  * </pre>
  */
-public final class CoreTestsFilter extends SelectTest {
+public final class FrameworksTestsFilter extends SelectTest {
 
-    private static final String[] SELECTED_CORE_TESTS = {
+    private static final String[] SELECTED_TESTS = {
+            // Test specifications for FrameworksCoreTests.
             "android.app.servertransaction.", // all tests under the package.
             "android.view.DisplayCutoutTest",
+            "android.view.InsetsAnimationControlImplTest",
             "android.view.InsetsControllerTest",
             "android.view.InsetsSourceTest",
             "android.view.InsetsSourceConsumerTest",
             "android.view.InsetsStateTest",
     };
 
-    public CoreTestsFilter(Bundle testArgs) {
-        super(addSelectTest(testArgs, SELECTED_CORE_TESTS));
+    public FrameworksTestsFilter(Bundle testArgs) {
+        super(addSelectTest(testArgs, SELECTED_TESTS));
     }
 }
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 5336141..8577921 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -217,6 +217,29 @@
   EXPECT_THAT(str->value->spans[1].last_char, Eq(13u));
 }
 
+TEST_F(ResourceParserTest, ParseStringTranslatableAttribute) {
+  // If there is no translate attribute the default is 'true'
+  EXPECT_TRUE(TestParse(R"(<string name="foo1">Translate</string>)"));
+  String* str = test::GetValue<String>(&table_, "string/foo1");
+  ASSERT_THAT(str, NotNull());
+  ASSERT_TRUE(str->IsTranslatable());
+
+  // Explicit 'true' translate attribute
+  EXPECT_TRUE(TestParse(R"(<string name="foo2" translatable="true">Translate</string>)"));
+  str = test::GetValue<String>(&table_, "string/foo2");
+  ASSERT_THAT(str, NotNull());
+  ASSERT_TRUE(str->IsTranslatable());
+
+  // Explicit 'false' translate attribute
+  EXPECT_TRUE(TestParse(R"(<string name="foo3" translatable="false">Do not translate</string>)"));
+  str = test::GetValue<String>(&table_, "string/foo3");
+  ASSERT_THAT(str, NotNull());
+  ASSERT_FALSE(str->IsTranslatable());
+
+  // Invalid value for the translate attribute, should be boolean ('true' or 'false')
+  EXPECT_FALSE(TestParse(R"(<string name="foo4" translatable="yes">Translate</string>)"));
+}
+
 TEST_F(ResourceParserTest, IgnoreXliffTagsOtherThanG) {
   std::string input = R"(
       <string name="foo" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 7c0619f..1773b5a 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -357,37 +357,6 @@
                          (validate_resources_ ? ResolveValueCollision : IgnoreCollision), diag);
 }
 
-bool ResourceTable::AddFileReference(const ResourceNameRef& name,
-                                     const ConfigDescription& config,
-                                     const Source& source,
-                                     const StringPiece& path,
-                                     IDiagnostics* diag) {
-  return AddFileReferenceImpl(name, config, source, path, nullptr,
-                              (validate_resources_ ? ResourceNameValidator : SkipNameValidator),
-                              diag);
-}
-
-bool ResourceTable::AddFileReferenceMangled(const ResourceNameRef& name,
-                                            const ConfigDescription& config, const Source& source,
-                                            const StringPiece& path, io::IFile* file,
-                                            IDiagnostics* diag) {
-  return AddFileReferenceImpl(name, config, source, path, file,
-                              (validate_resources_ ? ResourceNameValidator : SkipNameValidator),
-                              diag);
-}
-
-bool ResourceTable::AddFileReferenceImpl(const ResourceNameRef& name,
-                                         const ConfigDescription& config, const Source& source,
-                                         const StringPiece& path, io::IFile* file,
-                                         NameValidator name_validator, IDiagnostics* diag) {
-  std::unique_ptr<FileReference> fileRef =
-      util::make_unique<FileReference>(string_pool.MakeRef(path));
-  fileRef->SetSource(source);
-  fileRef->file = file;
-  return AddResourceImpl(name, ResourceId{}, config, StringPiece{}, std::move(fileRef),
-                         name_validator, ResolveValueCollision, diag);
-}
-
 bool ResourceTable::AddResourceMangled(const ResourceNameRef& name, const ConfigDescription& config,
                                        const StringPiece& product, std::unique_ptr<Value> value,
                                        IDiagnostics* diag) {
@@ -512,11 +481,6 @@
   return SetVisibilityImpl(name, visibility, {}, ResourceNameValidator, diag);
 }
 
-bool ResourceTable::SetVisibilityMangled(const ResourceNameRef& name, const Visibility& visibility,
-                                         IDiagnostics* diag) {
-  return SetVisibilityImpl(name, visibility, {}, SkipNameValidator, diag);
-}
-
 bool ResourceTable::SetVisibilityWithId(const ResourceNameRef& name, const Visibility& visibility,
                                         const ResourceId& res_id, IDiagnostics* diag) {
   return SetVisibilityImpl(name, visibility, res_id, ResourceNameValidator, diag);
@@ -634,11 +598,6 @@
   return SetOverlayableImpl(name, overlayable, ResourceNameValidator, diag);
 }
 
-bool ResourceTable::SetOverlayableMangled(const ResourceNameRef& name,
-                                          const OverlayableItem& overlayable, IDiagnostics* diag) {
-  return SetOverlayableImpl(name, overlayable, SkipNameValidator, diag);
-}
-
 bool ResourceTable::SetOverlayableImpl(const ResourceNameRef& name,
                                        const OverlayableItem& overlayable,
                                        NameValidator name_validator, IDiagnostics *diag) {
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 32dfd26..7ed7897 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -239,13 +239,6 @@
                          const android::StringPiece& product, std::unique_ptr<Value> value,
                          IDiagnostics* diag);
 
-  bool AddFileReference(const ResourceNameRef& name, const android::ConfigDescription& config,
-                        const Source& source, const android::StringPiece& path, IDiagnostics* diag);
-
-  bool AddFileReferenceMangled(const ResourceNameRef& name, const android::ConfigDescription& config,
-                               const Source& source, const android::StringPiece& path,
-                               io::IFile* file, IDiagnostics* diag);
-
   // Same as AddResource, but doesn't verify the validity of the name. This is used
   // when loading resources from an existing binary resource table that may have mangled names.
   bool AddResourceMangled(const ResourceNameRef& name, const android::ConfigDescription& config,
@@ -260,8 +253,6 @@
   bool GetValidateResources();
 
   bool SetVisibility(const ResourceNameRef& name, const Visibility& visibility, IDiagnostics* diag);
-  bool SetVisibilityMangled(const ResourceNameRef& name, const Visibility& visibility,
-                            IDiagnostics* diag);
   bool SetVisibilityWithId(const ResourceNameRef& name, const Visibility& visibility,
                            const ResourceId& res_id, IDiagnostics* diag);
   bool SetVisibilityWithIdMangled(const ResourceNameRef& name, const Visibility& visibility,
@@ -269,8 +260,6 @@
 
   bool SetOverlayable(const ResourceNameRef& name, const OverlayableItem& overlayable,
                       IDiagnostics *diag);
-  bool SetOverlayableMangled(const ResourceNameRef& name, const OverlayableItem& overlayable,
-                             IDiagnostics* diag);
 
   bool SetAllowNew(const ResourceNameRef& name, const AllowNew& allow_new, IDiagnostics* diag);
   bool SetAllowNewMangled(const ResourceNameRef& name, const AllowNew& allow_new,
@@ -333,10 +322,6 @@
                        NameValidator name_validator, const CollisionResolverFunc& conflict_resolver,
                        IDiagnostics* diag);
 
-  bool AddFileReferenceImpl(const ResourceNameRef& name, const android::ConfigDescription& config,
-                            const Source& source, const android::StringPiece& path, io::IFile* file,
-                            NameValidator name_validator, IDiagnostics* diag);
-
   bool SetVisibilityImpl(const ResourceNameRef& name, const Visibility& visibility,
                          const ResourceId& res_id, NameValidator name_validator,
                          IDiagnostics* diag);
@@ -347,10 +332,6 @@
   bool SetOverlayableImpl(const ResourceNameRef &name, const OverlayableItem& overlayable,
                           NameValidator name_validator, IDiagnostics *diag);
 
-  bool SetSymbolStateImpl(const ResourceNameRef& name, const ResourceId& res_id,
-                          const Visibility& symbol, NameValidator name_validator,
-                          IDiagnostics* diag);
-
   // Controls whether the table validates resource names and prevents duplicate resource names
   bool validate_resources_ = true;
 
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 2ec1ab3..9b81369f 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -143,6 +143,8 @@
                          const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer,
                          const std::string& output_path) {
   TRACE_CALL();
+  // Filenames starting with "donottranslate" are not localizable
+  bool translatable_file = path_data.name.find("donottranslate") != 0;
   ResourceTable table;
   {
     auto fin = file->OpenInputStream();
@@ -157,9 +159,7 @@
 
     ResourceParserOptions parser_options;
     parser_options.error_on_positional_arguments = !options.legacy_mode;
-
-    // If the filename includes donottranslate, then the default translatable is false.
-    parser_options.translatable = path_data.name.find("donottranslate") == std::string::npos;
+    parser_options.translatable = translatable_file;
 
     // If visibility was forced, we need to use it when creating a new resource and also error if
     // we try to parse the <public>, <public-group>, <java-symbol> or <symbol> tags.
@@ -172,7 +172,7 @@
     }
   }
 
-  if (options.pseudolocalize) {
+  if (options.pseudolocalize && translatable_file) {
     // Generate pseudo-localized strings (en-XA and ar-XB).
     // These are created as weak symbols, and are only generated from default
     // configuration
diff --git a/tools/aapt2/cmd/Compile_test.cpp b/tools/aapt2/cmd/Compile_test.cpp
index c0c05cd..5f637bd 100644
--- a/tools/aapt2/cmd/Compile_test.cpp
+++ b/tools/aapt2/cmd/Compile_test.cpp
@@ -27,6 +27,8 @@
 
 namespace aapt {
 
+using CompilerTest = CommandTestFixture;
+
 std::string BuildPath(std::vector<std::string> args) {
   std::string out;
   if (args.empty()) {
@@ -51,7 +53,7 @@
   return CompileCommand(&diag).Execute(args, &std::cerr);
 }
 
-TEST(CompilerTest, MultiplePeriods) {
+TEST_F(CompilerTest, MultiplePeriods) {
   StdErrDiagnostics diag;
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   const std::string kResDir = BuildPath({android::base::Dirname(android::base::GetExecutablePath()),
@@ -108,7 +110,7 @@
   ASSERT_EQ(::android::base::utf8::unlink(path5_out.c_str()), 0);
 }
 
-TEST(CompilerTest, DirInput) {
+TEST_F(CompilerTest, DirInput) {
   StdErrDiagnostics diag;
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   const std::string kResDir = BuildPath({android::base::Dirname(android::base::GetExecutablePath()),
@@ -138,7 +140,7 @@
   ASSERT_EQ(::android::base::utf8::unlink(kOutputFlata.c_str()), 0);
 }
 
-TEST(CompilerTest, ZipInput) {
+TEST_F(CompilerTest, ZipInput) {
   StdErrDiagnostics diag;
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
   const std::string kResZip =
@@ -169,4 +171,86 @@
   ASSERT_EQ(::android::base::utf8::unlink(kOutputFlata.c_str()), 0);
 }
 
-}  // namespace aapt
\ No newline at end of file
+/*
+ * This tests the "protection" from pseudo-translation of
+ * non-translatable files (starting with 'donotranslate')
+ * and strings (with the translatable="false" attribute)
+ *
+ * We check 4 string files, 2 translatable, and 2 not (based on file name)
+ * Each file contains 2 strings, one translatable, one not (attribute based)
+ * Each of these files are compiled and linked into one .apk, then we load the
+ * strings from the apk and check if there are pseudo-translated strings.
+ */
+
+// Using 000 and 111 because they are not changed by pseudo-translation,
+// making our life easier.
+constexpr static const char sTranslatableXmlContent[] =
+    "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+    "<resources>"
+    "  <string name=\"normal\">000</string>"
+    "  <string name=\"non_translatable\" translatable=\"false\">111</string>"
+    "</resources>";
+
+static void AssertTranslations(CommandTestFixture *ctf, std::string file_name,
+    std::vector<std::string> expected) {
+
+  StdErrDiagnostics diag;
+
+  const std::string source_file = ctf->GetTestPath("/res/values/" + file_name + ".xml");
+  const std::string compiled_files_dir = ctf->GetTestPath("/compiled_" + file_name);
+  const std::string out_apk = ctf->GetTestPath("/" + file_name + ".apk");
+
+  CHECK(ctf->WriteFile(source_file, sTranslatableXmlContent));
+  CHECK(file::mkdirs(compiled_files_dir.data()));
+
+  ASSERT_EQ(CompileCommand(&diag).Execute({
+      source_file,
+      "-o", compiled_files_dir,
+      "-v",
+      "--pseudo-localize"
+  }, &std::cerr), 0);
+
+  ASSERT_TRUE(ctf->Link({
+      "--manifest", ctf->GetDefaultManifest(),
+      "-o", out_apk
+  }, compiled_files_dir, &diag));
+
+  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+
+  ResourceTable* table = apk->GetResourceTable();
+  ASSERT_NE(table, nullptr);
+  table->string_pool.Sort();
+
+  const std::vector<std::unique_ptr<StringPool::Entry>>& pool_strings =
+      table->string_pool.strings();
+
+  // The actual / expected vectors have the same size
+  const size_t pool_size = pool_strings.size();
+  ASSERT_EQ(pool_size, expected.size());
+
+  for (size_t i = 0; i < pool_size; i++) {
+    std::string actual = pool_strings[i]->value;
+    ASSERT_EQ(actual, expected[i]);
+  }
+}
+
+TEST_F(CompilerTest, DoNotTranslateTest) {
+  // The first string (000) is translatable, the second is not
+  // ar-XB uses "\u200F\u202E...\u202C\u200F"
+  std::vector<std::string> expected_translatable = {
+      "000", "111", // default locale
+      "[000 one]", // en-XA
+      "\xE2\x80\x8F\xE2\x80\xAE" "000" "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB
+  };
+  AssertTranslations(this, "foo", expected_translatable);
+  AssertTranslations(this, "foo_donottranslate", expected_translatable);
+
+  // No translatable strings because these are non-translatable files
+  std::vector<std::string> expected_not_translatable = {
+      "000", "111", // default locale
+  };
+  AssertTranslations(this, "donottranslate", expected_not_translatable);
+  AssertTranslations(this, "donottranslate_foo", expected_not_translatable);
+}
+
+}  // namespace aapt
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index e17fb47..92f1ddb 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -2314,7 +2314,7 @@
 int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* printer,
                  IDiagnostics* diag) {
   ManifestExtractor extractor(apk, options);
-  return extractor.Dump(printer, diag);
+  return extractor.Dump(printer, diag) ? 0 : 1;
 }
 
 } // namespace aapt
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index f967c2f..97ca6dc 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -2147,6 +2147,8 @@
             del cur[prev_clazz.fullname]
 
     for clazz in cur.values():
+        if not is_interesting(clazz): continue
+
         if "deprecated" in clazz.split and not clazz.fullname in prev:
             error(clazz, None, None, "Found API deprecation at birth")
 
diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp
index 0f555b1..1a91f52 100644
--- a/tools/bit/main.cpp
+++ b/tools/bit/main.cpp
@@ -856,7 +856,7 @@
             // TODO: if (!apk.file.fileInfo.exists || apk.file.HasChanged())
             err = run_adb("shell", "mkdir", "-p", dir.c_str(), NULL);
             check_error(err);
-            err = run_adb("push", pushed.file.filename.c_str(), pushed.dest.c_str());
+            err = run_adb("push", pushed.file.filename.c_str(), pushed.dest.c_str(), NULL);
             check_error(err);
             // pushed.installed = true;
         }
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index ce9becd..f191f6c 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -475,6 +475,11 @@
     _emoji_sequences = remove_emoji_exclude(_emoji_sequences, exclusions)
     _emoji_zwj_sequences = remove_emoji_exclude(_emoji_zwj_sequences, exclusions)
     _emoji_variation_sequences = remove_emoji_variation_exclude(_emoji_variation_sequences, exclusions)
+    # Unicode 12.0 adds Basic_Emoji in emoji-sequences.txt. We ignore them here since we are already
+    # checking the emoji presentations with emoji-variation-sequences.txt.
+    # Please refer to http://unicode.org/reports/tr51/#def_basic_emoji_set .
+    _emoji_sequences = {k: v for k, v in _emoji_sequences.iteritems() if not v == 'Basic_Emoji' }
+
 
 def remove_emoji_variation_exclude(source, items):
     return source.difference(items.keys())
@@ -542,56 +547,6 @@
 ]
 
 ZWJ = 0x200D
-FEMALE_SIGN = 0x2640
-MALE_SIGN = 0x2642
-
-GENDER_DEFAULTS = [
-    (0x26F9, MALE_SIGN), # PERSON WITH BALL
-    (0x1F3C3, MALE_SIGN), # RUNNER
-    (0x1F3C4, MALE_SIGN), # SURFER
-    (0x1F3CA, MALE_SIGN), # SWIMMER
-    (0x1F3CB, MALE_SIGN), # WEIGHT LIFTER
-    (0x1F3CC, MALE_SIGN), # GOLFER
-    (0x1F46E, MALE_SIGN), # POLICE OFFICER
-    (0x1F46F, FEMALE_SIGN), # WOMAN WITH BUNNY EARS
-    (0x1F471, MALE_SIGN), # PERSON WITH BLOND HAIR
-    (0x1F473, MALE_SIGN), # MAN WITH TURBAN
-    (0x1F477, MALE_SIGN), # CONSTRUCTION WORKER
-    (0x1F481, FEMALE_SIGN), # INFORMATION DESK PERSON
-    (0x1F482, MALE_SIGN), # GUARDSMAN
-    (0x1F486, FEMALE_SIGN), # FACE MASSAGE
-    (0x1F487, FEMALE_SIGN), # HAIRCUT
-    (0x1F575, MALE_SIGN), # SLEUTH OR SPY
-    (0x1F645, FEMALE_SIGN), # FACE WITH NO GOOD GESTURE
-    (0x1F646, FEMALE_SIGN), # FACE WITH OK GESTURE
-    (0x1F647, MALE_SIGN), # PERSON BOWING DEEPLY
-    (0x1F64B, FEMALE_SIGN), # HAPPY PERSON RAISING ONE HAND
-    (0x1F64D, FEMALE_SIGN), # PERSON FROWNING
-    (0x1F64E, FEMALE_SIGN), # PERSON WITH POUTING FACE
-    (0x1F6A3, MALE_SIGN), # ROWBOAT
-    (0x1F6B4, MALE_SIGN), # BICYCLIST
-    (0x1F6B5, MALE_SIGN), # MOUNTAIN BICYCLIST
-    (0x1F6B6, MALE_SIGN), # PEDESTRIAN
-    (0x1F926, FEMALE_SIGN), # FACE PALM
-    (0x1F937, FEMALE_SIGN), # SHRUG
-    (0x1F938, MALE_SIGN), # PERSON DOING CARTWHEEL
-    (0x1F939, MALE_SIGN), # JUGGLING
-    (0x1F93C, MALE_SIGN), # WRESTLERS
-    (0x1F93D, MALE_SIGN), # WATER POLO
-    (0x1F93E, MALE_SIGN), # HANDBALL
-    (0x1F9D6, FEMALE_SIGN), # PERSON IN STEAMY ROOM
-    (0x1F9D7, FEMALE_SIGN), # PERSON CLIMBING
-    (0x1F9D8, FEMALE_SIGN), # PERSON IN LOTUS POSITION
-    (0x1F9D9, FEMALE_SIGN), # MAGE
-    (0x1F9DA, FEMALE_SIGN), # FAIRY
-    (0x1F9DB, FEMALE_SIGN), # VAMPIRE
-    (0x1F9DC, FEMALE_SIGN), # MERPERSON
-    (0x1F9DD, FEMALE_SIGN), # ELF
-    (0x1F9DE, FEMALE_SIGN), # GENIE
-    (0x1F9DF, FEMALE_SIGN), # ZOMBIE
-    (0X1F9B8, FEMALE_SIGN), # SUPERVILLAIN
-    (0x1F9B9, FEMALE_SIGN), # SUPERHERO
-]
 
 def is_fitzpatrick_modifier(cp):
     return 0x1F3FB <= cp <= 0x1F3FF
@@ -666,13 +621,6 @@
     equivalent_emoji.update(LEGACY_ANDROID_EMOJI)
     equivalent_emoji.update(ZWJ_IDENTICALS)
 
-    for ch, gender in GENDER_DEFAULTS:
-        equivalent_emoji[(ch, ZWJ, gender)] = ch
-        for skin_tone in range(0x1F3FB, 0x1F3FF+1):
-            skin_toned = (ch, skin_tone, ZWJ, gender)
-            if skin_toned in all_emoji:
-                equivalent_emoji[skin_toned] = (ch, skin_tone)
-
     for seq in _emoji_variation_sequences:
         equivalent_emoji[seq] = seq[0]
 
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index 6781eba..c856cc3 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -21,6 +21,7 @@
 import os
 import sys
 import re
+import functools
 
 # Names of flags recognized by the `hiddenapi` tool.
 FLAG_WHITELIST = "whitelist"
@@ -58,6 +59,10 @@
 # script to skip any entries which do not exist any more.
 FLAG_IGNORE_CONFLICTS_SUFFIX = "-ignore-conflicts"
 
+# Suffix used in command line args to express that all apis within a given set
+# of packages should be assign the given flag.
+FLAG_PACKAGES_SUFFIX = "-packages"
+
 # Regex patterns of fields/methods used in serialization. These are
 # considered public API despite being hidden.
 SERIALIZATION_PATTERNS = [
@@ -91,12 +96,16 @@
 
     for flag in ALL_FLAGS:
         ignore_conflicts_flag = flag + FLAG_IGNORE_CONFLICTS_SUFFIX
+        packages_flag = flag + FLAG_PACKAGES_SUFFIX
         parser.add_argument('--' + flag, dest=flag, nargs='*', default=[], metavar='TXT_FILE',
             help='lists of entries with flag "' + flag + '"')
         parser.add_argument('--' + ignore_conflicts_flag, dest=ignore_conflicts_flag, nargs='*',
             default=[], metavar='TXT_FILE',
             help='lists of entries with flag "' + flag +
                  '". skip entry if missing or flag conflict.')
+        parser.add_argument('--' + packages_flag, dest=packages_flag, nargs='*',
+            default=[], metavar='TXT_FILE',
+            help='lists of packages to be added to ' + flag + ' list')
 
     return parser.parse_args()
 
@@ -128,6 +137,19 @@
     with open(filename, 'w') as f:
         f.writelines(lines)
 
+def extract_package(signature):
+    """Extracts the package from a signature.
+
+    Args:
+        signature (string): JNI signature of a method or field.
+
+    Returns:
+        The package name of the class containing the field/method.
+    """
+    full_class_name = signature.split(";->")[0]
+    package_name = full_class_name[1:full_class_name.rindex("/")]
+    return package_name.replace('/', '.')
+
 class FlagsDict:
     def __init__(self):
         self._dict_keyset = set()
@@ -206,7 +228,10 @@
         self._dict_keyset.update([ csv[0] for csv in csv_values ])
 
         # Check that all flags are known.
-        csv_flags = set(reduce(lambda x, y: set(x).union(y), [ csv[1:] for csv in csv_values ], []))
+        csv_flags = set(functools.reduce(
+            lambda x, y: set(x).union(y),
+            [ csv[1:] for csv in csv_values ],
+            []))
         self._check_flags_set(csv_flags, source)
 
         # Iterate over all CSV lines, find entry in dict and append flags to it.
@@ -273,6 +298,15 @@
             valid_entries = flags.get_valid_subset_of_unassigned_apis(read_lines(filename))
             flags.assign_flag(flag, valid_entries, filename)
 
+    # All members in the specified packages will be assigned the appropriate flag.
+    for flag in ALL_FLAGS:
+        for filename in args[flag + FLAG_PACKAGES_SUFFIX]:
+            packages_needing_list = set(read_lines(filename))
+            should_add_signature_to_list = lambda sig,lists: extract_package(
+                sig) in packages_needing_list and not lists
+            valid_entries = flags.filter_apis(should_add_signature_to_list)
+            flags.assign_flag(flag, valid_entries)
+
     # Assign all remaining entries to the blacklist.
     flags.assign_flag(FLAG_BLACKLIST, flags.filter_apis(HAS_NO_API_LIST_ASSIGNED))
 
diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py
index 249f37d..4dc880b 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists_test.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists_test.py
@@ -18,33 +18,23 @@
 from generate_hiddenapi_lists import *
 
 class TestHiddenapiListGeneration(unittest.TestCase):
-    def test_init(self):
-        # Check empty lists
-        flags = FlagsDict([], [])
-        self.assertEquals(flags.generate_csv(), [])
-
-        # Check valid input - two public and two private API signatures.
-        flags = FlagsDict(['A', 'B'], ['C', 'D'])
-        self.assertEquals(flags.generate_csv(),
-                          [ 'A,' + FLAG_WHITELIST, 'B,' + FLAG_WHITELIST, 'C', 'D' ])
-
-        # Check invalid input - overlapping public/private API signatures.
-        with self.assertRaises(AssertionError):
-            flags = FlagsDict(['A', 'B'], ['B', 'C', 'D'])
 
     def test_filter_apis(self):
         # Initialize flags so that A and B are put on the whitelist and
         # C, D, E are left unassigned. Try filtering for the unassigned ones.
-        flags = FlagsDict(['A', 'B'], ['C', 'D', 'E'])
+        flags = FlagsDict()
+        flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B,' + FLAG_WHITELIST,
+                        'C', 'D', 'E'])
         filter_set = flags.filter_apis(lambda api, flags: not flags)
         self.assertTrue(isinstance(filter_set, set))
         self.assertEqual(filter_set, set([ 'C', 'D', 'E' ]))
 
     def test_get_valid_subset_of_unassigned_keys(self):
         # Create flags where only A is unassigned.
-        flags = FlagsDict(['A'], ['B', 'C'])
+        flags = FlagsDict()
+        flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B', 'C'])
         flags.assign_flag(FLAG_GREYLIST, set(['C']))
-        self.assertEquals(flags.generate_csv(),
+        self.assertEqual(flags.generate_csv(),
             [ 'A,' + FLAG_WHITELIST, 'B', 'C,' + FLAG_GREYLIST ])
 
         # Check three things:
@@ -55,44 +45,30 @@
             flags.get_valid_subset_of_unassigned_apis(set(['A', 'B', 'D'])), set([ 'B' ]))
 
     def test_parse_and_merge_csv(self):
-        flags = FlagsDict(['A'], ['B'])
-        self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ])
+        flags = FlagsDict()
 
         # Test empty CSV entry.
-        flags.parse_and_merge_csv(['B'])
-        self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ])
-
-        # Test assigning an already assigned flag.
-        flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST])
-        self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ])
+        self.assertEqual(flags.generate_csv(), [])
 
         # Test new additions.
         flags.parse_and_merge_csv([
             'A,' + FLAG_GREYLIST,
             'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O ])
         self.assertEqual(flags.generate_csv(),
-            [ 'A,' + FLAG_GREYLIST + "," + FLAG_WHITELIST,
+            [ 'A,' + FLAG_GREYLIST,
               'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O ])
 
-        # Test unknown API signature.
-        with self.assertRaises(AssertionError):
-            flags.parse_and_merge_csv([ 'C' ])
-
         # Test unknown flag.
         with self.assertRaises(AssertionError):
-            flags.parse_and_merge_csv([ 'A,foo' ])
+            flags.parse_and_merge_csv([ 'C,foo' ])
 
     def test_assign_flag(self):
-        flags = FlagsDict(['A'], ['B'])
-        self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ])
-
-        # Test assigning an already assigned flag.
-        flags.assign_flag(FLAG_WHITELIST, set([ 'A' ]))
-        self.assertEquals(flags.generate_csv(), [ 'A,' + FLAG_WHITELIST, 'B' ])
+        flags = FlagsDict()
+        flags.parse_and_merge_csv(['A,' + FLAG_WHITELIST, 'B'])
 
         # Test new additions.
         flags.assign_flag(FLAG_GREYLIST, set([ 'A', 'B' ]))
-        self.assertEquals(flags.generate_csv(),
+        self.assertEqual(flags.generate_csv(),
             [ 'A,' + FLAG_GREYLIST + "," + FLAG_WHITELIST, 'B,' + FLAG_GREYLIST ])
 
         # Test invalid API signature.
@@ -103,5 +79,18 @@
         with self.assertRaises(AssertionError):
             flags.assign_flag('foo', set([ 'A' ]))
 
+    def test_extract_package(self):
+        signature = 'Lcom/foo/bar/Baz;->method1()Lcom/bar/Baz;'
+        expected_package = 'com.foo.bar'
+        self.assertEqual(extract_package(signature), expected_package)
+
+        signature = 'Lcom/foo1/bar/MyClass;->method2()V'
+        expected_package = 'com.foo1.bar'
+        self.assertEqual(extract_package(signature), expected_package)
+
+        signature = 'Lcom/foo_bar/baz/MyClass;->method3()V'
+        expected_package = 'com.foo_bar.baz'
+        self.assertEqual(extract_package(signature), expected_package)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/tools/incident_report/main.cpp b/tools/incident_report/main.cpp
index be33afc..17a3c7a 100644
--- a/tools/incident_report/main.cpp
+++ b/tools/incident_report/main.cpp
@@ -277,147 +277,6 @@
 }
 
 // ================================================================================
-static uint8_t*
-write_raw_varint(uint8_t* buf, uint32_t val)
-{
-    uint8_t* p = buf;
-    while (true) {
-        if ((val & ~0x7F) == 0) {
-            *p++ = (uint8_t)val;
-            return p;
-        } else {
-            *p++ = (uint8_t)((val & 0x7F) | 0x80);
-            val >>= 7;
-        }
-    }
-}
-
-static int
-write_all(int fd, uint8_t const* buf, size_t size)
-{
-    while (size > 0) {
-        ssize_t amt = ::write(fd, buf, size);
-        if (amt < 0) {
-            return errno;
-        }
-        size -= amt;
-        buf += amt;
-    }
-    return 0;
-}
-
-static int
-adb_incident_workaround(const char* adbSerial, const vector<string>& sections)
-{
-    const int maxAllowedSize = 20 * 1024 * 1024; // 20MB
-    unique_ptr<uint8_t[]> buffer(new uint8_t[maxAllowedSize]);
-
-    for (vector<string>::const_iterator it=sections.begin(); it!=sections.end(); it++) {
-        Descriptor const* descriptor = IncidentProto::descriptor();
-        FieldDescriptor const* field;
-
-        // Get the name and field id.
-        string name = *it;
-        char* end;
-        int id = strtol(name.c_str(), &end, 0);
-        if (*end == '\0') {
-            // If it's an id, find out the string.
-            field = descriptor->FindFieldByNumber(id);
-            if (field == NULL) {
-                fprintf(stderr, "Unable to find field number: %d\n", id);
-                return 1;
-            }
-            name = field->name();
-        } else {
-            // If it's a string, find out the id.
-            field = descriptor->FindFieldByName(name);
-            if (field == NULL) {
-                fprintf(stderr, "Unable to find field: %s\n", name.c_str());
-                return 1;
-            }
-            id = field->number();
-        }
-
-        int pfd[2];
-        if (pipe(pfd) != 0) {
-            fprintf(stderr, "pipe failed: %s\n", strerror(errno));
-            return 1;
-        }
-
-        pid_t pid = fork();
-        if (pid == -1) {
-            fprintf(stderr, "fork failed: %s\n", strerror(errno));
-            return 1;
-        } else if (pid == 0) {
-            // child
-            dup2(pfd[1], STDOUT_FILENO);
-            close(pfd[0]);
-            close(pfd[1]);
-
-            char const** args = (char const**)malloc(sizeof(char*) * 8);
-            int argpos = 0;
-            args[argpos++] = "adb";
-            if (adbSerial != NULL) {
-                args[argpos++] = "-s";
-                args[argpos++] = adbSerial;
-            }
-            args[argpos++] = "shell";
-            args[argpos++] = "dumpsys";
-            args[argpos++] = name.c_str();
-            args[argpos++] = "--proto";
-            args[argpos++] = NULL;
-            execvp(args[0], (char*const*)args);
-            fprintf(stderr, "execvp failed: %s\n", strerror(errno));
-            free(args);
-            return 1;
-        } else {
-            // parent
-            close(pfd[1]);
-
-            size_t size = 0;
-            while (size < maxAllowedSize) {
-                ssize_t amt = read(pfd[0], buffer.get() + size, maxAllowedSize - size);
-                if (amt == 0) {
-                    break;
-                } else if (amt == -1) {
-                    fprintf(stderr, "read error: %s\n", strerror(errno));
-                    return 1;
-                }
-                size += amt;
-            }
-
-            int status;
-            do {
-                waitpid(pid, &status, 0);
-            } while (!WIFEXITED(status));
-            if (WEXITSTATUS(status) != 0) {
-                return WEXITSTATUS(status);
-            }
-
-            if (size > 0) {
-                uint8_t header[20];
-                uint8_t* p = write_raw_varint(header, (id << 3) | 2);
-                p = write_raw_varint(p, size);
-                int err = write_all(STDOUT_FILENO, header, p-header);
-                if (err != 0) {
-                    fprintf(stderr, "write error: %s\n", strerror(err));
-                    return 1;
-                }
-                err = write_all(STDOUT_FILENO, buffer.get(), size);
-                if (err != 0) {
-                    fprintf(stderr, "write error: %s\n", strerror(err));
-                    return 1;
-                }
-            }
-
-            close(pfd[0]);
-        }
-    }
-
-    return 0;
-}
-
-// ================================================================================
 static void
 usage(FILE* out)
 {
@@ -449,7 +308,6 @@
     const char* inFilename = NULL;
     const char* outFilename = NULL;
     const char* adbSerial = NULL;
-    bool adbIncidentWorkaround = true;
     pid_t childPid = -1;
     vector<string> sections;
     const char* privacy = NULL;
@@ -475,9 +333,6 @@
             case 'h':
                 usage(stdout);
                 return 0;
-            case 'w':
-                adbIncidentWorkaround = false;
-                break;
             case 'p':
                 privacy = optarg;
                 break;
@@ -517,19 +372,10 @@
             fprintf(stderr, "fork failed: %s\n", strerror(errno));
             return 1;
         } else if (childPid == 0) {
+            // child
             dup2(pfd[1], STDOUT_FILENO);
             close(pfd[0]);
             close(pfd[1]);
-            // child
-            if (adbIncidentWorkaround) {
-                // TODO: Until the device side incident command is checked in,
-                // the incident_report builds the outer Incident proto by hand
-                // from individual adb shell dumpsys <service> --proto calls,
-                // with a maximum allowed output size.
-                return adb_incident_workaround(adbSerial, sections);
-            }
-
-            // TODO: This is what the real implementation will be...
             char const** args = (char const**)malloc(sizeof(char*) * (8 + sections.size()));
             int argpos = 0;
             args[argpos++] = "adb";
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index f6c9c0e..3b3fe19 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -408,10 +408,16 @@
     for (int i=0; i<descriptor->field_count(); i++) {
         const FieldDescriptor* field = descriptor->field(i);
 
-        if (field->type() != FieldDescriptor::TYPE_MESSAGE && field->type() != FieldDescriptor::TYPE_STRING) {
+        if (field->type() != FieldDescriptor::TYPE_MESSAGE
+                && field->type() != FieldDescriptor::TYPE_STRING) {
             continue;
         }
+
         const SectionFlags s = getSectionFlags(field);
+        if (s.userdebug_and_eng_only()) {
+            printf("#if ALLOW_RESTRICTED_SECTIONS\n");
+        }
+
         switch (s.type()) {
             case SECTION_NONE:
                 continue;
@@ -424,8 +430,7 @@
                 printf(" NULL),\n");
                 break;
             case SECTION_DUMPSYS:
-                printf("    new DumpsysSection(%d, %s,", field->number(),
-                       s.userdebug_and_eng_only() ? "true" : "false");
+                printf("    new DumpsysSection(%d, ", field->number());
                 splitAndPrint(s.args());
                 printf(" NULL),\n");
                 break;
@@ -438,9 +443,13 @@
                 printf(" NULL),\n");
                 break;
             case SECTION_TOMBSTONE:
-                printf("    new TombstoneSection(%d, \"%s\"),\n", field->number(), s.args().c_str());
+                printf("    new TombstoneSection(%d, \"%s\"),\n", field->number(),
+                        s.args().c_str());
                 break;
         }
+        if (s.userdebug_and_eng_only()) {
+            printf("#endif\n");
+        }
     }
     printf("    NULL };\n");
 
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index daee6d6..a5b56a4 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -512,7 +512,7 @@
        fprintf(out, "      std::this_thread::sleep_for(std::chrono::milliseconds(10));\n");
        fprintf(out, "  }\n");
        fprintf(out, "  if (ret < 0) {\n");
-       fprintf(out, "      note_log_drop(ret);\n");
+       fprintf(out, "      note_log_drop(ret, code);\n");
        fprintf(out, "  }\n");
        fprintf(out, "  return ret;\n");
        fprintf(out, "}\n");
@@ -620,7 +620,7 @@
        fprintf(out, "      std::this_thread::sleep_for(std::chrono::milliseconds(10));\n");
        fprintf(out, "  }\n");
        fprintf(out, "  if (ret < 0) {\n");
-       fprintf(out, "      note_log_drop(ret);\n");
+       fprintf(out, "      note_log_drop(ret, code);\n");
        fprintf(out, "  }\n");
        fprintf(out, "  return ret;\n\n");
        fprintf(out, "}\n");
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 78967e4..be227e7 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -2190,22 +2190,7 @@
                 key += "-" + Integer.toString(UserHandle.getUserId(creatorUid));
             }
         } else {
-            if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
-                key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK];
-            } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
-                    allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
-                key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
-            } else if (wepKeys[0] != null) {
-                key = SSID + "WEP";
-            } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
-                key = SSID + KeyMgmt.strings[KeyMgmt.OWE];
-            } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
-                key = SSID + KeyMgmt.strings[KeyMgmt.SAE];
-            } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
-                key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192];
-            } else {
-                key = SSID + KeyMgmt.strings[KeyMgmt.NONE];
-            }
+            key = getSsidAndSecurityTypeString();
             if (!shared) {
                 key += "-" + Integer.toString(UserHandle.getUserId(creatorUid));
             }
@@ -2215,6 +2200,30 @@
     }
 
     /** @hide
+     *  return the SSID + security type in String format.
+     */
+    public String getSsidAndSecurityTypeString() {
+        String key;
+        if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
+            key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK];
+        } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)
+                || allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
+            key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
+        } else if (wepKeys[0] != null) {
+            key = SSID + "WEP";
+        } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
+            key = SSID + KeyMgmt.strings[KeyMgmt.OWE];
+        } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
+            key = SSID + KeyMgmt.strings[KeyMgmt.SAE];
+        } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
+            key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192];
+        } else {
+            key = SSID + KeyMgmt.strings[KeyMgmt.NONE];
+        }
+        return key;
+    }
+
+    /** @hide
      * get configKey, force calculating the config string
      */
     public String configKey() {
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 06a99e2..9b3796f 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2424,8 +2424,11 @@
      * @throws  {@link java.lang.SecurityException} if the caller is missing required permissions.
      *
      * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to
-     * enable/disable Wi-Fi regardless of application's target SDK. This API will have no effect
-     * and will always return false.
+     * enable/disable Wi-Fi.
+     * <b>Compatibility Note:</b> For applications targeting
+     * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code false}
+     * and will have no effect. If apps are targeting an older SDK (
+     * {@link android.os.Build.VERSION_CODES#P} or below), they can continue to use this API.
      */
     @Deprecated
     public boolean setWifiEnabled(boolean enabled) {
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index a9c9939..4262017 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -283,10 +283,10 @@
 
         /**
          * Specify the priority of this network among other network suggestions provided by the same
-         * app (priorities have no impact on suggestions by different apps). The lower the number,
-         * the higher the priority (i.e value of 0 = highest priority).
+         * app (priorities have no impact on suggestions by different apps). The higher the number,
+         * the higher the priority (i.e value of 0 = lowest priority).
          * <p>
-         * <li>If not set, defaults to -1 (i.e unassigned priority).</li>
+         * <li>If not set, defaults a lower priority than any assigned priority.</li>
          *
          * @param priority Integer number representing the priority among suggestions by the app.
          * @return Instance of {@link Builder} to enable chaining of the builder method.
@@ -374,12 +374,11 @@
         }
 
         /**
-         * Create a network suggestion object use in
+         * Create a network suggestion object for use in
          * {@link WifiManager#addNetworkSuggestions(List)}.
          *
-         * See {@link WifiNetworkSuggestion}.
-         *<p>
-         * Note: Apps can set a combination of SSID using {@link #setSsid(String)} and BSSID
+         *<p class="note">
+         * <b>Note:</b> Apps can set a combination of SSID using {@link #setSsid(String)} and BSSID
          * using {@link #setBssid(MacAddress)} to provide more fine grained network suggestions to
          * the platform.
          * </p>
@@ -387,7 +386,8 @@
          * For example:
          * To provide credentials for one open, one WPA2 and one WPA3 network with their
          * corresponding SSID's:
-         * {@code
+         *
+         * <pre>{@code
          * final WifiNetworkSuggestion suggestion1 =
          *      new Builder()
          *      .setSsid("test111111")
@@ -403,19 +403,20 @@
          *      .setWpa3Passphrase("test6789")
          *      .build()
          * final List<WifiNetworkSuggestion> suggestionsList =
-         *      new ArrayList<WifiNetworkSuggestion> &#123;{
+         *      new ArrayList<WifiNetworkSuggestion> { {
          *          add(suggestion1);
          *          add(suggestion2);
          *          add(suggestion3);
-         *      }};
+         *      } };
          * final WifiManager wifiManager =
          *      context.getSystemService(Context.WIFI_SERVICE);
          * wifiManager.addNetworkSuggestions(suggestionsList);
-         * ...
-         * }
+         * // ...
+         * }</pre>
          *
-         * @return Instance of {@link WifiNetworkSuggestion}.
-         * @throws IllegalStateException on invalid params set.
+         * @return Instance of {@link WifiNetworkSuggestion}
+         * @throws IllegalStateException on invalid params set
+         * @see WifiNetworkSuggestion
          */
         public @NonNull WifiNetworkSuggestion build() {
             if (mSsid == null) {
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
index d927052..ba9fc78 100644
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -348,4 +348,47 @@
         }
         assertTrue(exceptionThrown);
     }
+
+    /**
+     * Verifies that getSsidAndSecurityTypeString returns the correct String for networks of
+     * various different security types
+     */
+    @Test
+    public void testGetSsidAndSecurityTypeString() {
+        WifiConfiguration config = new WifiConfiguration();
+        final String mSsid = "TestAP";
+        config.SSID = mSsid;
+
+        // Test various combinations
+        config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
+        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WPA_PSK],
+                config.getSsidAndSecurityTypeString());
+
+        config.allowedKeyManagement.clear();
+        config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
+        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.WPA_EAP],
+                config.getSsidAndSecurityTypeString());
+
+        config.wepKeys[0] = "TestWep";
+        config.allowedKeyManagement.clear();
+        assertEquals(mSsid + "WEP", config.getSsidAndSecurityTypeString());
+
+        config.wepKeys[0] = null;
+        config.allowedKeyManagement.clear();
+        config.allowedKeyManagement.set(KeyMgmt.OWE);
+        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.OWE], config.getSsidAndSecurityTypeString());
+
+        config.allowedKeyManagement.clear();
+        config.allowedKeyManagement.set(KeyMgmt.SAE);
+        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.SAE], config.getSsidAndSecurityTypeString());
+
+        config.allowedKeyManagement.clear();
+        config.allowedKeyManagement.set(KeyMgmt.SUITE_B_192);
+        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.SUITE_B_192],
+                config.getSsidAndSecurityTypeString());
+
+        config.allowedKeyManagement.clear();
+        config.allowedKeyManagement.set(KeyMgmt.NONE);
+        assertEquals(mSsid + KeyMgmt.strings[KeyMgmt.NONE], config.getSsidAndSecurityTypeString());
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 600abc9..fa17db1 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -1382,4 +1382,60 @@
             r.run();
         }
     }
+
+    /**
+     * Test behavior of isEnhancedOpenSupported
+     * @throws Exception
+     */
+    @Test
+    public void testIsEnhancedOpenSupported() throws Exception {
+        when(mWifiService.getSupportedFeatures())
+                .thenReturn(new Long(WifiManager.WIFI_FEATURE_OWE));
+        assertTrue(mWifiManager.isEnhancedOpenSupported());
+        when(mWifiService.getSupportedFeatures())
+                .thenReturn(new Long(~WifiManager.WIFI_FEATURE_OWE));
+        assertFalse(mWifiManager.isEnhancedOpenSupported());
+    }
+
+    /**
+     * Test behavior of isWpa3SaeSupported
+     * @throws Exception
+     */
+    @Test
+    public void testIsWpa3SaeSupported() throws Exception {
+        when(mWifiService.getSupportedFeatures())
+                .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SAE));
+        assertTrue(mWifiManager.isWpa3SaeSupported());
+        when(mWifiService.getSupportedFeatures())
+                .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SAE));
+        assertFalse(mWifiManager.isWpa3SaeSupported());
+    }
+
+    /**
+     * Test behavior of isWpa3SuiteBSupported
+     * @throws Exception
+     */
+    @Test
+    public void testIsWpa3SuiteBSupported() throws Exception {
+        when(mWifiService.getSupportedFeatures())
+                .thenReturn(new Long(WifiManager.WIFI_FEATURE_WPA3_SUITE_B));
+        assertTrue(mWifiManager.isWpa3SuiteBSupported());
+        when(mWifiService.getSupportedFeatures())
+                .thenReturn(new Long(~WifiManager.WIFI_FEATURE_WPA3_SUITE_B));
+        assertFalse(mWifiManager.isWpa3SuiteBSupported());
+    }
+
+    /**
+     * Test behavior of isEasyConnectSupported
+     * @throws Exception
+     */
+    @Test
+    public void testIsEasyConnectSupported() throws Exception {
+        when(mWifiService.getSupportedFeatures())
+                .thenReturn(new Long(WifiManager.WIFI_FEATURE_DPP));
+        assertTrue(mWifiManager.isEasyConnectSupported());
+        when(mWifiService.getSupportedFeatures())
+                .thenReturn(new Long(~WifiManager.WIFI_FEATURE_DPP));
+        assertFalse(mWifiManager.isEasyConnectSupported());
+    }
 }